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重现包装后,前段已经说过,将输出流改变了方向。
以此实现了生成静态页面。