I would like to invoke the JSP parser programmatically. That means that I want to be able, in Java, to 'run' a jsp page and get its output, without sending it back to the client (I actually want to save the output to a file). I don't want to 'forward' the request to the JSP page. I want to be able to do that on several JSP pages in a row.
What is the best way of doing this?
I have found this question, but BalusC doesn't really answer the question directly.
In case you are wondering, I need to do this is because I want to 'precompile' the JSPs for using on other platforms than a Java servlet container.
EDIT
What I need is not the .class file, but the HTML output. Indeed, that will be static once generated but I have some custom jsp tags and I want to leverage the JSP parser to expand them.
I'm not sure that I understand the point of all this.
JSPs are parsed and precompiled to .class files. They're Java servlets at that point. You need a servlet engine to execute them.
If your intent is to capture the generated HTTP response as the "precompiled" response, it would suggest that there's no dynamic content and the response is the same every time you send that particular request. If that's the case, what you've got is static HTML.
If I'm correct, this would seem to be a poor way to generate such a thing.
If your wish is to precompile JSPs to .class files, the problem is that different Java EE app servers use different JSP precompilation engines. You can't precompile JSPs using Tomcat and use them on WebLogic.
The best way to get the html output from a jsp page is to actually deploy it to a real webserver and then call the page and save the rendered output.
If you want to automate some part of this, you might want to look into using a testing tool that exercises through the real interface, such as Selenium or that emulates the browser, such as HttpUnit.
But this is doing much more than just invoking the JSP compiler.
Maybe it would be more practical to use template engines like http://freemarker.sourceforge.net/ or http://velocity.apache.org/
Freemarker even seems to support JSP Taglibs: http://freemarker.sourceforge.net/features.html
Is your JSP dynamically generated. If so then you are stepping into a potential disadvantage situation wherein your JSP will be compiled again and again, leading to performance issues.
However if you could have a single large JSP with all the rules that you need to prepare your display, you could use HttpClient to make a call to your own JSP and that would return the HTML. This would ensure that you are not app-server dependent. If you use JSP Parser you are going to be vendor dependent.
But if your JSP is being dynamically constructed then you should look at options wherein your HTML can be generated on Java side. But if it involved rule based HTML creation, you are better off creating it in Java. You can use Apache Jakarta ECS library for this.
And yes JSPs are not meant for this purpose.
Related
For GWT we use static constants to provide internationalization for our users. However, this makes reviewing and editing the texts a tedious process, because if one of our stakeholders has comments, it has to be compiled and deployed to our demo environment again. The solution would be to have some kind of semi dynamic text constants.
What I would like, is that I can compile to some kind of "review mode", and when I do that, the constants are read from a file from the server or database. If possible I would like to be able to edit this file, so stakeholders can modify the texts themselves (using some kind of text edit widget I would have to write for that). Then we can develop, test and demo with these texts. If we are satisfied, we compile for production mode, which uses a old fashioned constants resource bundle, compiled completely in JavaScript.
Does somebody know if something like this exists, or have some pointers on how to implement this?
It is a very surprising situation that GWT programmers often overlook the usefulness of JSPs and the Dictionary class. Even though many of us had tons of JSP experience prior to using GWT.
Dictionary class
You can define your "static" information as javascript var objects in the html hosting file. The Dictionary class can be used to read those javascript objects any time after moduleload.
JSP
The HTML "hosting" file, i.e. the html file used for launching GWT need not be an HTML file. It can be a HTML file dynamically generated by a JSP.
If you are familiar with JSP, you could turn an HTML file into a JSP just by changing its extension. Now turn the javascript object section you used for defining GWT "static" information into being dynamically generated by the JSP.
Voila!
I use JSP as the hosting file when I need to generate user- or session- specific "static" information for the GWT client. The JSP could read from the database or from some conditionally chosen text files.
If I'm using HttpServlet's for my controllers, and I've got my models setup and in a specific package, what about the views? The last thing I want is to dump all of this HTML into my controllers. Where do I put it? What file types?
I'm new to Java :)
Update
If I should be using jsp files, wouldn't having jsp files within my "Web Pages" section make them publicly viewable? Or should they go somewhere else? How do I include them on my page and pass parameters to them?
If you are using servlets (which seems to be the case), your view should go in JSP files. If you are using JSF, you put your view in facelets, but it is not the case since you are using servlets. JSF is the most recent specification, but I bet it is better to start by JSPs and servlets - maybe following the official tutorial.
EDIT: how to dispatch a request from the servlet to a JSP? Just get a RequestDispatcher from the ServletRequest passing the JSP path as parameter:
RequestDispatcher dispatcher = request.getRequestDispatcher("/index.jsp");
If the dispatcher is different from null, just call its include() forward() method:
dispatcher.forward(request, response);`
The dispatcher can be null (for example, if the JSP does not exist) so it is a good practice to verify if a proper dispatcher was returned.
jsps or javascript if you are going for a rich internet application (RIA).
You most likely want jsps.
JSPs are for views. So they should be public. JSPs dont expose anything except for html that your output just as you would in PHP. The source does not show unless you have configured your server incorrectly.
Also you can pass objects from servlet to jsp through shared objects as they are in same vm. JSP is servlet reversed so instead of printing HTML from java you embed Java in html which saves you from writing out.print statements....
So servlets are more suited to write actions. JSP for views.
You might also look into spending some time learning JSTL too. It makes your JSPs clean and readable: http://docs.oracle.com/javaee/5/tutorial/doc/bnakc.html
Keep in mind, a user will not be able to see the code in your JSP, the web container actually compiles the JSP file much like the JVM (actually in a very similar fashion) compiles source code. If you are using something like Tomcat, you can look at a compiled JSP in the work directory of your web container. It will look surprisingly like a normal class file with a lot of out.write's in it.
I started out with an html page. Then, I renamed the file with a .jsp extension, as I will be using jsp to accomplish this particular task.
Which is: I wish to take a value from the page on a form, send it to sql to be used in a where clause, then send the data set back to the same page. Now, I could likely employ AJAX, instead of submitting a form. I would appreciate some advice, like a step-by-step procedure, for I'm bewildered about at least a couple of items. 1) Can I write the JSP code in the same page? 2) Can or should I write SQL inside the JSP code? 3) Should I Have another page set up just for JSP?
I suppose I'm looking for a "Hello World" explanation, as I've primarily worked with non-java based languages in the past.
Thank you.
1) You can write JSP (Java) code in the same file, but it is not recommended.
2) Same as 1. you can write SQL code in JSP, but you shouldnt.
3) HTMLs renamed to JSPs are perfectly valid jsp files.
I suggest that you use a MVC framework like Spring MVC to do your task. Here's a tutorial.
UPDATE: Standard JSP & servlet tutorials
http://archive.coreservlets.com/Chapter3.html
http://archive.coreservlets.com/Chapter16.html
http://archive.coreservlets.com/Chapter15.html
http://archive.coreservlets.com/Chapter3.html
For quick and dirty, you should look at using the JSTL SQL tags. They're pretty easy to use, actually, and eliminate much of the JDBC cruft if you simply embedded Java.
This page is a decent little example that covers most of the fundamentals, for SQL with JSTL.
Overflowed Stack,
I have a Java web application (tomcat) whereby I allow the user to upload HTML code through a form.
Now since I am running on tomcat and I actually display the user-uploaded HTML I do not want a user to malicious code JSP tags/scriptlet/EL and for these to be executed on the server. I want to filter out any JSP/non-HTML content.
Writing a parser myself seems too onerous - apart from the lots of subtleties one has to take care of (comments, byte representation for the scripts etc).
Do you know of any API/library which does this for me ? I know about Caja filtering, but am looking at something specifically for JSPs.
Many Thanks,
JP, Malta.
Using a library for content cleaning is better than trying to do it yourself with e.g. Regexes.
Try Antisamy of the Open Web Application Security Project.
http://www.owasp.org/index.php/Antisamy
I didnt used it (yet), but seems to be suitable. JSP Content should be automatically removed/escaped by the HTML Normalization.
Edit, just found these:
Best Practice: User generated HTML cleaning
RegEx match open tags except XHTML self-contained tags
Don't worry about executing JSP code. Your JSP will be turned into a servlet once, so you will have something like:
out.println(contents);
and the contents won't be evaluated as JSP code. But you must worry about malicious javascript
Just save it as *.html, not as *.jsp, then it won't be passed through the JspServlet which does all the taglib/EL processing work. All taglibs/EL will end up plain (unparsed) in response.
I'm not sure if i have understand you question completly but if you whant to remove all content in suround with a "<%# .. %>" you can replace it with regex.
String resultString = subjectString.replaceAll("(?sim)<%# .*? %>", "");
I don't have a library to remove JSP tags, but you can write a little one based on regexp that would :
delete all "<% %>" tags
delete all HTML tags that contains the ':' character (to avoid "" tags for example
I don't know whether all potential malicious java code is included with theses two filters but it is a good start...
Another solution, but a little more complicated : use a http proxy server (Apache httpd, Nginx, etc.), that will serve directly static resources (css, images, html pages) and forward to Tomcat only dynamic resources (JSP and .do actions for example).
When a file is uploaded, you force the file extension to ".html". You are sure (thanks to the http proxy) that the file will not be interpreted by Tomcat.
If the pages supplied by the users aren't mentioned in the web.xml and you don't have a rule "anything that ends with *.jsp is a JSP" in web.xml, Tomcat won't try to compile/run them.
What is much more important: You must filter the HTML or users could add arbitrary JavaScript which would then steal other users passwords. This is non-trivial. Try to clean the code with JTidy to get XML and then remove all <script> tags, <link>, <object>, maybe even <img> (unless you make sure the URLs supplied are valid; some buggy browsers might run JavaScript if the image source is actually text/JavaScript, all CSS styles and make sure any href points to a safe URL. Don't forget <iframe> and <applet> and all the other things that might break your secure shell.
[EDIT] Thats should give you an idea where this is going to. In the end, you should do the reverse: Allow only a very small subset of HTML -- if at all. Most sites (like this one) use special markup for the formatting for two reasons:
It's more simple for the user
It's more secure
I am working on a project which is basically a Java application with an embedded IE browser (using JDIC 0.9.5) to display custom HTML files (stored locally that I created). I have a test HTML file with a JavaScript function that checks a simple form with checkboxes and alerts the user with a dialog stating which checkboxes are checked.
My question is, is there a way for my Java application to do the same procedure on the embedded HTML form instead of using JavaScript. I want to keep my application and HTML files simple without the clutter of JavaScript in my HTMLs or a pile of .js files.
Thanks for any help and guidance!
You have two options. Either shift the project to run the Java on the server side using JSP technology inside a web container like Apache Tomcat or Jetty, or write you web page to open up a Java applet.
The applet route allows you to run the code on someone else's machine, and as a trade off you will have to run the application in a strongly security constrained environment. After all, if someone were to run code on your machine, you wouldn't want it able to access your disk, etc.
The JSP solution will have you running the code on the same machine as your web server, since you (probably) control your own web server, the code will not be ran with as many security constraints enabled. This means the code can make requests to other machines, write and read files, etc.
You could replace your model with a client-server model using Java Server Pages (JSP).
If you are displaying the page through an embedded browser it is very unlikely that you will be able to get access to the DOM via Java.
One option is to use GWT javascript compiler to code in java and then convert to javascript. If it will only use IE, then you will only need to keep one of the generated .js files, so the clutter will be low.
Since you're embedding your HTML files in your own Java program, I would recommend you to use one of these 2 approaches:
1.- Use Javascript and structure the files cleanly, is not that complex.
2.- When you do the POST check the values in your Java code and return a new dynamically generated HTML file with needed info
I sincerely recommend you to follow the first option. Other options to work with Java in HTML would be JSP or GWT, but both will require a proper J2EE server, which would be overkill in your application