这篇文章源码转载自☞http://www.cnblogs.com/xiaochangwei/p/5025790.html
我做了更详细的介绍。。。。。。。
我觉得这篇文章应该是介绍jsp页面静态化的最详细的文章了(尽管我可能没找到更详细的),但是我还是花了很长的时间来理解这里面调用的类和方法之类的,
并且记录了下来,现记录如下:
这是articleTemplate.jsp,测试用的jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文章标题——${id}</title>
</head>
<body>现在时间是${time},你访问的文章id为${id}
</body>
</html>
这是 JspStatic servlet,用于出来前台的url链接的请求
package Test;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class JspStatic extends HttpServlet {
private static final long serialVersionUID = 1L;
public JspStatic() {
super();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (request.getParameter("id") != null) {
String fileName = "article_" + request.getParameter("id") + ".html";
//getServletContext().getRealPath("/")获取的是
//D:\mkeclipse\workplace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\mkk\article_100.html
//这里需要/mkk/下有这个文件夹,没有的话报错(系统找不到指定路径)
String filePath = getServletContext().getRealPath("/articles/")+ fileName;
System.out.println(filePath);
File chapterFile = new File(filePath);
if (chapterFile.exists()) {
// System.out.println("html页面存在,直接跳转");
response.sendRedirect(fileName);
return;
}
// System.out.println("新生成html页面");
//TODO 这里可调用service查询页面上需要的数据,然后封装到request里面
request.setAttribute("time", new java.util.Date());
request.setAttribute("id", request.getParameter("id"));
new CreateStaticHTMLPage().create(request, response, getServletContext(), fileName, filePath,
"/articleTemplate.jsp");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
这里是CreateStaticHTMLPage()类,用于创建一个静态页面的具体步骤
package Test; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; /** * 创建HTML静态页面 * * @author xiaochangwei * */ public class CreateStaticHTMLPage { /** * 生成静态HTML页面的方法 * * @param request * 请求对象 * @param response * 响应对象 * @param servletContext * Servlet上下文 * @param fileName * 文件名称 * @param fileFullPath * 文件完整路径 * @param jspPath * 需要生成静态文件的JSP路径(相对即可) * @throws IOException * @throws ServletException */ HttpServlet da= new HttpServlet() { }; public void create(HttpServletRequest request, HttpServletResponse response, ServletContext servletContext, String fileName, String fileFullPath, String jspPath) throws ServletException, IOException { response.setContentType("text/html;charset=gb2312");// 设置HTML结果流编码(即HTML文件编码) /* * 这里用到javax.*;这里的类,所以把源文件引进来,然后自己看 * 本tomcat是9.0M10,所以下载该版本的src_zip包。 * 地址:http://archive.apache.org/dist/tomcat/tomcat-9/ * 引入源码步骤:自己百度 * */ RequestDispatcher rd = servletContext.getRequestDispatcher(jspPath);// 得到JSP资源 /* * ByteArrayOutputStream 中的数据被写入一个字节数组 * 方法:write(byte[] b):把b字节数组中的内容写到该ByteArrayOutPutStream中,该类中有一个byte buf[]; * 用于缓存读进来的b(其实就是复制一份)【源码分析】http://wangkuiwu.github.io/2012/05/03/ByteArrayOutputStream/ * 获取byte[]方法:byte[] toByteArray():调用这个方法就可以获取一份经过Arrays.copyOf(buf, count);复制过的字节数组了。 */ final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();// 用于从ServletOutputStream中接收资源 final ServletOutputStream servletOuputStream = new ServletOutputStream() {// 用于从HttpServletResponse中接收资源 public void write(byte[] b, int off, int len) { byteArrayOutputStream.write(b, off, len); } public void write(int b) { byteArrayOutputStream.write(b); } @Override public boolean isReady() { // TODO Auto-generated method stub return false; } @Override public void setWriteListener(WriteListener arg0) { // TODO Auto-generated method stub } }; /* * OutputStreamWriter 是字节流到字符流的一个桥梁 * 用法: new BufferedWriter(new OutputStreamWriter(System.out));这里就会返回一个字符流的对象 */ /* * PrintWriter 将对象的格式表示打印到文本输出流。 * 构造函数: 1.PrintWriter(OutputStream out) * 2.PrintWriter(File file) * ...... * 用法: 1.print() 打印出内容 * 2.flush() 刷新流 * 3.write(char[] buf, int off, int len) 写一个字符数组的一部分。 */ final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream));// 把转换字节流转换成字符流 /* * * HttpServletResponseWrapper(HttpServletRequest req) 构造一个包装给定请求的请求对象 */ /* * 这里的response就是之前的response * 而这里的httpServletResponse已经具有了完整的信息的httpservletresponse了 * 并且 */ HttpServletResponse httpServletResponse = new HttpServletResponseWrapper(response) {// 用于从response获取结果流资源 /* * 这里重写了HttpServletResponseWrapper的父类ServletResponseWrapper的getOutputStream()和getWriter()方法 * getOutputStream()和getWriter()返回一个字节流和一个字符流都是向客户端发送响应 getOutputStream()可以发送二进制数据,getWriter()可以发送字符数据 */ public ServletOutputStream getOutputStream() { return servletOuputStream; } public PrintWriter getWriter() { return printWriter; } }; /*关于include的详细解释,请看这篇文章 http://www.jianshu.com/p/35d9e05d5989*/ rd.include(request, httpServletResponse);// 发送结果流、、 //向客户端发送response, printWriter.flush();// 刷新response中缓冲区,把缓冲区的数据输出,这样byteArrayOutputStream就获取了全部的数据 FileOutputStream fileOutputStream = new FileOutputStream(fileFullPath); /* 此时的bytearrayoutputstream已经具有了所有的jsp中servletoutputstream的内容*/ byteArrayOutputStream.writeTo(fileOutputStream);// 把byteArrayOuputStream中的资源全部写入到fileOuputStream中 fileOutputStream.close();// 关闭输出流,并释放相关资源 response.sendRedirect(fileName);// 发送指定文件流到客户端 } }