项目上用的这个过滤器,主要流程是。前端请求所带的参数是全部加密的。我用过滤器截获到请求携带的数据,解密,放行
理论上请求request是不能被修改的。可以继承HttpServletRequestWrapper,重写父类方法,来实现。
启动类
@SpringBootApplication
@ServletComponentScan(basePackages = "com.example.demo")
@ComponentScan(basePackages = {"com.example.demo"})
public class DemoLiumApplication {
public static void main(String[] args) {
SpringApplication.run(DemoLiumApplication.class, args);
}
}
过滤器
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.codec.Charsets;
import org.springframework.core.annotation.Order;
import org.springframework.util.ReflectionUtils;
import com.example.demo.lium.utils.DataUtil;
@Order(1)
@WebFilter(filterName = "DecodeFilter",urlPatterns = "/*")
public class DecodeFilter implements Filter{
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
System.out.println("第一过滤器开始");
//拦截到请求
HttpServletRequest request =(HttpServletRequest) req;
RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(request);
Map extraParams1=new HashMap();
extraParams1.put("other", "othervalue");
requestParameterWrapper.addParameters(extraParams1);
System.out.println("请求ContentType"+request.getContentType());
System.out.println("请求"+request.getMethod());
//获得请求参数
Map requestMap=DataUtil.getRequestMap(request);
for (String key:requestMap.keySet()) {
String value;
if (key.indexOf("name")!=-1) {
value=requestMap.get(key);
//TODO
String strAdd=value+":刘宁宁添加的后缀";
System.out.println("key是"+key);
System.out.println("value是"+value);
// request.setAttribute("name", strAdd);
Map extraParams=new HashMap();
extraParams.put(key, strAdd);
requestParameterWrapper.addParameters(extraParams);
}if (key.indexOf("password")!=-1) {
value=requestMap.get(key);
//TODO
String strAdd=value+":刘宁宁添加mima的后缀";
System.out.println("key是"+key);
System.out.println("value是"+value);
// request.setAttribute("password", strAdd);
Map extraParams=new HashMap();
extraParams.put(key, strAdd);
requestParameterWrapper.addParameters(extraParams);
}
}
//获取response内容,未成功
String ResponseStr=outResponse(resp);
//TODO
System.out.println("拦截到的回"+ResponseStr);
//放行
chain.doFilter(requestParameterWrapper, resp);
// chain.doFilter(new TokenRequestWrapper((HttpServletRequest) req), resp);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
Filter.super.destroy();
}
/**获取response的内容,没有成功
* @param resp
* @return
*/
private String outResponse(ServletResponse resp) {
String out=null;
try {
ServletOutputStream os = resp.getOutputStream();
Field ob= ReflectionUtils.findField(os.getClass(),"ob");
ob.setAccessible(true);
Object obValue= ReflectionUtils.getField(ob,os);
Field bb= ReflectionUtils.findField(obValue.getClass(),"bb");
bb.setAccessible(true);
Object bbValue= ReflectionUtils.getField(bb,obValue);
Field hb= ReflectionUtils.findField(bbValue.getClass(),"hb");
hb.setAccessible(true);
Object value= ReflectionUtils.getField(hb,bbValue);
out= null==value?null:new String((byte[])value, Charsets.UTF_8);
}catch (Exception e){
out=null;
// out="ERROR:"+e.getMessage();
}
return out;
}
}
重写父类方法
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class RequestParameterWrapper extends HttpServletRequestWrapper {
private Map params = new HashMap();
public RequestParameterWrapper(HttpServletRequest request) {
super(request);
//将现有parameter传递给params
this.params.putAll(request.getParameterMap());
}
/**
* 重载构造函数
* @param request
* @param extraParams
*/
public RequestParameterWrapper(HttpServletRequest request, Map extraParams) {
this(request);
addParameters(extraParams);
}
public void addParameters(Map extraParams) {
for (Map.Entry entry : extraParams.entrySet()) {
addParameter(entry.getKey(), entry.getValue());
}
}
/* 重写父类方法
* 自定义参数
*/
public Enumeration getParameterNames() {
Set set=params.keySet();
if (set.size()>0&set!=null){
return Collections.enumeration(set);
}else {
return super.getParameterNames();
}
}
/**
* 重写getParameter,代表参数从当前类中的map获取
* @param name
* @return
*/
@Override
public String getParameter(String name) {
String[]values = params.get(name);
if(values == null || values.length == 0) {
return null;
}
return values[0];
}
/**
* 同上
* @param name
* @return
*/
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
/**
* 添加参数
* @param name
* @param value
*/
public void addParameter(String name, Object value) {
if (value != null) {
System.out.println(value);
if (value instanceof String[]) {
params.put(name, (String[]) value);
} else if (value instanceof String) {
params.put(name, new String[]{(String) value});
} else {
params.put(name, new String[]{String.valueOf(value)});
}
}
}
}
controller
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DecodeController {
@RequestMapping("/reqTest")
public String reqTest(@RequestParam("name")String name,@RequestParam("password") String password) {
String str="名字是:"+name+"密码是:"+password;
System.out.println(str);
return str;
}
}
工具类
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
public class DataUtil {
public static Map getRequestMap(HttpServletRequest request){
Enumeration enumRequst=request.getParameterNames();
Map requestMap = new HashMap();
while(enumRequst.hasMoreElements()){
String key = enumRequst.nextElement();
String values[]=request.getParameterValues(key);
for(String val:values){
requestMap.put(key, val);
}
}
return requestMap;
}
}
于是我又写了一个过滤器去过滤第一个过滤器。打印请求参数,发现请求参数已经修改成功。
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import org.springframework.core.annotation.Order;
import com.example.demo.lium.utils.DataUtil;
@Order(2)
@WebFilter(filterName = "DecodeFilterTwo",urlPatterns = "/*")
public class DecodeFilterTwo implements Filter{
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request =(HttpServletRequest) req;
String url=request.getRequestURI();
System.out.println("第二过滤器开始");
System.out.println("TWOurl"+url);
System.out.println("TWO请求ContentType"+request.getContentType());
System.out.println("TWO请求"+request.getMethod());
//获得请求参数
Map requestMap=DataUtil.getRequestMap(request);
for (String key:requestMap.keySet()) {
String value=requestMap.get(key);
System.out.println("keyTWO:"+key);
System.out.println("valueTWO:"+value);
}
chain.doFilter(request, resp);
}
}
我试了一下 http://127.0.0.1:8080/reqTest?name=liunn&password=123456
返回的数据表示,修改成功了
然后对返回到前端的数据修改
修改过滤器
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.Charsets;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.util.ReflectionUtils;
import com.example.demo.lium.utils.DataUtil;
import io.micrometer.core.instrument.util.StringUtils;
/**过滤器,对请求参数解密,对返回参数加密
*
* @author liunn
*
*/
@Order(1)
@WebFilter(filterName = "DecodeFilter",urlPatterns = "/*")
public class DecodeFilter implements Filter{
/* 执行过滤器的方法
*
*/
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
//转换请求
HttpServletRequest request =(HttpServletRequest) req;
//自定义请求参数,转换成代理类
RequestParameterWrapper requestParameterWrapper = new RequestParameterWrapper(request);
//转换返回
HttpServletResponse response =(HttpServletResponse) resp;
//自定义返回参数,转换成代理类
ResponseWrapper responseWrapper = new ResponseWrapper(response);
// ResponesParameterWrapper responseWrapper = new ResponesParameterWrapper(response);
//自定义参数,测试.在这里添加额外的请求参数
Map extraParams1=new HashMap();
extraParams1.put("other", "othervalue");
requestParameterWrapper.addParameters(extraParams1);
//获得前端请求参数
Map requestMap=DataUtil.getRequestMap(request);
//循环取出,对每个参数做修改,其实就是解密。
for (String key:requestMap.keySet()) {
String value;
if (key.indexOf("name")!=-1) {
value=requestMap.get(key);
//TODO,对value解密.这里,我对修改了字符串内容
String strAdd=value+":刘宁宁添加的后缀";
Map extraParams=new HashMap();
extraParams.put(key, strAdd);
//修改好的参数放到自定义请求里面
requestParameterWrapper.addParameters(extraParams);
}if (key.indexOf("password")!=-1) {
value=requestMap.get(key);
//TODO,对value解密.这里,我对修改了字符串内容
String strAdd=value+":刘宁宁添加mima的后缀";
Map extraParams=new HashMap();
extraParams.put(key, strAdd);
//修改好的参数放到自定义请求里面
requestParameterWrapper.addParameters(extraParams);
}
}
//放行
chain.doFilter(requestParameterWrapper, responseWrapper);
/**
* 返回值
*
*/
byte[] content = responseWrapper.getContent();//获取返回值
//判断是否有值
if (content.length > 0)
{
String str = new String(content, "UTF-8");
System.out.println("返回值:" + str);
String textliunn = null;
String str1 =null;
try
{
//TODO 根据需要处理返回值
// Long date=System.currentTimeMillis();
textliunn="我在后端返回前端数据,这是我修改后端的数据----------";
str1="—修改好的数据:"+str;
}
catch (Exception e)
{
e.printStackTrace();
}
//把返回值输出到客户端
resp.getWriter().write(str1);
/**
//显示返回到前端的数据不全,我换成字符流了
ServletOutputStream out = response.getOutputStream();
out.write(textliunn.getBytes());
out.write(str1.getBytes());
out.flush();
out.close();
*/
}
}
//TODO
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
Filter.super.init(filterConfig);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
Filter.super.destroy();
}
}
重写父类HttpServletResponseWrapper
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class ResponseWrapper extends HttpServletResponseWrapper
{
private ByteArrayOutputStream buffer;
private ServletOutputStream out;
public ResponseWrapper(HttpServletResponse httpServletResponse)
{
super(httpServletResponse);
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
}
}
}
然后就可以在前端看到修改后的数据