I have a JSP page which doesn't actually have any server tags in it so its basically an HTML page. But, my work is in love with JSP so I set it as a .jsp file. Anyhow, Tomcat is under the belief that my JavaScript is in fact Java code and tries to parse it. I get a nice big error on the screen saying its not a real function, etc. Could anyone tell me why its doing this? Code below...
...
<script>
$(function() {
$.dragAndDrop({
dom: {
fileList: '#fileList tbody',
contextMenu: '#fileContextMenu',
dropzone: '#dropzone'
},
templates: {
file: '<tr><td>${fileName}</td><td>${$.dragAndDrop.getDate()}</td><td>${$.dragAndDrop.parseSize(size)}</td></tr>'
}
});
});
</script>
...
The error:
org.apache.jasper.JasperException: /index.jsp(22,42) The function getDate must be used with a prefix when a default namespace is not specified
org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:148)
${} marks expressions for evaluating via JSP. As you say you don't use any JSP, you can disable the expressions language by adding
<%# page isELIgnored="true" %>
to your page.
It is likely the ${ notation
Try replacing this code ${$
with something like this $' + '{$
or $<%='{'%>$
I don't know if there is a proper way to escape that,, but what I just gave you should work.
See Google for more information. The top result looks good but I could not find how to do a proper escape: http://www.google.com/search?q=jsp+dollar+sign
Related
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.
I am using sitemesh for a spring based site. The problem is that I have some javascript that I want it to run on the onload event of only one specific page using jquery $(function() { ... }) and not on every page.
I have included the jquery.js in the bottom of my decorator, after the body. So, if I try to include a <script> tag in the body of my decorated page the script won't be executed because jquery will be loaded after that! I know that I could include the jquery.js in the header of my decorator so it will be before the custom script in the decorated page however I don't really like that solution since it will contain javascritp in the head of my page.
So I would like to have something like a placeholder in my sitemesh decorator in where the custom from my decorated page will be placed (as you can understand I come from the django world :p). Is this possible ? Do you propose anything else or should I just put my jquery.js in the header and be done with it ?
To answer my question, after some search I found the following solution:
I Added the following to the end of my decorator page (after including jquery.js)
<decorator:getProperty property="page.local_script"></decorator:getProperty>
I also added the following
<content tag="local_script">
<script>
$(function() {
alert("Starting");
});
</script>
</content>
The decorated result page contained the contents of the local_script tag exactly where I wanted them and everything worked fine :)
I don't know why this feature of sitemesh is not properly documented - using this you can have a great templating behaviour (like django).
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"%>
I have two different divisions in a JSP page. One contains a menu of links, when clicked the div2 (id-content) loads different pages accordingly. I am doing something like -
<div id="menu">
<ul class="navbar">
<li><a name="login" href="Login.jsp" onclick="changeContent()">Login</a>
</li></div>
and in the script I have something as -
<script language="JavaScript">
function changeContent() {
document.getElementById('content').load('Login.jsp');
}
</script>
I also tried -
document.getElementById('content').innerHTML=
"<jsp:include page="Login.jsp">";
None of the ways worked. Please suggest how should I
Try jquery..
function changeContent() {
$('#content').load('Login.jsp');
}
The solution is to use Ajax, which will asynchronously retrieve your page content that can be pasted in with the innerHTML method. See my answer to a similar question of how an Ajax call works and some introductory links.
As to why your examples in your answer don't work, in the first case there is no load() method on an Element object (unless you've defined one yourself and not shown it). In the second example, as one of the question comments says, there is probably something causing a syntax error in the javascript.
As an FYI, when there is a syntax error in some javascript in a web page, the current expression being parsed and the rest of the <script></script> block will be ignored. Since this is inside a function declaration, that function will never get defined.
For instance, an embedded quote in the included page will end the string for the innerHTML assignment. Then the javascript parser will try to parse the remainder of the HTML causing a syntax error as the HTML will not be valid javascript.
We use jquery. Add a click event handler to the anchor elements. In the click handler call $('#content').load(your_url);. You might want to use the load(url, function() { ...}) version. More info here http://api.jquery.com/load/
Your initial page comes down from the server. It's displayed by the browser. When you click on a link (or a button) in the browser, you want to fill the second div with new HTML. This is is a perfect job for an AJAX request. What the AJAX object in the browser does, is to send a POST (or whatever) string to the server. And then the Ajax object receives the HTML response back from the server. And then you can display that response data which the AJAX object contains, anywhere you want.
arrays.jsp:
//...
var x = <c:out value="${x}"/>
<c:if test="${empty doExternal}">
processExternalArrays();
</c:if>
//...
I want to minify/obfuscate JavaScript contained in a large JSP file in which numerous JSP/JSTL variables are mixed into the JavaScript code such as in the snippet above.
The code relies on variables populated using server-side logic and then passed to the client-side code, as above.
I'm already minifying my JS files using YUI compressor but I don't know what to do about the JavaScript code in my JSPs.
Is it possible to minify/obfuscate this code, given that it is dynamically created?
Probably the best solution for you would be use Granule JSP tag.
You can download it at
http://code.google.com/p/granule/
code sample is:
<g:compress>
<script type="text/javascript" src="common.js"/>
<script type="text/javascript" src="closure/goog/base.js"/>
<script>
goog.require('goog.dom');
goog.require('goog.date');
goog.require('goog.ui.DatePicker');
</script>
<script type="text/javascript">
var dp = new goog.ui.DatePicker();
dp.render(document.getElementById('datepicker'));
</script>
</g:compress>
...
Have you taken a look at htmlcompressor? In short it's a:
Java HTML/XML Compressor is a very
small, fast and easy to use library
that minifies given HTML or XML source
by removing extra whitespaces,
comments and other unneeded characters
without breaking the content
structure.
It's main function is so compress HTML and XML, but it also comes with JSP tags that can be used to compress inline JavaScript blocks by leveraging YUI Compressor. Check out the Google Code page, especially the Compressing selective content in JSP pages section.
I don't see other ways than fully delegating the job to pure JS with help of Ajaxical powers in combination with a Servlet which returns the desired information on an Ajax request (in flavor of JSON?).
E.g. in Servlet
Map<String, Object> data = new HashMap<String, Object>();
data.put("doExternal", doExternal);
data.put("x", x);
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().write(new Gson().toJson(data)); // Gson is a Java-JSON converter.
and in JS (with little help of jQuery since it makes the Ajax works less verbose)
$.getJSON('servleturl', function(data) {
var x = data.x;
if (!data.doExternal) {
processExternalArrays();
}
});
This way you end up with clean JS without server-side specific clutter.
Ensure that your output is gzip encoded (apache mod_deflate). Minimizing the html/js first may make it a bit smaller, but not by much.
If you can't, or don't want to, move your JavaScript out of your HTML, one possibility would be to create a tag handler that wraps the content of your <script> tags:
<script type="text/javascript"><js:compress>
...
</js:compress></script>
The handler could probably extend SimpleTagSupport. You'd then have to investigate the Java APIs for compressors/minifiers, like YUI Compressor or dojo ShrinkSafe, and use them to process the tag body.
Edit: Sorry, I skimmed the other answers and it appears that Zack Mulgrew might be referencing a taglib that already does exactly what I'm suggesting...
Edit2: Yup, JavaScriptCompressorTag. Guess I'll have to up-vote his answer ;-)...