过滤器使用案例:
package Filter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: lvyk
* @Description: 过滤器
* @Date: 2020/5/26 16:29
*/
@Component//http://10.7.213.151:9007/test/api/v1/mytest
@WebFilter(filterName = "myFilter",urlPatterns = "/api/v1/*",/*通配符(*)表示对所有的web资源进行拦截*/
initParams = {@WebInitParam(name = "charset", value = "utf-8")/*这里可以放一些初始化的参数*/})
@Slf4j
public class MyFilter implements Filter {
private String filterName;
@Autowired
private FilterUtil filterUtil;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
filterName = filterConfig.getFilterName();
log.info("过滤器初始化方法,过滤器名:"+filterName);
//初始化方法
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws IOException, ServletException {
//过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理
log.info(filterName+":执行过滤方法开始====");
// 防止流读取一次后就没有了, 所以需要将流继续写出去
HttpServletRequest httpServletRequest = (HttpServletRequest) req;
//获取请求报文
String requestBody = filterUtil.getRequestBody(httpServletRequest);
//对请求报文做解密处理
String decryptBASE64="";
try {
decryptBASE64 = new String(filterUtil.decryptBASE64(requestBody));
log.info("解密请求报文:"+decryptBASE64);
} catch (Exception e) {
log.info("请求报文解密失败。");
e.printStackTrace();
}
Map<String, String> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("content-type","application/json");
RequestWrapper requestWrapper = new RequestWrapper(httpServletRequest, decryptBASE64);
String headerNames = requestWrapper.getHeader("content-type");
String httpServletRequestHeader = httpServletRequest.getHeader("content-type");
//设置请求头
requestWrapper.addHeader("content-type","application/json");
headerNames = requestWrapper.getHeader("content-type");
httpServletRequestHeader = httpServletRequest.getHeader("content-type");
//响应处理 包装响应对象 res 并缓存响应数据
ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) res);
//demo:对加密报文进行加密
/*String strDemo="加密测试";
try {
log.info("base64加密之前:"+strDemo);
String encryptBASE64 = encryptBASE64(strDemo.getBytes());
log.info("base64加密之后:"+encryptBASE64);
//将加密报文进行解密
String decryptBASE64 = new String(decryptBASE64(encryptBASE64));
log.info("base64解密之后:"+decryptBASE64);
} catch (Exception e) {
log.info("base64加解密失败");
e.printStackTrace();
}*/
//执行业务逻辑 交给下一个过滤器或servlet处理
filterChain.doFilter(requestWrapper, responseWrapper);
byte[] resData = responseWrapper.getResponseData();
//设置响应内容格式,防止解析响应内容时出错
responseWrapper.setContentType("text/plain;charset=UTF-8");
log.info("原始响应报文:\n"+ new String(resData));
//加密响应报文并响应
String encryptBASE64="";
try {
encryptBASE64 = filterUtil.encryptBASE64(resData);
} catch (Exception e) {
e.printStackTrace();
}
log.info("响应加密报文:"+encryptBASE64);
filterUtil.writeResponse(res, encryptBASE64);
log.info(filterName+":执行过滤方法结束====");
}
@Override
public void destroy() {
//销毁时调用
log.info(filterName+":服务停止之后过滤器销毁了");
}
}
请求包装类(由于拿到请求内容进行处理之后发现请求内容丢失了,所以这里进行包装处理):
package Filter;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
/**
* @Author: lvyk
* @Description: 请求包装类
* @Date: 2020/5/26 16:29
*/
@Slf4j
public class RequestWrapper extends HttpServletRequestWrapper {
private String requestBody = null;
//请求体
private HttpServletRequest req = null;
// private final byte[] body;//保存流的字节数组
private final Map<String, String> reqHeaders=new HashMap<>();
public RequestWrapper(HttpServletRequest request) throws IOException {
super(request);
this.req = request;
// this.reqHeaders = new HashMap<String, String>();
// String sessionStream = getRequestBodyStr(request);//读取流中的参数
// body = sessionStream.getBytes(Charset.forName("UTF-8"));
}
public RequestWrapper(HttpServletRequest request, String requestBody) {
super(request);
this.requestBody = requestBody;
this.req = request;
// this.reqHeaders = request.get;
}
/**
* @Author: lvyk
* @Description: 获取请求body
* @Date: 2020/5/26 10:31
* @Param: [request]
* @Return: java.lang.String
*/
public String getRequestBodyStr(final ServletRequest request) throws IOException {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
try {
inputStream = cloneInputStream(request.getInputStream());
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
inputStream.close();
}
if (reader != null) {
reader.close();
}
}
return sb.toString();
}
/**
* @Author: lvyk
* @Description: 复制输入流
* @Date: 2020/5/26 10:33
* @Param: [inputStream]
* @Return: java.io.InputStream
*/
public InputStream cloneInputStream(ServletInputStream inputStream) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > -1) {
byteArrayOutputStream.write(buffer, 0, len);
}
byteArrayOutputStream.flush();
InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
return byteArrayInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(getInputStream()));
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody.getBytes(req.getCharacterEncoding()));
return new ServletInputStream() {
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return bais.read();
}
};
}
/**
* 添加header的名称和值
*
* @param name
* @param value
*/
public void addHeader(String name, String value) {
reqHeaders.put(name, value);
}
@Override
public String getHeader(String name) {
// log.info("getHeader --->{}", name);
String headerValue = super.getHeader(name);
if (reqHeaders.containsKey(name)) {
headerValue = reqHeaders.get(name);
}
return headerValue;
}
/**
* 得到headers的名称
*/
@Override
public Enumeration<String> getHeaderNames() {
List<String> names = Collections.list(super.getHeaderNames());
for (String name : reqHeaders.keySet()) {
names.add(name);
}
return Collections.enumeration(names);
}
@Override
public Enumeration<String> getHeaders(String name) {
// log.info("getHeaders name --->>>>>>{}", name);
List<String> values = Collections.list(super.getHeaders(name));
// log.info("getHeaders value --->>>>>>{}", values);
if (reqHeaders.containsKey(name)) {
log.info("getHeaders --->{}", reqHeaders.get(name));
values = Arrays.asList(reqHeaders.get(name));
}
return Collections.enumeration(values);
}
}
响应包装类:
package Filter;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;
/**
* @Author: lvyk
* @Description: 响应包装类
* @Date: 2020/5/26 16:29
*/
public class ResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer = null;
private ServletOutputStream out = null;
private PrintWriter writer = null;
public ResponseWrapper(HttpServletResponse response) throws IOException {
super(response);
buffer = new ByteArrayOutputStream();// 真正存储数据的流
out = new WapperedOutputStream(buffer);
writer = new PrintWriter(new OutputStreamWriter(buffer,this.getCharacterEncoding()));
}
/** 重载父类获取outputstream的方法 */
@Override
public ServletOutputStream getOutputStream() throws IOException {
return out;
}
/** 重载父类获取writer的方法 */
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException {
return writer;
}
/** 重载父类获取flushBuffer的方法 */
@Override
public void flushBuffer() throws IOException {
if (out != null) {
out.flush();
}
if (writer != null) {
writer.flush();
}
}
@Override
public void reset() {
buffer.reset();
}
/** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */
public byte[] getResponseData() throws IOException {
flushBuffer();
return buffer.toByteArray();
}
/** 内部类,对ServletOutputStream进行包装 */
private class WapperedOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos = null;
public WapperedOutputStream(ByteArrayOutputStream stream)
throws IOException {
bos = stream;
}
@Override
public void write(int b) throws IOException {
bos.write(b);
}
@Override
public void write(byte[] b) throws IOException {
bos.write(b, 0, b.length);
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
}
}
公用Util方法:
package Filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @Author lvyk
* @Description: 供过滤器使用的工具类
* @Date 2020/5/27 14:05
* @Modify By:
*/
@Component
@Slf4j
public class FilterUtil {
/**
* BASE64加密
*/
public String encryptBASE64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
}
/**
* BASE64解密
*/
public byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}
/**
* @Author: lvyk
* @Description: 获取请求信息中请求报文
* @Date: 2020/5/27 14:08
* @Param: [req]
* @Return: java.lang.String
*/
public String getRequestBody(HttpServletRequest req) {
try {
BufferedReader reader = req.getReader();
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String json = sb.toString();
return json;
} catch (IOException e) {
log.error("验签时请求体读取失败", e);
}
return "";
}
/**
* @Author: lvyk
* @Description: 响应内容
* @Date: 2020/5/27 14:15
*/
public void writeResponse(ServletResponse response, String responseString) throws IOException {
PrintWriter out = response.getWriter();
out.print(responseString);
out.flush();
out.close();
}
}