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)
call /doSomething (using ajax?)
get the generated html back
call /createPdf passing the generated html as a paramter
get the generated pdf back