测试
jsp代码:
<form action="${pageContext.request.contextPath}/Servlet1" method="post"> <input type="hidden" name="username" value="<h1>你好i好<h1>"> <input type="submit" value="提交"> </form>
Servlet代码:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String value = request.getParameter("username"); response.getWriter().write(value); }
缓存数据到内存中
在前面我们已经做过了,让浏览器不缓存数据【验证码的图片是不应该缓存的】。
现在我们要做的是:缓存数据到内存中【如果某个资源重复使用,不轻易变化,应该缓存到内存中】
这个和压缩数据的Filter非常类似的,因为让数据不直接输出给浏览器,把数据用一个容器(ByteArrayOutputSteam)存起来。如果已经有缓存了,就取缓存的。没有缓存就执行目标资源!
增强response对象
class MyResponse extends HttpServletResponseWrapper { private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); private PrintWriter printWriter ; private HttpServletResponse response; public MyResponse(HttpServletResponse response) { super(response); this.response = response; } @Override public ServletOutputStream getOutputStream() throws IOException { //这个的ServletOutputSteam对象调用write()方法的时候,把数据是写在byteArrayOutputSteam上的 return new MyServletOutputStream(byteArrayOutputStream); } @Override public PrintWriter getWriter() throws IOException { printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, this.response.getCharacterEncoding())); return printWriter; } public byte[] getBuffer() { try { //防止数据在缓存中,要刷新一下! if (printWriter != null) { printWriter.close(); } if (byteArrayOutputStream != null) { byteArrayOutputStream.flush(); return byteArrayOutputStream.toByteArray(); } } catch (IOException e) { e.printStackTrace(); } return null; } } //增强ServletOutputSteam,让writer方法不把数据直接返回给浏览器 class MyServletOutputStream extends ServletOutputStream { private ByteArrayOutputStream byteArrayOutputStream; public MyServletOutputStream(ByteArrayOutputStream byteArrayOutputStream) { this.byteArrayOutputStream = byteArrayOutputStream; } //当调用write()方法的时候,其实是把数据写byteArrayOutputSteam上 @Override public void write(int b) throws IOException { this.byteArrayOutputStream.write(b); } }
过滤器
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //定义一个Map集合,key为页面的地址,value为内存的缓存 Map<String, byte[]> map = new HashMap<>(); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; //得到客户端想要请求的资源 String uri = request.getRequestURI(); byte[] bytes = map.get(uri); //如果有缓存,直接返回给浏览器就行了,就不用执行目标资源了 if (bytes != null) { response.getOutputStream().write(bytes); return ; } //如果没有缓存,就让目标执行 MyResponse myResponse = new MyResponse(response); chain.doFilter(request, myResponse); //得到目标资源想要发送给浏览器的数据 byte[] b = myResponse.getBuffer(); //把数据存到集合中 map.put(uri, b); //把数据返回给浏览器 response.getOutputStream().write(b); }
测试
尽管是刷新,获取得到的也是从缓存拿到的数据!