Compiling JSP to string or bytearray memory with Tomcat / Websphere

I am doing image conversion and PDF output. I need an input HTML document that is generated by our JSP applications. Essentially, I need to map the final output product of the JSP application to String or memory, and then use this string for other processing.

In what ways can I just call the JSP handler to get the final HTML content that is usually displayed to the user? Ideally, I'm looking for something that will work for multiple application servers, such as websphere. But what is characteristic of Tomcat will also work.

There are several other approaches, but I think the best way for a JSP (which may include Sub JSPs) is a better approach.

Additional paths that I prefer to avoid.

  • I could do a network request to the page using the Socket API, and then read the final output that is displayed from that particular page. This is probably the next best option, but we work on multiple servers and the JVM, it will be difficult to target the required page.

  • Use the filter to get the final output. This is good, but I always had problems with filters and invalid exceptions. It seems like it never works 100% as I need.

It seems to be easy. The JSP compiler is essentially just a library for parsing a JSP input document and subdocuments, and then outputting some HTML content. I would like to call this process through Java code. On the server and possibly as a standalone console application.

+6
java jsp tomcat websphere
source share
1 answer

This is a completely annoying problem that I had to handle several times, and I never found a satisfactory solution.

The main problem is that the servlet API will not help here, so you need to trick it. My solution is to write a subclass of HttpServletResponseWrapper that overrides the getWriter () and getOutput () methods and captures the data into the buffer. Then you forward () your request to the JSP URI you want to capture, substituting a wrapper response for the original response. Then you extract data from the buffer, process it and write the final result back to the original response.

Here is my code that does this:

public class CapturingResponseWrapper extends HttpServletResponseWrapper { private final OutputStream buffer; private PrintWriter writer; private ServletOutputStream outputStream; public CapturingResponseWrapper(HttpServletResponse response, OutputStream buffer) { super(response); this.buffer = buffer; } @Override public ServletOutputStream getOutputStream() { if (outputStream == null) { outputStream = new DelegatingServletOutputStream(buffer); } return outputStream; } @Override public PrintWriter getWriter() { if (writer == null) { writer = new PrintWriter(buffer); } return writer; } @Override public void flushBuffer() throws IOException { if (writer != null) { writer.flush(); } if (outputStream != null) { outputStream.flush(); } } } 

The code to use it might be something like this:

 HttpServletRequest originalRequest = ... HttpServletResponse originalResponse = ... ByteArrayOutputStream bufferStream = new ByteArrayOutputStream(); CapturingResponseWrapper responseWrapper = new CapturingResponseWrapper(originalResponse, bufferStream); originalRequest.getRequestDispatcher("/my.jsp").forward(originalRequest, responseWrapper); responseWrapper.flushBuffer(); byte[] buffer = bufferStream.toByteArray(); // now use the data 

This is very ugly, but it is the best solution I have found. In case you are interested, the shell response should contain the original answer, because the servlet specification says that you cannot replace a completely different request or response object when forwarding, you should use the originals or their certified versions.

+6
source share

All Articles