Read a JSP file and produce HTML - not with a web server - java

If I wanted to read a jsp like:
File f = new File("my.jsp");
and then I want it to produce the expected HTML as say a String (byte[], OutputStream, whatever), How would I do that?
I assume there is some transformer or something. Can anyone point me in the right direction?

A JSP File is translated and compiled as a Servlet class, so it not directly generate a html File, the reason is a JSP as a Servlet could generate dynamic html depending of the parameters in the request, in the tomcat server it use the Jasper 2 JSP Engine to implement the JavaServer Pages 2.1 specification that process the JSP, so you can check it but I don't recommend you do that.
Maybe what your really want is a template mechanism, for example you have a text file similar to the jsp with similar sintax to the EL that can access some objects, so you can use the template engine and bound your object with the text and produce your html. If it works for you, you can use Apache Velocity - HTML example or FreeMaker - HTML example.

Jasper is the JSP compiler used by Tomcat, it takes the JSP pages themselves, parses them, and generates Java code (in the form of a servlet, or at least it used to be) which writes the JSP's output to the servlet response. That Java code would then be compiled and executed against the containers implementation of the Servlet API.
Jasper is a standalone library, so in theory you could instantiate its classes inside your own harness, point it at a JSP, generate the servlet code, then compile and execute it. However you'd need to pass in your own mock implementations of the Servlet API interfaces, as it's these that will be called to determine request parameters (HttpServletRequest), and to write the response (HttpServletResponse). You'd need to provide a version of HttpServletResponse that will buffer up the output for you to grab later.
From the Tomcat 6 API, this bits your want are in the org.apache.jasper package.
Taking a look at at it you'd probably want to create a JspCompilationContext which points to your JSP, call createCompiler(), and take it from there.
As far as mocking out the Servlet API goes, you might get what you need from the stub implemetations provided by the Spring Framework for testing purposes

Velocity and FreeMarker are both excellent for this, and much easier for basic templating.
However, it can be done.
I have an example explained here: Tomcat JSP/JSTL without HTTP
It's obviously easier from within a web app (as all of the jars will be there), but it can be done outside, you'll just need to identify and the appropriate jars to your program.

Related

Interact with JSP compiler

I have some text templates stored in a database. We need to use a templating engine to process these texts. We first thought of Velocity / Freemaker / Thymeleaf to process these texts. However, I thought (but could be wrong) that one could interact with the application server JSP compiler. I'd prefer to use JSP compiler rather than importing a new bunch of jars.
Thanks
AFAIK they are different concepts and work differently so they won't directly interact :
JSP is processed by a JSP compiler to generate java code for a servlet that is compiled (at run-time) in a .class file. It is later used by the servlet container as any other servlet. You can include any java code in a JSP with scriptlets (even if it now considered as bad practice)
template engines (Velocity / Freemaker / Thymeleaf) take a template and only allow to replace variable place holders with values at run time to produce text. Of course, they also allow tests and loops, but no java source nor class object is ever generated. In a web application they use one single servlet that takes the template and the replacement values and generate the text that will be sent in the response.
But of course as JSP can contain arbitrary java code, you could call a template engine from a JSP, but I really cannot imagine a proper use case.
Edit per comment:
You could try to use JSP as a template engine, but my advice is : don't do that ! You would need :
create a stub implementing ServletResponse where the getOutputStream() and the getWriter() methods end in a String.
force the ServletContainer to generate the java source and the class file - or manage to do that at compile time (I don't know how exactly how to do that, but I'm pretty sure it can be done)
at run time include the generated servlet with the response stub to generate the output String.
But beware, even if you succeed, it will lead to hardly maintainable code heavily coupled to a servlet container or using special steps (JSP -> java) at build time. As already said : don't do that.
I've just come to JSP compilation to string or in memory bytearray with Tomcat/Websphere, looks like your question is a duplicate of that one ...

