jsp解决高并发,其中一个方法就是生成静态页面,这样可以减少访问数据库次数,也可以省去后台处理逻辑。
那么实现生成静态页面的技术已经相当成熟了,向velocity,freemarks架构都已经包装好了。
但是在结合各种奇奇怪怪的架构中,还是在自己实现的代码复用最好,所以,接下来简单解析生成页面部分代码,
在这个生成静态页面代码中,URL的重定向,就是将URL改为约定好的html页面地址,这个步骤就是拼拼接接字符串,放在
requestDispatcher中,或是说requestDispatcher指向html页面资源
那么下面是关键生成讲台页面的代码,不管是哪个版本的,都会有如下代码:
{
final ByteArrayOutputStream os = new ByteArrayOutputStream();
final ServletOutputStream stream = new ServletOutputStream() {
public void write(byte[] data,int offset, int length) {
os.write(data, offset, length);
}
public void write(int b) throws IOException {
os.write(b);
}
};
final PrintWriter pw = new PrintWriter(new OutputStreamWriter(os, encoding));
HttpServletResponse rep = new HttpServletResponseWrapper(response) {
public ServletOutputStream getOutputStream() {
return stream;
}
public PrintWriter getWriter() {
return pw;
}
};
logger.debug("HtmlCreatorServlet RequestDispatcher = " + templatePath);
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(templatePath);
dispatcher.include(request, rep);
pw.flush();
FileOutputStream fos = null;
try {
if(os.size() == 0) {
response.sendError(HttpServletResponse.SC_NOT_FOUND, "");
}
else {
fos = new FileOutputStream(cachhtmlFileName);
os.writeTo(fos);
dispatcher = getServletContext(). getRequestDispatcher("/"+htmlName);
dispatcher.include(request, response);
}
} finally {
if(fos != null) {
fos.close();
}
}
}
其目的就是从response中将目标资源jsp写入到静态页面html中,其中关键语句为
HttpServletResponse rep = new HttpServletResponseWrapper(response) {
public ServletOutputStream getOutputStream() {
return stream;
}
public PrintWriter getWriter() {
return pw;
}
他将输出流的方向改变了,将response中的内容转到打印流pw中,pw在写入到数组字节流os中,os就可以写到文件指定的html文件中了,可喜可贺可喜可贺。那么都是在哪句代码中实现的呢,在这句活
dispatcher.include(request, rep);
disparcher的include,玩过jsp都知道,是将目标资源处理结果包括在当前资源中,呈现给用户,可是response被rep重现包装后,前段已经说过,将输出流改变了方向。
以此实现了生成静态页面。