How to get Current Absolute URL with Query String in JSF? - java

I am trying to get the absolute URL in my managed bean's action listener. I have used:
HttpServletRequest#getRequestURL() // returning http://localhost:7101/POSM/pages/catalog-edit
HttpServetRequest#getQueryString() // returning _adf.ctrl-state=gfjk46nd7_9
But the actual URL is: http://localhost:7101/POSM/pages/catalog-edit?_adf.ctrl-state=gfjk46nd7_9&articleReference=HEN00067&_afrLoop=343543687406787. I don't know why the parameter artcileReference get omitted.
Is there any method which can give me the whole URL at once? How can I get the whole URL with all query string?

You can reconstruct your URL manually by using ServletRequest#getParameterNames() and ServletRequest#getParameter() both available with the HttpServletRequest instance.
Here is a sample code I've used in the past for this exact purpose :
private String getURL()
{
Enumeration<String> lParameters;
String sParameter;
StringBuilder sbURL = new StringBuilder();
Object oRequest = FacesContext.getCurrentInstance().getExternalContext().getRequest();
try
{
if(oRequest instanceof HttpServletRequest)
{
sbURL.append(((HttpServletRequest)oRequest).getRequestURL().toString());
lParameters = ((HttpServletRequest)oRequest).getParameterNames();
if(lParameters.hasMoreElements())
{
if(!sbURL.toString().contains("?"))
{
sbURL.append("?");
}
else
{
sbURL.append("&");
}
}
while(lParameters.hasMoreElements())
{
sParameter = lParameters.nextElement();
sbURL.append(sParameter);
sbURL.append("=");
sbURL.append(URLEncoder.encode(((HttpServletRequest)oRequest).getParameter(sParameter),"UTF-8"));
if(lParameters.hasMoreElements())
{
sbURL.append("&");
}
}
}
}
catch(Exception e)
{
// Do nothing
}
return sbURL.toString();
}

Here I came up with my solution, taking idea of the answer given by Alexandre, considering that HttpServletRequest#getParameterValues() method:
protected String getCurrentURL() throws UnsupportedEncodingException {
Enumeration parameters = getServletRequest().getParameterNames();
StringBuffer urlBuffer = new StringBuffer();
urlBuffer.append(getServletRequest().getRequestURL().toString());
if(parameters.hasMoreElements()) {
if(!urlBuffer.toString().contains("?")) {
urlBuffer.append("?");
} else {
urlBuffer.append("&");
}
}
while(parameters.hasMoreElements()) {
String parameter = (String)parameters.nextElement();
String[] parameterValues = getServletRequest().getParameterValues(parameter);
if(!CollectionUtils.sizeIsEmpty(parameterValues)) {
for(int i = 0; i < parameterValues.length; i++) {
String value = parameterValues[i];
if(StringUtils.isNotBlank(value)) {
urlBuffer.append(parameter);
urlBuffer.append("=");
urlBuffer.append(URLEncoder.encode(value, "UTF-8"));
if((i + 1) != parameterValues.length) {
urlBuffer.append("&");
}
}
}
}
if(parameters.hasMoreElements()) {
urlBuffer.append("&");
}
}
return urlBuffer.toString();
}

Related

in Opentelemetry, not able to get parent span

I am new to OpenTelemetry word. I have created spans for my services separately, but when i am try to combine spans of two different services, using context propogation, I am not able to do it successfully.
I have used following code:
// at client side:
public static void sendContext(String resource) {
TextMapSetter<HttpURLConnection> setter =
new TextMapSetter<HttpURLConnection>() {
#Override
public void set(HttpURLConnection carrier, String key, String value) {
carrier.setRequestProperty(key, value);
}
};
HttpURLConnection transportLayer = null;
String urlString = "http://127.0.0.1:8080" + resource;
try {
URL url = new URL(urlString);
transportLayer = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException ex) {
System.out.println(ex.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
GlobalOpenTelemetry.getPropagators()
.getTextMapPropagator()
.inject(Context.current(), transportLayer, setter);
}
// at server side:
public static Context getContext(HttpServletRequest request) {
TextMapGetter<HttpServletRequest> getter =
new TextMapGetter<HttpServletRequest>() {
#Override
public String get(HttpServletRequest carrier, String key) {
Enumeration<String> headerNames = carrier.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
System.out.println("headerNames.nextElement(): " + headerName);
if (headerName.equals(key)) {
String headerValue = request.getHeader(headerName);
System.out.println("headerValue): " + headerValue);
return headerValue;
}
}
}
return null;
}
#Override
public Iterable<String> keys(HttpServletRequest carrier) {
Set<String> set = new HashSet<String>();
Enumeration<String> headerNames = carrier.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
set.add(headerNames.nextElement());
}
}
return set;
}
};
Context extractedContext =
GlobalOpenTelemetry.getPropagators()
.getTextMapPropagator()
.extract(Context.current(), request, getter);
At server, i am not able to get parent span.
Kindly help on this.
You can refer to OpenTelemetry main documentation from here. It contains the context propagation part but I used HttpHeader type getter as the TextMapGetter with the same functionality which shows in the doc and instead of using
Scope scope = extractedContext.makeCurrent()
as the scope to create a child span, better to use directly without the scope,
tracer.spanBuilder(spanName).setParent(extractedContext)
Because sometimes the automated way to propagate the parent span on the current thread does not work fine.

