页面静态化是把动态页面生成的html保存到服务器的文件上,然后再有相同请求时,不再去执行动态页面,而是直接给用户响应上次已经生成的静态页面。
例子
实体类book
public class Book { private String bid;//id private String bname;//书名 private double price;//单价 private int category;//所属分类 public String getBid() { return bid; } public void setBid(String bid) { this.bid = bid; } public String getBname() { return bname; } public void setBname(String bname) { this.bname = bname; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public int getCategory() { return category; } public void setCategory(int category) { this.category = category; } @Override public String toString() { return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + ", category=" + category + "]"; } } |
BookServlet
public class BookServlet extends BaseServlet { private BookDao bookDao = new BookDao(); public String findByCategory(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 获取分类 * 2. 通过分类查询图书 * 3. 把图书保存到request中 * 4. 转发到show.jsp */ int category = Integer.parseInt(request.getParameter("category")); List<Book> bookList = bookDao.findByCategory(category); request.setAttribute("bookList", bookList); return "/show.jsp"; } public String findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /* * 1. 查询所有图书 * 2. 存放到request中 * 3. 转发到show.jsp */ request.setAttribute("bookList", bookDao.findAll()); return "/show.jsp"; } } |
staticFilter
import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class StaticFilter implements Filter { private ServletContext cxt; public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; /* * 1. 获取category参数,可能是null、1、2、3 * 2. 通过参数来查找对应的静态页面,如果存在这个静态页面,直接重定向! * 3. 如果不存在静态页面,创建自己的response,然后调包放行! * 4. 保存静态页面与参数的关系 * 5. 重定向到静态页面 */ String s = req.getParameter("category");//获取参数 String key = "key_" + s;// key_null、key_1、key_2、key_3 // 获取参数与静态页面的Map,Map中key是参数,值是静态页面名称 Map<String,String> staticPages = (Map<String, String>) cxt.getAttribute("static_pages"); if(staticPages == null) {//首次访问Map不存在,我们创建Map。 staticPages = new HashMap<String,String>(); cxt.setAttribute("static_pages", staticPages);//把Map存放到cxt中 } // 查看是否存在这个对应的静态页面 String fileName = staticPages.get(key);//获取静态页面的路径! if(fileName != null) {//如果对应的静态页面存在,重定向!结束!!! res.sendRedirect(req.getContextPath() + "/static/" + fileName); return;//不在向后走了。 } // 如果参数没有对应的静态页面,说明是第一次访问这个参数。 // 生成真实的html文件路径 String path = cxt.getRealPath("/static/" + key + ".html"); // 创建山寨版的response StaticResponse sr = new StaticResponse(res, path); // 调包放行 chain.doFilter(request, sr);//jsp会使用我们提供的流,玩命输出!最终数据都写入到文件中了。 sr.close();//关闭流,会使数据刷新到文件中。 // 保存静态页面与参数的关系到map中 staticPages.put(key, key + ".html"); res.sendRedirect(req.getContextPath() + "/static/" + key + ".html");//重定向到刚刚生成的静态页面上 } public void init(FilterConfig fConfig) throws ServletException { cxt = fConfig.getServletContext(); } } |
staticRespose
import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class StaticResponse extends HttpServletResponseWrapper { private PrintWriter out; /* * fileName:创建本类对象时,需要提供静态页面的路径! */ public StaticResponse(HttpServletResponse response, String fileName) throws FileNotFoundException, UnsupportedEncodingException { super(response); out = new PrintWriter(fileName, "UTF-8"); } @Override public PrintWriter getWriter() throws IOException { return out; } // 调用这个方法会关闭这个流,关闭流之前会刷新流! public void close() { out.close(); } } |
<body> <a href="<c:url value='/BookServlet?method=findAll'/>">全部图书</a><br/> <a href="<c:url value='/BookServlet?method=findByCategory&category=1'/>">JavaSE分类</a><br/> <a href="<c:url value='/BookServlet?method=findByCategory&category=2'/>">JavaEE分类</a><br/> <a href="<c:url value='/BookServlet?method=findByCategory&category=3'/>">Java框架分类</a><br/> </body> |
<table border="1" align="center" width="50%"> <tr> <th>图书名称</th> <th>图书单价</th> <th>图书分类</th> </tr> <c:forEach items="${bookList }" var="book"> <tr> <td>${book.bname }</td> <td>${book.price }</td> <td> <c:choose> <c:when test="${book.category eq 1}"><p style="color:red;">JavaSE分类</p></c:when> <c:when test="${book.category eq 2}"><p style="color:blue;">JavaEE分类</p></c:when> <c:when test="${book.category eq 3}"><p style="color:green;">Java框架分类</p></c:when> </c:choose> </td> </tr> </c:forEach> </table> </body> |