编辑:
我最终写了这个bean(使用HtmlServlet*Response*Wrapper
:-)),我希望它对某人有用(感谢:Reading ServletOutputStream to String)
(viewResolver 是自动装配的,因此需要在 servlet 上下文中定义)
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;
}
}
}
你可以这样称呼它
@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
}
旧回应:
您可以调用/doSomething,取回生成的html并将其作为参数传递给另一个控制器,以使其创建pdf并将其作为最终结果取回(如果绝对需要从html生成pdf,也许更好使用原始数据生成pdf)
调用 /doSomething(使用 ajax?)
取回生成的 html
调用 /createPdf 将生成的 html 作为参数传递
取回生成的 pdf