1、先利用HttpServletRequestWrapper定义我们自己的request装饰器
package com.community.wisdom.config;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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;
class MultiReadHttpServletRequestWrapper extends HttpServletRequestWrapper {
public Log log = LogFactory.getLog(MultiReadHttpServletRequestWrapper.class);
private String tempBody;
public MultiReadHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
tempBody = getBodyString(request);
}
@Override
public ServletInputStream getInputStream() {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(tempBody.getBytes(Charset.forName("UTF-8")));
return new ServletInputStream() {
@Override
public boolean isReady() {
return false;
}
@Override
public int readLine(byte[] b, int off, int len) throws IOException {
return super.readLine(b, off, len);
}
@Override
public boolean isFinished() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() {
return byteArrayInputStream.read();
}
};
}
@Override
public BufferedReader getReader() {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
public String getBody() {
return this.tempBody;
}
public void setBody(String body) {
this.tempBody = body;
}
/**
* 获取请求Body
*
* @param request request
* @return String
*/
public String getBodyString(final ServletRequest request) {
try {
return inputStream2String(request.getInputStream());
} catch (IOException e) {
log.error("", e);
throw new RuntimeException(e);
}
}
/**
* 将inputStream里的数据读取出来并转换成字符串
*
* @param inputStream inputStream
* @return String
*/
private String inputStream2String(InputStream inputStream) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
log.error("", e);
throw new RuntimeException(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
log.error("", e);
}
}
}
return sb.toString();
}
}
2、在利用HttpServletResponseWrapper定义response修饰器
package com.community.wisdom.config;
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;
public class MultiReadHttpServletResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer;
private ServletOutputStream out;
/**
* Constructs a response adaptor wrapping the given response.
*
* @param response The response to be wrapped
* @throws IllegalArgumentException if the response is null
*/
public MultiReadHttpServletResponseWrapper(HttpServletResponse response) {
super(response);
buffer = new ByteArrayOutputStream();
out = new WrapperOutputStream(buffer);
}
@Override
public ServletOutputStream getOutputStream()
throws IOException
{
return out;
}
@Override
public void flushBuffer()
throws IOException
{
if (out != null)
{
out.flush();
}
}
public byte[] getContent()
throws IOException
{
flushBuffer();
return buffer.toByteArray();
}
class WrapperOutputStream extends ServletOutputStream
{
private ByteArrayOutputStream bos;
public WrapperOutputStream(ByteArrayOutputStream bos)
{
this.bos = bos;
}
@Override
public void write(int b)
throws IOException
{
bos.write(b);
}
@Override
public boolean isReady()
{
// TODO Auto-generated method stub
return false;
}
@Override
public void setWriteListener(WriteListener arg0)
{
// TODO Auto-generated method stub
}
}
}
3、通过实现Filter接口定义过滤器
package com.community.wisdom.config;
import com.alibaba.fastjson.JSONObject;
import com.community.core.util.AesCBCUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
public class RequestWrapperFilter implements Filter{
public Log log = LogFactory.getLog(RequestWrapperFilter.class);
private final String BODY_KEY = "Body";
//不过滤集合
private List<String> excludedUris;
@Override
public void init(FilterConfig config) {
String param = config.getInitParameter("excludedUris");
if (StringUtils.isNotBlank(param)) {
this.excludedUris = Arrays.asList(param.split(","));
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
ServletOutputStream out = null;
//响应json默认失败json字符串
/**1、定义表示变量 并验证用户请求URI 是否包含不过滤路径 */
boolean flag = false;
if (null != excludedUris && !excludedUris.isEmpty() && excludedUris.contains(((HttpServletRequest) request).getRequestURI())){
flag = true;
}
MultiReadHttpServletRequestWrapper requestWrapper = new MultiReadHttpServletRequestWrapper((HttpServletRequest) request);
MultiReadHttpServletResponseWrapper wrapperResponse = new MultiReadHttpServletResponseWrapper((HttpServletResponse)response);//转换成代理类
try{
/**2、判断是否需要过滤处理 */
if(!flag && requestWrapper != null && wrapperResponse != null) {
/** 3、 装饰请求解密请求主体 start **/
String body = requestWrapper.getBody(); //获取body
/*修改逻辑*/
requestWrapper.setBody(body ); //修改body
/** 装饰请求解密请求主体 end **/
chain.doFilter(requestWrapper, wrapperResponse); // 请求资源
/** 4、装饰响应修改主体 start **/
byte[] content = wrapperResponse.getContent();//获取返回值
//判断是否有值
if (content.length > 0){
String resStr = new String(content, "UTF-8"); // 获取响应主体
/*修改逻辑*/
out = response.getOutputStream(); // 修改响应主体
out.write(resStr .getBytes("UTF-8"));
out.flush();
out.close();
}
/** 装饰响应修改主体 end **/
} else{ //不需要过滤处理
chain.doFilter(request, response); // 请求资源
}
}catch (Exception e){
try {
out.flush();
out.close();
}catch (Exception ex){
log.error("IOException:",ex);
}
}
}
@Override
public void destroy() {
}
}
3、定义过滤器bean并注入spring
@Bean
public FilterRegistrationBean addRequestWrapperFilter() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new RequestWrapperFilter());
registration.setName("RequestWrapperFilter");
registration.addUrlPatterns("/app/*");
//不进行过滤指定路径
registration.addInitParameter("excludedUris","/app/login,/app/test/");
registration.setOrder(1);
return registration;
}
用过滤器实现对request和response切面处理的效果