In my web.xml I set context param "pathToImages". In my jsp files to get path to my images files I use EL, like this:
<img src="${initParam.pathToImages}"/image.jpg" />
But I have problem with JavaScript. In my js files I have code:
setInnerHTML("somePlace", "<.img src='images/s.gif'>");
I know this isn't beautiful code but it isn't mine :) I cannot get my pathToImages in the same way like from jsp. What is the best way to do this?
Pass it as parameter to the js function: function createImage(path) {..} and invoke it with createImage('${initParam.pathToImages}')
Another, perhaps a better option is to have a js variable and initialize it with the desired value. In the JS file:
var imagePath;
function init(config) {
imagePath = config.imagePath;
}
and in your header:
init({imagePath: '${initparam.pathToImages}'});
If you are using templates to build your pages (i.e., tiles or velocity templates) you could assign the variable in your base template with a scriptlet, like:
<script> var imagePath = '<%= config.getServletContext().getInitParameter("pathToImages") %>'; </script>
Then you can refer to the imagePath variable in your js files.
Not pretty, but I don't believe there is a way to access the servlet context from a javascript file directly.
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 newbie to external javascript files (*.js). Basically I have my JSP ready but my manager wants me to add graphics in it.
So I found some *.js files. But I don't know how to communicate between them and my JSP page.
I want to pass data from jsp to external .js file.
Is there any mechanism to do that?
For e.g:-
Demo.jsp
out.print(request.getAttribute("Name"));
Now I want use/pass/set above value to main.js file how to do that?
<script type="text/javascript">
var myJavascriptVariable = <%= request.getParameter("Name")%>;
//or .getAttribute("Name")
</script>
This could do the trick, it will make a global Variable which could be accessed in main.js. When you have GET Parameters you could also use only JS:
var paramarr = window.location.search.substr(1).split("&");
var params = {};
for (var i = 0; i < paramarr.length; i++) {
var tmparr = paramarr[i].split("=");
params[tmparr[0]] = tmparr[1];
}
or a bit shorter:
var params = {};
// parse URL's GET parameters and iterate over them
window.location.search.substr(1).split("&"),forEach(function(el) {
var kv = el.split('"'); // split into [ key, value ] array
params[kv[0]] = kv[1];
});
Now you can access the parameter in JS via:
params['name']
Personally I would use AJAX (e.g. with the help of JQuery) to get Data for my JavaScript files, you can look at that at http://api.jquery.com/category/ajax/shorthand-methods/ (2018 edit: kust use native ajax calls or whatever JS framework is hyped this week ;-) )
If you are using .js file you can't write jsp sriptlet in it.
If you need to call value in .js file there is one simple way.
Assign values to input elements in .jsp page.(If you are not using values in .jsp page assign values to hidden input elements)
Then include.js file in your .jsp page
get values as javasript or jquery methods.
Ex:-
value= document.getElementById("element_id").value
OR If you are using jquery you can get as
value = $("#element_id").val();
You can declare a global js variable and assign the value.
<% String myValue = (String)request.getAttribute("Name"); %>
var global1 ='<%= myValue %>';
Is this possible? I want to be able to pass java bean data into javascript objects, but I'd really prefer not to muck up my jsp pages with a bunch of inline script tags. I like to keep my javascript separate in external files, but how do you accomplish something like this without using inline js?
<script type="text/javascript">
var variableFromServer = '${someBean.someProperty}';
</script>
You can create a JSON file with all the data and either include it inline or fetch the JSON through Ajax - that way you don't clutter the markup with data. See http://json-taglib.sourceforge.net/ for an example of a JSP-JSON template.
I'm not sure if this is worth it but one alternative will be to set the desired value in an input filed with type="hidden" and get it's in js. But this will also pass this parameter in GET and POST request from the form.
You can either do what you're doing in the snippet (do you consider that "inline JS"?), create a div of JSON with data in it (exposed as a single string) and process it, pass JS files through the JSP process (or use a different templating system for dynamic JS pages), etc.
I'm not a huge fan of processing JS files through JSP; I'll often create an object containing all the info my JS needs in a <script> tag at the bottom of the body before including my real JS. It's kind of lazy, but it's straight-forward.
One option that I've used in the past is to configure the servlet container to run the JSP interpreter on *.js files. How to set this up will depend upon what server you are running.
Note that if you want to access any request attributes this way you will need to set them up as part of the request that fetches the JavaScript file(s) (i.e. you will have to have a servlet in front of your JavaScript...or as an alternative you can use an include directive to bring in the scripts instead of a <script src='...'> tag). Session attributes you can access without needing to have a custom servlet in front of your JavaScript files.
I'm a fan of doing it the simple and easy way, so I'd create a single script element that has a minimal number of JS variables set from Java - ideally a single JS variable that is set to an object with different properties for all the different bits of data you need to pass through. Your Java code basically just outputs JSON that will be interpreted as an object literal in the JS. Immediately after that include any external scripts - because they're included afterwards they can use the variables already created.
You can put the above in the head or at the end of the body. (Or in the middle, but that doesn't really make sense.)
<html>
<head>
</head>
<body>
<!-- actual HTML markup here -->
<script>
var variableFromServer = '${someBean.someProperty}',
objectFromServer = /* jsp to spit out JSON here as appropriate */ ;
</script>
<!-- external files included after the above will be able to access
those variables -->
<script src="external1.js" type="text/javascript"></script>
<script src="external2.js" type="text/javascript"></script>
<script src="etc.js" type="text/javascript"></script>
</body>
</html>
You certainly don't need "a bunch of inline script tags" - even if it doesn't make sense to put all the values in a single object at least create all the variables in a single script element, and then all of your other JS can be in an external file.
(Add namespacing as required.)
I retrieved a blob along with some other data from a table, say name and image:
name = varchar, image = blob
I set this to an object in my filter and pass it to the JSP file:
request.setAttribute("info", object);
In the JSP file I get that data:
request.getAttribute("info");
Now that I have the data from that object how do I go about passing that info to my JS file and render the image as a source for the JS file?
I'm trying:
<div>
<script type="text/javascript" src="jsFile.js></script>
</div>
var name = <%=info.name%>;
var image = <%=info.image%>
It just doesn't seem to be working. What is the correct method of doing this?
This isn't going to work. Leave the blob there in the server side. JavaScript on the client side can't do anything sensible with binary data. All it needs is an URL of the image so that it can reference it in the src attribute of a HTML <img> element, so that the webbrowser can in turn do its job of downloading and displaying the image. Best would be to include the image identifier in the URL. The name is unique for the image, right? Use that in the URL instead.
The first step is to let JS create a HTML <img> element with the proper src attribute which points to an URL which returns the image. Assuming that you're preparing the data like follows
String name = "foo.png";
String imageURL = "imageservlet/" + name;
request.setAttribute("imageURL", imageURL);
and are printing it in JSP(!) as if it are JS variables as follows
<script>
var imageURL = '${imageURL}';
// ...
</script>
(please note that those singlequotes are thus mandatory to represent them as a JS string variable)
so that they end up in the generated HTML source like follows (rightclick page in browser and do View Source to verify it)
<script>
var imageURL = 'imageservlet/foo.png';
// ...
</script>
then you can create the image as follows
var img = document.createElement("img"); // or getElementById("someId")?
img.src = imageURL;
// ... add to document?
(please note that this is just an example, I have no utter idea what the functional requirement is and what you would like to do with this image element, even more, perhaps JS code isn't needed at all for the concrete functional requirement)
so that it ends up like this in HTML:
<img src="imageservlet/foo.png" />
Now, the second step is to create a servlet which listens on an URL pattern of /imageservlet/*, retrieves the image as an InputStream from the database by the passed-in indentifier and writes it to the OutputStream of the response along a set of correct response headers. Long story short, I've posted several answers before as to how to do it, they contains kickoff code snippets:
How to retrieve and display images from a database in a JSP page?
Writing image to servlet response with best performance
You can access your data from the script if you set the variables in a script block before your jsFile.js. Ie:
<div>
<script type="text/javascript">
var name = <%=info.name%>;
var image = <%=info.image%>;
</script>
<script type="text/javascript" src="jsFile.js></script>
</div>
I'm not sure how you intend to handle the binary (BLOB) image data however? Typically this would be written to an image file on the server and referenced via an img tag:
<img src="/path/to/myimage.jpg" />
Instead of passing your blob data to the JSP file, I would suggest having the server (your servlet) pass a URL to the JSP which the browser can use to get the image via an img tag. You can either write the blob data to a URL or write a servlet that writes out Content-type: image/jpeg (or similar) data when passed an id, ie:
<img src="http://www.yourserver.com/GetImage?imageId=xxx" />
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 ;-)...