Thymeleaf: Unencode or Encode URL on client - java

I am using Thymeleaf as the front end.
I have some menu categories in natural language that I display on a web page and pass to the server.
For example, I have a category of "My favourite cats"
The category is in a variable ${category.key}
This category has a link;
<a th:href="|http://myserver?selectedCategory=${category.key}|><span th:text=${category.key}></span></a>
If I do not URLEncode ${category.key} on the server, then when a
user clicks the link, the selectedCategory parameter is null if there
is a whitespace in the category string.
If I encode the category string, the selectedCategory parameter
passes to the server fine BUT the link text appears as
My+favourite+cats
I don't want two variables, one encoded, one not encoded.
How do I either encode or unencode ${category.key} as part of the Thymeleaf HTML compilation process?

#symbol is Server Context path in Thymeleaf. you use #symbol.
<a href="#" th:href="#{/your server context path?selectedCategory=__${category.key}__}">
<span th:text="${category.key}"> </span></a>

Thymeleaf will url encode strings if you build them with url syntax (which was supplied in a comment above). For your example url, it should look like this -- using the # symbol instead of the $:
<a th:href="#{http://myserver(selectedCategory=${category.key})}" th:text="${category.key}" />
(Also, you don't need that extra span.)

Using the #symbol is definitely the primary alternative. But just to note another option that may be of use on occasions:
The answer is to use the lesser know #strings functions to replace the '+' with ' '
In the link text, use
th:text="${#strings.replace(category.key,'+',' ')}"

Related

Cannot escape a quotation(") character when retriveing a string containg quotation inside a string from DB in jsp

I have saved quotation(") in a string using escape character i database. That is working ok. But when i am retrieving the value in a jsp field from database, the string is being ended at the first quotation it gets in the whole string. I am giving an example below:
Lets take a string that i have stored in database as -
" Hello David. This is a "customer"."
Now, i am somehow need to save the string back from databse into a hidden field in a jsp page like below-
<input type="hidden" name="string_from_database" id="string_from_database" value="<%=some varibale that holds the data from database%>">
issue is -
Part of the string is getting exposed (means it is being written on top of the page) which i do not want. In this case,the below phrase is written on the beginning of the jsp page, which i don't want.
customer".
kindly suggest on how to resolve this issue.
Using this function you could replace the quote marks with the html entity variant ". Here's a simple function for it. Hope it fits into your templating system, but should be easy to modify if not.
function escapeQuotes(str){
return str.replace(/"/g,'"');
}
Here's a working fiddle
Use Jstl rather than scriptlets for further Explanation
use EL - Expression Language (${variable}) to get the Value eg. ${welcome}
<c:out value="${some varibale that holds the data from database}"/>

Dynamic file path in assets reverse routing

I am trying to use reverse routing to access static Assets using:
#routes.Assets.at("path", "file")
However I would like to define file as dynamic part as well like:
#for(c <- models.WebContent.find.all) {
<img src="#routes.Assets.at("/contentfiles/useruploads", "#c.picture1")">
}
Statement above however results in HTML code:
<img src="/contentfiles/userupload/#c.picture1">
Where you can see dynamic part #c.picture1 is not interpreted as dynamic filename but is parsed as raw text resulting in broken link. What I am expecting is that both dynamic parts are interpreted as dynamic resulting in eg.:
<img src="/contentfiles/userupload/1776446515.jpg">
How to define it so both dynamic statements are parsed as dynamic?
PS: I have tried to escape it as ##c.picture or $#c.picture with no luck
Thank you
When using variables as a function argument use it w/out # char and also not within quotes, otherwise as you can is it's used as a... String
<img src="#routes.Assets.at("/contentfiles/useruploads", c.picture1)">
The same as in condition:
Use:
#if(foo==bar){...}
NOT
#if(#foo==#bar){...}

How to pass raw html to Play framework view?

I'm trying to pass a simple URL to a view within a play framework app, however when passed as a string, the & in the url is changed to & which causes the URL to not work.
If I change the argument to Html, i.e #(url: Srting) to #(url: Html), then I get an error when I try to pass the url as string to view.render() method.
How can I convert the url into Html and pass it as that?
To prevent the default escaping that happens for dynamic content on views you need to wrap the String with #Html(String) function:
View:
#(url: String)
<div class="myLink">
Go to: #Html(url) <br>
not to: #url
</div>
Controller:
public static Result displayLink(){
return ok(view.render("<a href='http://stackoverflow.com/'>Stack Overflow</a>"));
}
See The template engine page on the documentation for more info (specifically the "Escaping" section at the very bottom).
If you want to render HTML content instead of displaying it as raw text, return the content .as("text/html"). Example:
WS.url("http://www.stackoverflow.com").get().map(resp => Ok(resp.body).as("text/html"))

Get parameter with the character '#' from a query string on java

I am trying to get a request string that has the character # and my parameter is got only until the #. But the thing is that I need to have this character, can't remove it.
Any idea?
Encode the # if it has to be there. A literal # indicates a fragment id and can't be used in a URI for any other purpose. w3schools has encoding tables so you can look up the values yourself, too.
You need to encode the parameter value correctly.
If the URL is generated by a JSP, make sure to use the JSTL c:url tag:
<c:url value="/path/to/myServlet">
<c:param name="param1" value="#paramValue"/>
</c:url>
If you're using straight Java, use URLEncoder.encode().
If the URL is static, use %23paramValue instead of #paramValue

firefox a href # symbol causes setter not to be called

Morning all,
It early Monday morning and I'm struggling to understand why the followng line works in IE and not in FF.
<a class="button" href="#" onclick="setMaintenanceMode(false);">disable</a>
In both IE and FF the URL when you hover over the button is...
http://localhost:8080/mainapp/secure/gotoDevice.action?hardwareId=1&storeCode=2571#
When the button is clicked, the following method is called...
function setMaintenanceMode(enabled) {
var url = '<s:url action="secure/setMaintenanceMode"/>' + '&ModeEnabled=' + enabled;
document.location.href = url;
}
The URL that docuement is sent to is (in both browsers)...
/mainapp/secure/gotoDevice.action?hardwareId=1&storeCode=2571&ModeEnabled=false
The problem is that in IE the method on the struts action 'setSetCode()' is called, but from FF its not! If I remove the hash ahref above FF works, but IE doesn't (href="#").
I've tried changing the '&ModeEnabled=' to '&ModeEnabled=', but no success.
I've looked on google and the struts forum, but no success.
I'm tempted to rip out all the ahref's and replace them with Dojo buttons and see if that works, but before I do, I just wondered if anyone could shead some light on why.
My guess is that ahref is the wrong thing to use, but why?
If anyone could help me understand why though it would be appreciated.
Thanks
Jeff Porter
EDIT: The return false is part of the solution. The problem seems to be that the url..
/mainApp/secure/setMaintenanceMode.action?hardwareId=5&storeCode=2571&ModeEnabled=true
has the & inside it, if I go to this url as it is, then it works in IE, but not in FF.
if I change both to be & then it works in IE & FF.
if I change both to be & then it still works in IE but not FF.
Any ideas?
Note:
Seems that struts 2.0.9 does not support the property escapeAmp on the <s:url tag:
By default request parameters will be separated using escaped ampersands (i.e., &). This is necessary for XHTML compliance, however, when using the URL generated by this tag with the <s:property> tag, the escapeAmp attribute should be used to disable ampersand escaping.
soultion: return false on the onclick and upgrade to new struts + set escapeAmp param.
else, url = url.replace("&", "&");.
Try returning false from the javascript method
function setMaintenanceMode(enabled) {
var url = '<s:url action="secure/setMaintenanceMode"/>' + '&ModeEnabled=' + enabled;
document.location.href = url;
return false;
}
<a class="button" href="#" onclick="return setMaintenanceMode(false);">disable</a>
This should stop the javascript onclick event reaching the browser.
onclick="setMaintenanceMode(false); return false;"
The onclick is working, but then the href does immediately, as well. You need to return false from the click handler to signal that href should not be followed.
IE likely guesses at what you mean, and does the wrong thing.
the URL has the & inside it, if I go to this url as it is, then it works in IE, but not in FF.
I doubt it – it shouldn't work in either. It's not browser-dependent, but server-dependent.
The string a=b&c=d is split into parameters by the server framework. Servlet requires that only & be used to separate parameters, so it will return a=b and amp;c=d. The latter parameter obviously won't be recognised by the application which is expecting c.
The HTML specification for various reasons strongly recommends that ; also be allowed as a separator, in which case you'd get a=b, a stray amp which without an equals sign would be meaningless and discarded, and c=d. So despite the mis-encoding of the ampersand it would still work. Unfortunately, Servlet ignores this recommendation.
By default request parameters will be separated using escaped ampersands (i.e., &).
Oh dear! How unfortunate. You shouldn't escape ampersands at the point of joining parameters into a URL. You should simply join the parameters with a single ampersand, and then, if you need to put the finished URL into an attribute value of text content, HTML-encode the entire URL. Struts's default behaviour is simply wrong here.
In your case you are not outputting the URL to an attribute value or text content, you're writing it into a string literal in a script block:
var url = '<s:url action="secure/setMaintenanceMode"/>' + '&ModeEnabled=' + enabled;
In a script block in old-school HTML, HTML-escaping does not apply. (In XHTML in native XML it does, but let's not think about that yet.)
However, you still do need to think about JavaScript escapes. For example what if there were an apostrophe in the setMaintenanceMode link? It would break the string. Or if somehow you had a </ sequence in the string it'd break the entire script block.
What you really want to be doing is making the URL (without any ampersand-escaping), and then use a JavaScript string literal backslash-escape on it. Best would be to use an existing JSON encoder which will turn any Java value into a JavaScript literal, putting the surrounding quotes in for you too if it's a string. You can also on most JSON encoders tell it to JS-escape the < and & characters, which means not having to worry about XHTML parsing if you decided to serve the page as XML in the future.
I'm tempted to rip out all the ahref's and replace them with buttons
Well certainly if you have a thing you click on that isn't a link to another location, but simply does something to the page via script, then that's not a link really, and you'd be much better off marking it up as a <button> or <input type="button">, and using CSS to restyle it not to look like a button if you don't want it to.
However (again), this all seems rather pointless, as at the moment you are replacing the behaviour of a link with behaviour that just like a link only not as flexible. What's wrong with simply:?
disable

Categories

Resources