setting a javascript variable to a struts property map value - java

basically I want to do the following.
var myvar = '<s:property value="myMap['mapKey'].mapObjectValue" />'
but that fails. I've tried several variations of quotes and can't quite get it to work correctly. any ideas?
I can do this:
var myVar = <s:property value="myMap['mapKey'].mapObjectValue" />;
but then the javascript variable isn't a string, so I can't use it as needed.

If your first attempt is failing, I'm guessing that the problem is in the Javascript parsing. You might want to try escaping the string for Javascript, using Apache Commons Lang for example:
var myvar = '<s:property value="#org.apache.commons.lang.StringEscapeUtils#escapeJavaScript(myMap['mapKey'].mapObjectValue)" />';

It should be working, as the tag will be rendered before Javascript gets interpreted. If javascript value isn't getting setted properly, maybe
<s:property value="myMap['mapKey'].mapObjectValue" />
isn't returning the correct value.
As #BalusC said, theres is no need to make javascript compile on your IDE.

Related

Fetchinng JSON data from servlet to display on JSP [duplicate]

I have a form in JSP. I have to populate it based on the request object (from the servlet). How do I use Java Script for accessing request object attributes or if you can suggest me any other better way to populate form dynamically?
You need to realize that Java/JSP is merely a HTML/CSS/JS code producer. So all you need to do is to just let JSP print the Java variable as if it is a JavaScript variable and that the generated HTML/JS code output is syntactically valid.
Provided that the Java variable is available in the EL scope by ${foo}, here are several examples how to print it:
<script>var foo = '${foo}';</script>
<script>someFunction('${foo}');</script>
<div onclick="someFunction('${foo}')">...</div>
Imagine that the Java variable has the value "bar", then JSP will ultimately generate this HTML which you can verify by rightclick, View Source in the webbrowser:
<script>var foo = 'bar';</script>
<script>someFunction('bar');</script>
<div onclick="someFunction('bar')">...</div>
Do note that those singlequotes are thus mandatory in order to represent a string typed variable in JS. If you have used var foo = ${foo}; instead, then it would print var foo = bar;, which may end up in "bar is undefined" errors in when you attempt to access it further down in JS code (you can see JS errors in JS console of browser's web developer toolset which you can open by pressing F12 in Chrome/FireFox23+/IE9+). Also note that if the variable represents a number or a boolean, which doesn't need to be quoted, then it will just work fine.
If the variable happens to originate from user-controlled input, then keep in mind to take into account XSS attack holes and JS escaping. Near the bottom of our EL wiki page you can find an example how to create a custom EL function which escapes a Java variable for safe usage in JS.
If the variable is a bit more complex, e.g. a Java bean, or a list thereof, or a map, then you can use one of the many available JSON libraries to convert the Java object to a JSON string. Here's an example assuming Gson.
String someObjectAsJson = new Gson().toJson(someObject);
Note that this way you don't need to print it as a quoted string anymore.
<script>var foo = ${someObjectAsJson};</script>
See also:
Our JSP wiki page - see the chapter "JavaScript".
How to escape JavaScript in JSP?
Call Servlet and invoke Java code from JavaScript along with parameters
How to use Servlets and Ajax?
If you're pre-populating the form fields based on parameters in the HTTP request, then why not simply do this on the server side in your JSP... rather than on the client side with JavaScript? In the JSP it would look vaguely like this:
<input type="text" name="myFormField1" value="<%= request.getParameter("value1"); %>"/>
On the client side, JavaScript doesn't really have the concept of a "request object". You pretty much have to parse the query string yourself manually to get at the CGI parameters. I suspect that isn't what you're actually wanting to do.
Passing JSON from JSP to Javascript.
I came here looking for this, #BalusC's answer helped to an extent but didn't solve the problem to the core. After digging deep into <script> tag, I came across this solution.
<script id="jsonData" type="application/json">${jsonFromJava}</script>
and in the JS:
var fetchedJson = JSON.parse(document.getElementById('jsonData').textContent);
In JSP file:
<head>
...
<%# page import="com.common.Constants" %>
...
</head>
<script type="text/javascript">
var constant = "<%=Constants.CONSTANT%>"
</script>
This constant variable will be then available to .js files that are declared after the above code.
Constants.java is a java file containing a static constant named CONSTANT.
The scenario that I had was, I needed one constant from a property file, so instead of constructing a property file for javascript, I did this.
In JSP page :
<c:set var="list_size" value="${list1.size() }"></c:set>
Access this value in Javascipt page using :
var list_size = parseInt($('#list_size').val());
I added javascript page in my project externally.

Security flaws : How to avert them?

I am in a bit of a pickle :
I have a lot of values which i am setting in a bean in java and then i am getting them in javascript and jsp using scriplets like this :
In My Bean.java :
public void setListValue(String s) { listValue = s; }
public String getListValue() { return listValue; }
Now in my jsp(inside a javascript function) :
input = $input({type:'hidden',id:'ListVal',name:'ListVal',
value: '<%= results.getListValue() %>'});
Sometimes i am using the scriplet code to retrieve parametres in jsp as well.
Normally if a parameter is passed from java file to java file or from jsp file to jsp file , then i use native java encoder and decoder like this :
EncodedHere = URLEncoder.encode(encodedStr,"UTF-8");
DecodedHere = URLDecoder.decode(EncodedHere,"UTF-8");
This works flawlessly for those scenarios but if i have set my variables in java and then i try to retrieve them in javascript or jsp like the afore mentioned way , it fails. I have tried the JSTL way as well , but could not make it work, seems JSTL is not suitable to get values in javascript. Now this scriplet has been flagged as security concern by many. Since it's a huge code base it's very difficult to change that as well.
Does some one have any ideas as to avert this security flaw somehow. In other words, is there a way i can encode the variable in java and get the encoded string in jsp and javascript and then decode it ?
It sounds like your security guys are worried about XSS (cross site scripting) attacks, which means data entered by the user that is re-displayed on a page could have malicious code in it. If that is the case you actually don't want to URL encode the data, you want to XML escape it, i.e replace potentially dangerous characters like < with their corresponding character entity like <. To do this in JSP you can use the <c:out> tag or the fn:escapeXML EL function. This works perfectly fine in javascript code, even if it is a little ugly. In your case it would look something like this:
First escape the javascript before you put it on the request using an escaping library the ESAPI reference implementation:
String jsEscapedValue = ESAPI.encoder().encodeForJavaScript(results.getListValue());
request.setAttribute("listValue", jsEscapedValue);
Then on the page use the <c:out> tag to HTML/XML escape it:
var myJsValue = '<c:out value="${listValue}"/>';
Make sure jstl.jar is on the classpath and be sure to include the correct tag lib at the top of your page.
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

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

Printing a java scriptlet variable as if it is a JavaScript variable

hello i need to output a java variable inside a javascript call inside a tag inside a jsp !
for example:
<% String param = "hello";%>
<dmf:checkbox name="checkbox"
onclick = "selectAll(<%=param%>)"
/>
the javascript generated is:
selectAll(<%=param%>),this); but I actually want something like
selectAllCheckBoxes(Hello),this);
That's not escaping. That's just printing a scriptlet variable as if it is a JavaScript variable.
Besides, your examples are confusing, they doesn't match each other and the Javascript code is syntactically invalid. I can at least tell that JavaScript string variables are to be surrounded by quotes. If you want to end up with
selectAllCheckBoxes('Hello', this);
where Hello should be obtained as a value of the scriptlet local name variable (the param is a reserved variable name, you shouldn't use it yourself), then you need to do
selectAllCheckBoxes('<%= name %>', this);
In the same way, if you want to end up with
onclick="selectAll('Hello')"
you need to do
onclick="selectAll('<%= name %>')"
That said, I strongly recommend you to stop using the old fashioned scriptlets which are been discouraged since more than a decade. JSP programmers were been recommended to use taglibs and EL only to make the JSP code more clean and robust and better maintainable. You can use taglibs such as JSTL to control the flow in the JSP page and you can use EL to access the "back-end" data. Your example can be replaced by:
<c:set var="name" value="Hello" />
...
selectAllCheckBoxes('${name}', this);
Generate the whole attribute value with a scriptlet, like this:
<dmf:checkbox name="checkbox"
onclick = "<%= "selectAll(" + param + ")" %>" />
maybe you are trying to achieve this?
var myVar = '<%= (String)request.getParameter("tab") %>';
loadtabs(myVar);

Passing an HTML string to jQuery function

I'm working on an application which retrieves some HTML code from a record in a database. That strings then gets taken and inserted inside of a specific div. Right now I'm accomplishing this by passing the variable from Java and printing it within the div in the JSP. Now I'm trying to use an external jQuery function to accomplish this task and I'm struggling with how to pass this String to the jQuery function.
I tried something like this:
<script>
var message = <%=message %>;
</script>
<script src="files/js.js" type="text/javascript"></script>
But it can't seem to interpret the var once it hits the external function (I tried using StringEscapeUtils but that didn't fix the issue).
try:
var message = '<%= message %>';
var message = '<%=message %>';
$(message); // we have a jQuery object with a property
// for each html element in the message string!
When you run into problems like this, view the source of your page. How does message render? My guess might be
var message = Passing an HTML string to jQuery function;
Which isn't valid. Enclosing the code in apostrophies will fix this case.
var message = '<%= message %>';
I also usually put global objects like this on the window object so it is easier to find
window.message = '<%= message %>';
var message= <%= message %>;
You not only need to put some quotes around the message text, you also need to escape it suitably for a JavaScript string literal. Otherwise a quote in the message will break it, and potentially open you up to cross-site scripting attacks.
var message= '<%= message.replaceAll("\\\\", "\\\\\\\\").replaceAll("'", "\\\\'") %>';
I think that's the right number of backslashes, but the interaction of Java String literal backslashes and regex backslashes balloons them out of all sanity. Also control codes like newlines would need escaping if you need to include those.
All in all it might be best to hand the task off to a JSON-encoding library which will output all kinds of JavaScript types properly, not just strings. eg. with json-simple:
var message= <%= JSONValue.toJSONString(message) %>;

Categories

Resources