tags:

views:

1316

answers:

4

Hi to all!

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!

+3  A: 

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.

Brian
+4  A: 

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.

ChssPly76
Thanks for your advice. I actually don't want to implement my own servlet container. I don't want to compile and process JSP too, but I don't see any alternative for what I look for.I want to create server responses as a JSON like this: {html1: "<pre>1</pre>", html2: "<script>...</script>"}Every html has to be made with JSP, but the JSON can't be there. I used FreeMarker and I don't see how if it can help.If you know some way for doing what I'm looking for, I would appreciate.Thanks.
I'm not quite clear on what you're trying to achieve. Are you returning that JSON response from an application running _outside_ a servlet container? Why? I have a hardest time imagining using JSON for inter-app communication. If you could clarify what you're trying to do a bit more I'd be happy to help. The difference FreeMarker would make is that you can run it completely from within your app without having to fake servlet environment. E.g. every 'html' fragment in your response would be produced by a separate FTL template and you'd just call Template.process(model, writer) on each.
ChssPly76
A: 

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

Pablojim
A: 

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)

Aaron Digulla