What is Ruby's counterpart to Java's web.xml?

I'm working with Redmine for the first time and was able to successfully install it locally. I haven't used Ruby before and I come from a Java background.
I am able to run the application by going to -
http://localhost:3000/projects
The question is, where can I find the html file (if it exists) that corresponds to http://localhost:3000/projects. In Java, we can do this by looking at web.xml or the relevant Spring configuration file and see how the URL is mapped to a servlet or controller. How to do this in Ruby?
The counterpart of web.xml is the routes.rb and the config.rb files in ruby. You'll find them in the config directory. The routes.rb defines which controller and action (much like servlets) will handle a certain request (URL). And since Rails has predefined conventions, all the html files go in the folders named after the controllers in the views directory and by convention the html file with the same name as that of the controller's action that has been invoked will be rendered as the response.
But all of this can be overridden if desired.
This is a nice place to start understanding Rails: http://guides.rubyonrails.org/
Note that Ruby is not the same as Rails.
Ruby, like Java, is a programming language. It appeared in 1995. For example, the following is a script/program you can execute from the command line.
#!/usr/bin/env ruby
puts "Hello World"
Rack is a web server interface for Ruby. It handles the HTTP protocol, and allows one to write web applications in Ruby by making it easy to parse HTTP requests and send HTTP responses.
Rails is a web framework with powerful conventions, patterns, and tools for developing web applications in Ruby. Some part of it uses Rack. It appeared in 2004. Sinatra is an example of another web framework that uses Rack.
What's the equivalent of web.xml in Ruby?
It does not exist.
What's the equivalent of web.xml in Rack?
Probably config.ru.
What's the equivalent of web.xml in Rails?
config/routes.rb and config/application.rb. Please refer to Configuring Rails Applications.
Routes
To figure out which html file corresponds to http://localhost:3000/projects, look in config/routes.rb. If you see
resources :projects
then it is handled by the index action in ProjectsController with the view at app/views/projects/index.*.
Rails follows convention over configuration principle so all views can always be found in
app/views/
and the one you are looking for should be (depending on Redmine template processor)
app/views/projects/index.html.erb
Also a convention is that view files are named like
path/to/view/_action_name_._content_type_._processor_
In Rails you can find all the mappings to the routes of your web app looking at the routes.rb file in the config folder inside your project folder.
For example, if you want to configure the index page in your project, remove the index.html.erb in the public folder and do like:
root :to => "yourController#someAction"
Understanding routes is not an easy task for someone coming from a Java background. But this should help.

Java & Heritrix 3.1.x: Web Content parsing?

Since the developer documentation for Heritrix 3.x is largely out of date (most of it pertains to Heritrix 1.x, as most of the classes have been changed or code has been significantly rewritten/refactored), could anyone point me to the relevant class (or classes) of the system that deal with the actual web page content extraction?
What I want to do is obtain the content of a web page Heritrix is about to crawl and then apply a classifier to the web page's content? (analyze structural features, etc.) I think this functionality may be distributed among the ContentExtractor class and its many subclasses, but what I'm trying to do is locate the point where I have either the web page content in its entirety or in a readable/parse-able stream. Where is the content (the html) that Heritrix applies regular expressions to (in order to find links, certain file types, etc.)?
I suggest looking into a custom WriterProcessor I wrote a custom MirrorWriter that looks at the incoming data, and writes files to different locations as they come it for later post-processing. The code for the MirrorWriter class is rather straight forward and well commented.
The documentation is here: http://builds.archive.org:8080/javadoc/heritrix-3.1.0/org/archive/modules/writer/MirrorWriterProcessor.html
If you are dead set on pre-processing, you can work with extending the org.archive.modules.extractor.ExtractorHTML and do a on-the-fly version. http://builds.archive.org:8080/javadoc/heritrix-3.1.0/org/archive/modules/extractor/ExtractorHTML.html

JSP recompilation needed?

