Play! Template syntax - java

I am using Play Framework 1.2.5. What is the difference between:
#{Application.render()}
and
#Application.render()
The first one is preferably used in the form action whereas the second one may be used for an anchor template. Both of them will be generating a URL, hence not able to understand which for the first one I need a {} surrounding braces.
Please let me know about this.
Thanks,

#{} is a short cut to generate a relative url based on a reverse route (Controller.method -> URL)
##{} gives you the absolute URL
#{} refer to tags. There just so happens to be an #a tag and you can do
#{a #Application.logout()}Disconnect#{/a}
because within the tag, you're actually passing the ActionDefinition when doing #Application.logout(), not the URL.
See http://www.playframework.org/documentation/1.2.5/tags

As far as I know, you need the curly braces when you use this in a template, for instance:
<form action="#{Application.post}">.
I just tried without the curly braces and that resulted in the exact string (#Application.render) and not an URL.
My code in the template:
#Application.index()<br />
#{Application.index()}<br />
Results in the following HTML in my browser:
#Application.index()<br />
/<br />

Related

ESAPI implementation for spring form tags

How can we implement ESAPI output encoding in an application using java and spring-mvc.
Read many posts and saw this:
<%# page import="org.owasp.esapi.*" %>
<input type="hidden" name="hidden" value="<%out.print(ESAPI.encoder().encodeForHTML(content));%>"/>
But, in my application all the jsps use spring form tags like the following,
<td>Number:
<form:input path="someNo" size="20" maxlength="18" id="firstfield" onkeypress="return PressAButton('submithidden');"/></td>
How can I have ESAPI implementation for above code? is there any other way of implementing output encoding like creating a filter or something? Any suggestions are greatly appreciated!
After researching spring tags a bit, it appears that the data-binding happens in framework code thus preventing you from applying any escaping in the jsp.
One, semi-quick win could be defaulting all output to escape HTML. Add this entry in web.xml:
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
The only problem here is that output-escaping is a BIG pain... the rules for html escaping are different when your value is going to be passed as data to an HTML attribute or a Javascript function. And there could be some parts of your application where you DO NOT want to html escape, but you should be able to override those with the form tag attribute htmlEscape="false" when you need to.
What you need is to be able to hook the part of Spring tags where it is binding the HTML to the form, but you need to be able to do it so you can escape based on where its being placed. Escaping rules are different for an HTMLAttribute as opposed to plain HTML and if the value is going to be passed as data to a javascript function. So Spring's solution only defends one category of attack.
These are the only ways out I see, all of them will require work:
Use JSTL tags instead of Spring tags so you can write your variables with ${thisSyntax} and wrap them in esapi tags like this:
<c:out value="<esapi:encodeForHTML>${variable}</esapi:encodeForHTML>"/>
Follow a solution like what #A. Paul put forward, where you do your context escaping back on the controller side. I'm aware you feel that this isn't an option, but the next solution I'm putting forward is untested.
Implement your own tag library that subclasses [org.springframework.web.servlet.tags.form.InputTag][1], specifically the method writeValue. While esapi prevents alot, I would recommend looking at owasp's new Encoder project to show you exactly how tricky output encoding is. Ideally your tag library will allow you to utilize either esapi's Encoder or this new API.
Just a thought not sure if this is what you are looking for.
Can you use the below code in Java and change the data in the bean itself and then send in the user interface.
if ( ESAPI.securityConfiguration().getLogEncodingRequired() ) {
data = ESAPI.encoder().encodeForHTML(message);
}
You can check the below url.
http://www.jtmelton.com/tag/esapi/

How to pass output of an <s:action> to a <s:url> value parameter in a JSP view?

I haven't touched Struts2 in a couple of years and have to do some maintenance on some JSP pages. But I can't figure out the proper syntax to pass the output from an <s:Action> tag to an <s:url> tag.
I'd like to do the following:
<s:action name="loadPath" namespace="/files" flush="false" var="filePath" />
<s:url value="#filePath.path"/>
But that does not work. However, I can see that my path property is properly set by doing:
<s:property value="#filePath.path" />
I've played around with %, # and $, but can't seem to find the right combination to get the value off the stack and into the s:url tag.
AHA!
After some more digging around, and trial and error, I finally found the right combination:
<s:url value="%{ #filePath.path }"/>
But I do not understand why this works. Can anyone provide an explanation why this syntax works and not just value="#filePath.path"?
I am not quite sure about what you are trying to achieve but perhaps these documents will help you:
Struts2 Action Tag Example
Struts2 URL Tag Example

Java Custom tag containing generated JSTL : not interpreted

I have a custom tag that has no body at all. I'm trying to programmatically replace the empty body with, for simplicity's sake,
[<c:out value="SUCCESS!"/>]
The goal is to see "[SUCCESS!]" displayed by the JSP which uses the tag, but all I see is "[]" and if I look at the generated source code, I can see that the c:out statement is written on the page between the brackets, but not interpreted.
Is there a common way to achieve this ? The final goal will be to use other custom tags instead of the "c:out" tag. The tags/content will come from a database.
I tried different techniques with SimpleTagSupport and BodyTagSupport but none of those were successfull. In fact I'm not sure if it is technically possible to do it, since, the tag has already been interpreted at that time.. But then how should this be done ?
Server tags (like your custom tag or JSTL tags) get transformed to Java code when the JSP is translated into a servlet. For example, the following JSP code:
<c:out value="FooBar" />
gets translated to something like this inside the servlet:
....
OutTag outTag = (OutTag) tagHandlerPool.get(OutTag.class);
outTag.setPageContext(pageContext);
outTag.setParent(null);
outTag.setValue(new String("FooBar"));
int evalOut = outTag.doStartTag();
....
In your custom tags you can call other Java classes/methods and can write HTML code (not JSP code) to the response.
The [<c:out value="SUCCESS!"/>] is not interpreted because at this level it's just a string that gets written directly to the response.

In JSP, what do the path and value attribute do within the input tag, and how does the form prefix affect them?

Just wanted a clear answer for a direct question -- google results have been all over the place or don't address the combos you'll see below.
I'm generally a JSP newbie and have been screwing around with the following code.
<form:input id="theId" path="path.copied.directly.fromSomewhereElse"
cssClass="contentTextInput" cssStyle="width: 229px" />
When I put that into my JSP page and load my website, it works fine and looks as my cssClass defines it. Then I start messing with it because I want it to display a default value.
<form:input id="theId" path="path.copied.directly.fromSomewhereElse"
value="blah" cssClass="contentTextInput" cssStyle="width: 229px" />
Suddenly, HTTP 500, an org.apache.jasper.JasperException! So I decide to remove the path altogether, while leaving in the value. This is just step 1 in something I know works because of prior experience. The code is now:
<form:input id="theId" value="someClass.valueIWantAsDefault"
cssClass="contentTextInput" cssStyle="width: 229px" />
That actually throws an exception, too -- but then I remove the form prefix and it works-- mostly. You see, the cssClass's effects are now gone; it looks like a regular, unaffected input textbox. Here's the code so far.
<input id="theId" value="someClass.valueIWantAsDefault"
cssClass="contentTextInput" cssStyle="width: 229px" />
What exactly do these attributes (and prefix) do that makes this mix-and-match work?
I'm guessing you're dealing with a jsp page that relies on a JSP custom tag library that's part of the Spring Framework. Here are the docs for the <form:input> tag. value is not a valid attribute for this custom tag as you can see in the docs link I provided above. When you remove the form:, you're turning the tag into a plain old HTML <input> tag which is why your error is going away at that point. It's also why your css stops working. cssClass is not the correct attribute for the HTML <input> tag. It's simply class. They called it cssClass in the jsp custom tag lib most likely to avoid a lower level collision with the Object.getClass() method (long story, just take my word for it).

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