Discuss / Java / 通过Filter修改响应

通过Filter修改响应

Topic source

净净一隅

#1 Created at ... [Delete] [Delete and Lock User]

package com.proxy;

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;

public class CachedHttpServletResponse extends HttpServletResponseWrapper {
private boolean open = false;
private ByteArrayOutputStream output = new ByteArrayOutputStream();
public CachedHttpServletResponse(HttpServletResponse response) {
super(response);
}

// 获取Writer:
public PrintWriter getWriter() throws IOException {
if (open) {
throw new IllegalStateException("Cannot re-open writer!");
}
open = true;
return new PrintWriter(output, false);
}

// 获取OutputStream:
public ServletOutputStream getOutputStream() throws IOException {
if (open) {
throw new IllegalStateException("Cannot re-open output stream!");
}
open = true;
return new ServletOutputStream() {
public boolean isReady() {
return true;
}

public void setWriteListener(WriteListener listener) {
}

// 实际写入ByteArrayOutputStream:
public void write(int b) throws IOException {
output.write(b);
}
};
}

// 返回写入的byte[]:
public byte[] getContent() {
return output.toByteArray();
}
}

package com.filter;

import com.proxy.CachedHttpServletResponse;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@WebFilter
public class CacheFilter implements Filter {
// Path到byte[]的缓存:
private Map<String, byte[]> cache = new ConcurrentHashMap<>();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// 获取Path:
String url = req.getRequestURI();
// 获取缓存内容:
byte[] data = this.cache.get(url);
resp.setHeader("X-Cache-Hit", data == null ? "No" : "Yes");
if (data == null) {
System.out.println("首次访问,从下游组件获取");
// 缓存未找到,构造一个伪造的Response:
CachedHttpServletResponse wrapper = new CachedHttpServletResponse(resp);
// 让下游组件写入数据到伪造的Response:
chain.doFilter(request, wrapper);
// 从伪造的Response中读取写入的内容并放入缓存:
data = wrapper.getContent();
cache.put(url, data);
}else{
System.out.println("从缓存中返回");
}
// 写入到原始的Response:
ServletOutputStream output = resp.getOutputStream();
output.write(data);
output.flush();
}
}

package com.controller;

import com.framework.ModelAndView;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpSession;

public class HelloController {
@GetMapping("/hello")
public ModelAndView index() throws InterruptedException {
Thread.sleep(3000);
ModelAndView mv=new ModelAndView("/hello.html");
return mv;
}
}

<!DOCTYPE html\>

<html lang\="en"\> <head> <meta charset\="UTF-8"\> <title>首页</title> </head> <body> <h1>hello,this is a springMVC created by Me!的的</h1> </body> </html>


  • 1

Reply