I just want the general idea about what will happen in the following situation, without getting into the technical details.
The main advantage of JSP is that we have separate presentation (static HTML) and dynamic application logic. So we can make changes into either of them without affecting the other. Now suppose, we have a precompiled JSP into either a servlet or bytecode, and we want to make a change in the presentation part, would we then have to recompile the whole stuff, even though we did not make any change in the application logic?
Thanks everyone for the answer, but all the answers that I get do point to the fact that whether automatically or manually, the JSP does need to be recompiled into the servlet, which is then converted into the corresponding byctecode. In short a completely new file would be created I suppose.
As long as it is JSP, you dont need to compile/convert. The application server automatically translates your JSP into corresponding servlet, a Java file (on the first hit to the JSP), and then compiles it to class file. Whenever you update the JSP file and when the server receives request for that resource (JSP) it checks the last updated time and does the above job if required.
Yes and no. JSP's are ultimately compiled into servlets, but the servlet container will usually recompile the JSP for you if it has changed, which is a fairly quick operation.
No. If you change the JSP, generally speaking the servlet/jsp container will 'see' the jsp changed and will recompile it.
That being said, i'm not clear on your deployment model. if you're 'precompiling' the asps and adding those to your .war then you might be out of luck.

Execute JSP directly from Java

I need to execute a JSP. But I need to directly from Java, without using Tomcat or any other servlet container. Compiling JSPs would be a good thing too, but not necessary. I think maybe org.apache.jasper package is good for doing this, but I can't find any good example or tutorial online.
I need something as:
Class compiledJSP = compileJSP(new File("helloWorld.jsp"));
String html = executeJSP(compiledJSP, httpServletRequest, httpServletResponse, ...);
html --> "Hello World, John!"
Thanks!
If you need to capture JSP's output as string it's reasonably straightforward (although far from ideal from the design point of view) from within Servlet Container:
1. Extend javax.servlet.HttpServletResponseWrapper and override getWriter() / getOutputStream() methods to provide your own buffered versions (e.g. StringWriter)
2. Invoke "include()" method of RequestDisparcher, wrapping original response in your own.
3. Grab buffer's content.
Now if you need to do the same thing outside Servlet Container, you really need to ask yourself "why?". Perhaps you should be using a template engine (FreeMarker / Velocity / StringTemplate / etc...) instead of JSPs? If your JSPs are well-formed XML files and are not using any java code inserts it may be reasonably trivial to convert them to FreeMarker templates (FreeMarker supports custom JSP tag libraries) which would greatly simplify your task.
Nevertheless, if it's an absolute hard requirement your most straightforward options are:
1. Run an external Servlet Container and let it handle JSP interpretation. Your program would submit HTTP requests to it and capture the output.
2. Same as above, but you can run embedded Servlet Container (e.g. Jetty).
If your JSPs are available at build-time you can precompile them via Jasper as suggested in other answers.
I would strongly advice against trying to implement your own servlet container - you'll be walking into a world of hurt.
You will need a container. A JSP is an abstraction on Servlet. Servlets have a dependency on a life cycle provided by a container.You need a container to provide the life cycle.
This is possible without a servlet container. There are two steps to it.
The first is to generate the source code. If you look at the source code of the jspc ant task it is possible to do it directly in code. Or you could just invoke the ant task.
The code that is generated is just a Servlet and it is possible to invoke the methods on a servlet outside of a container:
Just instantiate it and then call doGet(request, response). I'm not sure exactly what you need this for but your life will be made easier using spring mock objects for the http request and response.
This will populate the Response object. you can then get the output with:
res.getContentAsString();
See an example here:
http://ytreyvus.blogspot.com/2007/03/private-void-cloneplaneffectrelationshi.html
Try MockRunner to execute it. You'll need to compile the JSP first, though. I'm using Maven 2 for this (and the JSP Compiler plugin)

Categories

Resources