Get HTTP URL from href-attribute (All possible ways for links)

I am trying to do a simple script that will convert any possible HTML link into HTTP URL, such as
http://example.com //example.com /index.html ./index.html index.html
I already tried function that I found in another answer:
public static Integer isAbsoluteURL (String url) throws java.net.MalformedURLException {
final URL baseHTTP = new URL("http://example.com");
final URL baseFILE = new URL("file:///");
if (url.length() > 0) {
if (url.substring(0, 1) == "/") {
return 0;
}
}
URL frelative;
URL hrelative;
try {
frelative = new URL(baseFILE, url);
hrelative = new URL(baseHTTP, url);
} catch (MalformedURLException e) {
System.out.println("MalformedURLException found");
return 3;
}
if (frelative.equals(hrelative)) {
return 0;
} else {
return 1;
}
}
I want to get absolute links, but the code don't work for ./, //(without http[s]).
Thanks.
I'd prefer to use spring's UriComponentBuilder which will take care about everything:
https://www.baeldung.com/spring-uricomponentsbuilder

How to encapsulate the logic of parametrized messages?

I'm using java.util.resourcebundle to format my JSTL messages and this works fine:
I use the class MessageFormat you can see here. Now I want to encapsulate this to a method that is just getParametrizedMessage(String key, String[]parameters) but I'm not sure how to do it. Now there is quite a lot of work to display just one or two messages with parameters:
UserMessage um = null;
ResourceBundle messages = ResourceBundle.getBundle("messages");
String str = messages.getString("PF1");
Object[] messageArguments = new String[]{nyreg.getNummer()};
MessageFormat formatter = new MessageFormat("");
formatter.applyPattern(messages.getString("PI14"));
String outputPI14 = formatter.format(messageArguments);
formatter.applyPattern(messages.getString("PI15"));
String outputPI15 = formatter.format(messageArguments)
if(ipeaSisFlag)
if(checkIfPCTExistInDB && nyreg.isExistInDB()) {
//um = new ExtendedUserMessage(MessageHandler.getParameterizedMessage("PI15", new String[]{nyreg.getNummer()}) , UserMessage.TYPE_INFORMATION, "Info");
um = new ExtendedUserMessage(outputPI15 , UserMessage.TYPE_INFORMATION, "Info");
…and so on. Now can I move this logic to a static class MessageHandler.getParameterizedMessage that now is not working and looking like this:
private final static String dictionaryFileName="messages.properties";
public static String getParameterizedMessage(String key, String [] params){
if (dictionary==null){
loadDictionary();
}
return getParameterizedMessage(dictionary,key,params);
}
private static void loadDictionary(){
String fileName = dictionaryFileName;
try {
dictionary=new Properties();
InputStream fileInput = MessageHandler.class.getClassLoader().getResourceAsStream(fileName);
dictionary.load(fileInput);
fileInput.close();
}
catch(Exception e) {
System.err.println("Exception reading propertiesfile in init "+e);
e.printStackTrace();
dictionary=null;
}
}
How can I make using my parametrized messages as easy as calling a method with key and parameter?
Thanks for any help
Update
The logic comes from an inherited method that in in the abstract class that this extends. The method looks like:
protected static String getParameterizedMessage(Properties dictionary,String key,String []params){
if (dictionary==null){
return "ERROR";
}
String msg = dictionary.getProperty(key);
if (msg==null){
return "?!Meddelande " +key + " saknas!?";
}
if (params==null){
return msg;
}
StringBuffer buff = new StringBuffer(msg);
for (int i=0;i<params.length;i++){
String placeHolder = "<<"+(i+1)+">>";
if (buff.indexOf(placeHolder)!=-1){
replace(buff,placeHolder,params[i]);
}
else {
remove(buff,placeHolder);
}
}
return buff.toString();
}
I think I must rewrite the above method in order to make it work like a resourcebundle rather than just a dictionary.
Update 2
The code that seems to work is here
public static String getParameterizedMessage(String key, Object [] params){
ResourceBundle messages = ResourceBundle.getBundle("messages");
MessageFormat formatter = new MessageFormat("");
formatter.applyPattern(messages.getString(key));
return formatter.format(params);
}
I'm not really sure what you're trying to achive, here's what I did in the past:
public static final String localize(final Locale locale, final String key, final Object... param) {
final String name = "message";
final ResourceBundle rb;
/* Resource bundles are cached internally,
never saw a need to implement another caching level
*/
try {
rb = ResourceBundle.getBundle(name, locale, Thread.currentThread()
.getContextClassLoader());
} catch (MissingResourceException e) {
throw new RuntimeException("Bundle not found:" + name);
}
String keyValue = null;
try {
keyValue = rb.getString(key);
} catch (MissingResourceException e) {
// LOG.severe("Key not found: " + key);
keyValue = "???" + key + "???";
}
/* Message formating is expensive, try to avoid it */
if (param != null && param.length > 0) {
return MessageFormat.format(keyValue, param);
} else {
return keyValue;
}
}

Why can't I parse a javamail attachment using toString?

It seems to me the snippet below should work, but "mp.getBodyPart(1).getContent().toString()" returns
com.sun.mail.util.BASE64DecoderStream#44b07df8
instead of the contents of the attachment.
public class GMailParser {
public String getParsedMessage(Message message) throws Exception {
try {
Multipart mp = (Multipart) message.getContent();
String s = mp.getBodyPart(1).getContent().toString();
if (s.contains("pattern 1")) {
return "return 1";
} else if (s.contains("pattern 2")) {
return "return 2";
}
...
It simply means that the BASE64DecoderStream class does not provide a custom toString definition. The default toString definition is to display the class name + '#' + Hash Code, which is what you see.
To get the "content" of the Stream you need to use the read() method.
This parses BASE64DecoderStream attachments exactly as needed.
private String getParsedAttachment(BodyPart bp) throws Exception {
InputStream is = null;
ByteArrayOutputStream os = null;
try {
is = bp.getInputStream();
os = new ByteArrayOutputStream(256);
int c = 0;
while ((c = is.read()) != -1) {
os.write(c);
}
String s = os.toString();
if (s.contains("pattern 1")) {
return "return 1";
} else if (s.contains("pattern 2")) {
return "return 2";
}
...

Blackberry URL encoder

I need to encode a URL using HTTP GET request in Blackberry. Can any one help me find how do I achieve this.
Whyt don't you use RIM's URLEncodedPostData?
private String encodeUrl(String hsURL) {
URLEncodedPostData urlEncoder = new URLEncodedPostData("UTF-8", false);
urlEncoder.setData(hsURL);
hsURL = urlEncoder.toString();
return hsURL;
}
here you go ;^)
public static String URLencode(String s)
{
if (s!=null) {
StringBuffer tmp = new StringBuffer();
int i=0;
try {
while (true) {
int b = (int)s.charAt(i++);
if ((b>=0x30 && b<=0x39) || (b>=0x41 && b<=0x5A) || (b>=0x61 && b<=0x7A)) {
tmp.append((char)b);
}
else {
tmp.append("%");
if (b <= 0xf) tmp.append("0");
tmp.append(Integer.toHexString(b));
}
}
}
catch (Exception e) {}
return tmp.toString();
}
return null;
}
use the class provided by w3. Here is the download link
the reply using "URLEncodedPostData" above is incorrect.
Corrected sample:
public static String encodeUrl(Hashtable params)
{
URLEncodedPostData urlEncoder = new URLEncodedPostData("UTF-8", false);
Enumeration keys = params.keys();
while (keys.hasMoreElements()) {
String name = (String) keys.nextElement();
String value = (String) params.get(name);
urlEncoder.append(name, value);
}
String encoded = urlEncoder.toString();
return encoded;
}
Cheers!

Categories