3

How can I execute a JSP in controller and get html response in Sring variable without using HtmlServletRequestWrapper

following is my code, i am trying to hit jsp get response html str and pass that html string to itext to generate pdf.

@RequestMapping(value = "/dosomething", method = RequestMethod.GET)
public void dosomething(HttpServletRequest request, HttpServletResponse response)  throws IOException {
    // setup your Cookie here
    response.setCookie(cookie)
    request.getRequestDispatcher("/WEB-INF/jsp/account_summary.jsp").include(request, response)

}
3
  • Why do you want to do this? Commented Aug 21, 2013 at 15:29
  • It would be better if you explain your functional requirement Commented Aug 21, 2013 at 15:29
  • am trying to hit jsp get response html str and pass that html string to itext to generate pdf. Commented Aug 21, 2013 at 15:36

2 Answers 2

4

Edit:

I ended up writing this bean (using HtmlServlet*Response*Wrapper :-)), I hope it could be useful for someone (thanks to: Reading ServletOutputStream to String)

(The viewResolver is autowired so it needs to be defined inside the the servlet context)

import java.io.IOException;

import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;

public class InternalRenderer {

    private final static String ENCODE = "UTF-8";

    @Autowired
    private ViewResolver viewResolver;

    public String evalView(HttpServletRequest request, HttpServletResponse response, Model model, Locale locale, String viewName) throws Exception {

        CustomHttpServletResponse customResponse = new CustomHttpServletResponse(response);

        View view = viewResolver.resolveViewName(viewName, locale);

        if(view != null){

            view.render(fillModelMap(model), request, customResponse);

            OutputStream os = customResponse.getOutputStream();

            return os.toString();

        }

        throw new Exception("no view found");
    }

    private Map<String, Object> fillModelMap(Model model) {

        if(model == null)
            return new HashMap<String,Object>();

        return model.asMap();
    }

    class CustomServletOutPutStream extends ServletOutputStream {

        private StringBuilder stringBuilder = new StringBuilder();

        @Override
        public String toString() {
            return stringBuilder.toString();
        }

        @Override
        public void write(int b) {
            stringBuilder.append(b);
        }

        @Override
        public void write(byte b[], int off, int len) throws IOException {
            stringBuilder.append(new String(b, off, len, ENCODE));
        }
    }

    class CustomHttpServletResponse extends HttpServletResponseWrapper {

        private ServletOutputStream outputStream;
        private PrintWriter printWriter;

        public CustomHttpServletResponse(HttpServletResponse response) throws UnsupportedEncodingException {
            super(response);

            this.outputStream = new CustomServletOutPutStream();
            this.printWriter = new PrintWriter(new OutputStreamWriter(outputStream, ENCODE));

        }

        @Override
        public ServletOutputStream getOutputStream() {
            return this.outputStream;
        }

        @Override
        public PrintWriter getWriter() throws IOException {
            return this.printWriter;
        }
    }

}

and you can call it like

    @Autowired
    InternalRenderer internalRenderer;

    @RequestMapping(value = "/internalRender")
    public void internalRender(HttpServletRequest request, HttpServletResponse response, Model model, Locale locale) throws Exception {

        String evalView = internalRenderer.evalView(request, response, model, locale, "index");

        logger.debug("evalView: " + evalView);

        //TODO: use the generated code to create the pdf and return it

    }

old response:

You could call /doSomething, getting back the generated html and pass it to another controller as a parameter to make it create the pdf and get it back as a final result (if it is strictly necessary generate the pdf from the html, maybe it's better to generate the pdf using the raw data)

  1. call /doSomething (using ajax?)

  2. get the generated html back

  3. call /createPdf passing the generated html as a paramter

  4. get the generated pdf back

Sign up to request clarification or add additional context in comments.

4 Comments

You could also make a call to the server in loopback using an http client, getting back the html, generate the pdf and returns the pdf directly, only one call, a very clean approach :D
i agree this is work around i tried and it is working well, but actually it is internal call i was looking for some thing i don't have to make httpclient or multiple ajax calls.
I appreciate you put efforts to write this code, but if you wants to use wrapper it is so wassy using this ways javascriptdownload.net/site/page.asp?dsy_id=468
So, the logic is the same but the work should be done inside a custom filter?.
-1

I found a simpler way

1 just add dependency

testCompile group: 'org.springframework', name: 'spring-mock', version: '2.0.8'

2 and then use

View resolvedView = this.viewResolver.resolveViewName("viewname", locale);
MockHttpServletResponse mockResp = new MockHttpServletResponse();
resolvedView.render(model, request, mockResp);
System.out.println("rendered html : " + mockResp.getContentAsString());

1 Comment

Your solution only works for unit tests (the testCompile group), and the OP indicated this is for runtime.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.