通过filter过滤器对请求参数进行处理
遇见的问题:
前台把参数通过报文或者使用表单、ajax提交到后台,如果我们的请求参数是加密的,那么我们在controller里面的每一个方法里都需要进行解密处理。如果方法太多,那就太麻烦了。
设计方案:
在一个Filter中将 HttpServletRequest 里的所有参数都取出来分别进行过滤然后再放回到该HttpServletRequest 中行不行呢?通过测试后发现是不行的,因为HttpServletRequest 只提供了getParameter ,而没有提供setParameter;所以,我们只能自己写一个HttpServletRequest 方法继承HttpServletRequestWrapper,然后覆盖里面的方法,并且增加我们自己的setParameters方法,这样我们就可以为所欲为了,最后再在filter中调用该类的方法对参数进行处理(获取、修改、存储等等)。
解决方案:在请求参数到达controller之前,在filter里面进行解密;这样,通过简单的过滤器处理,把需要处理的请求都在过滤器里进行解密操作,这样就等于实现了自动化处理。
这里我们针对两种不同的请求方式进行讲解:1.普通的表单、ajax请求;2.json格式的报文请求。(三步搞定)
1.普通的表单、ajax请求;
第一步:新建一个类
这个类继承自HttpServletRequestWrapper
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/*** 重写 HttpServletRequestWrapper* 处理表单、ajax请求* @author zhaoheng**/
public class MyHttpServletRequestWrapper1 extends HttpServletRequestWrapper{ // 用于存储请求参数private Map<String , String[]> params = new HashMap<String, String[]>(); // 构造方法public MyHttpServletRequestWrapper1(HttpServletRequest request) throws IOException { super(request);// 把请求参数添加到我们自己的map当中this.params.putAll(request.getParameterMap()); } /*** 添加参数到map中* @param extraParams*/public void setParameterMap(Map<String, Object> extraParams) {for (Map.Entry<String, Object> entry : extraParams.entrySet()) {setParameter(entry.getKey(), entry.getValue());}}/*** 添加参数到map中* @param name * @param value*/public void setParameter(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)});}}}/*** 重写getParameter,代表参数从当前类中的map获取* @param name* @return*/@Overridepublic String getParameter(String name) {String[]values = params.get(name);if(values == null || values.length == 0) {return null;}return values[0];}/*** 重写getParameterValues方法,从当前类的 map中取值* @param name* @return*/@Overridepublic String[] getParameterValues(String name) {return params.get(name);}
}
通过建立这个类我们就能完成向request对象添加我们处理之后的参数了。
第二步:通过实现filter接口建一个过滤器
package com.zhh.filter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;import org.apache.log4j.Logger;import com.zhh.util.request.MyHttpServletRequestWrapper1;/*** 参数处理验过滤器(针对ajax、表单等请求) 1.获取请求参数; 2.对获取到的请求参数进行处理(解密、字符串替、请求参数分类截取等等); 3.把处理后的参数放回到请求列表里面* * @author zhaoheng**/
public class ValidatorFilter1 implements Filter {private static final Logger log = Logger.getLogger(ValidatorFilter1.class);/*** 需要过滤的地址*/private static List<String> urlList = Arrays.asList("/pastOrder/filterCsF");/*** 是否不需要过滤* * @param requestUrl* 请求的url* @return*/public boolean isPast(String requestUrl) {for (String url : urlList) {if (requestUrl.equals(url)) {return true;}}return false;}@Overridepublic void destroy() {}@SuppressWarnings("unchecked")@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {log.info("过滤器2执行开始");String url = ((HttpServletRequest) request).getRequestURI().substring(((HttpServletRequest)request).getContextPath().length());//通过地址对特定的请求进行处理,如果不需要可以不用,如果不用,就会对使用的请求进行过滤if (isPast(url)) {MyHttpServletRequestWrapper1 requestWrapper1 = new MyHttpServletRequestWrapper1((HttpServletRequest) request);// 1.获取需要处理的参数String email = requestWrapper1.getParameter("email");// 2.把处理后的参数放回去(这里是大小转小写处理)requestWrapper1.setParameter("email", email.toLowerCase());// 3.放行,把我们的requestWrapper1放到方法当中chain.doFilter(requestWrapper1, response);} else {chain.doFilter(request, response);}}@Overridepublic void init(FilterConfig arg0) throws ServletException {}
}
第三步:过滤器的配置
方法一、在web.xml文件里面进行简单的配置(一般项目)
把我们的过滤器在该文件中注册
<!-- 配置过滤器 --><filter> <filter-name>ValidatorFilter1</filter-name> <!-- 我们写的过滤的地址 --><filter-class>com.zhh.filter.ValidatorFilter1</filter-class> </filter> <filter-mapping> <filter-name>ValidatorFilter1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
方法二、springboot项目的配置
新建一个配置类,加上@Configuration注解,在方法头加上@Bean注解
@Configuration
public class WebFileterConfig {/*** 配置过滤器* order属性:控制过滤器加载顺序:数字越小,加载越早* @return*/@Beanpublic FilterRegistrationBean ValidatorFilterRegistration() {//新建过滤器注册类FilterRegistrationBean registration = new FilterRegistrationBean();// 添加我们写好的过滤器registration.setFilter( new ValidatorFilter1());// 设置过滤器的URL模式registration.addUrlPatterns("/*");registration.setOrder(Integer.MAX_VALUE-10);return registration;}
}
controller 接收参数代码:
/*** 过滤方法测试*/@RequestMapping("/filterCsF2")public void filterCs22(String email,String userName){System.out.println("处理后的参数:"+userName+" "+email);}
请求示例代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>请求demo</title>
</head><body><form id="userForm" action="#" method="post">username:<input type="text" id ="userName" name="userName" value="21088888"/><br/><br>email:<input type="text" id ="email" name="email" value="zhaoHENG@163.com"/><br/><br/>age:<input type="text" id ="age" name="age" value="18"/><br/><br/><input type="reset" value="重置"/> <input type="button" id ="sub" value="提交"></form></body><script src="jquery.min.js"></script>
<script type="text/javascript">$("#sub").click(function(){var userName = $("#userName").val(); var email = $("#email").val(); var age = $("#age").val(); $.ajax({type : "POST",url:'http://127.0.0.1:8080/merchant_wap/pastOrder/filterCsF2',dataType : "json",data : {"userName":userName,"age":age,"email":email},success : function(data) {alert("33");},error : function(data) {alert("cccc"+data.email);}});});
</script>
</html>
处理结果:
处理后的参数:21088888 zhaoheng@163.com
从结果可以看出,我们成功的通过过滤器对请求的email进行大写转小写处理
2.json格式的报文请求;
第一步:新建一个类
这个类继承自HttpServletRequestWrapper
package com.zhh.util.request;import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;import jodd.io.StreamUtil;/*** 重写 HttpServletRequestWrapper* 处理json报文请求* @author zhaoheng**/
public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper{ private byte[] body; //用于保存读取body中数据 public MyHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request);//读取请求的数据保存到本类当中body = StreamUtil.readBytes(request.getReader(), "UTF-8"); }//覆盖(重写)父类的方法@Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } //覆盖(重写)父类的方法@Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(body); return new ServletInputStream() { @Override public int read() throws IOException { return bais.read(); } }; }/*** 获取body中的数据* @return*/public byte[] getBody() {return body;}/*** 把处理后的参数放到body里面* @param body*/public void setBody(byte[] body) {this.body = body;}
}
通过建立这个类我们就能完成向request对象添加我们处理之后的参数了。
第二步:通过实现filter接口建一个过滤器
package com.zhh.filter;import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;import org.apache.log4j.Logger;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zhh.util.request.MyHttpServletRequestWrapper;/*** 参数校验过滤器(针对json报文请求) 1.获取请求参数; 2.对获取到的请求参数进行处理(解密、字符串替、请求参数分类截取等等); 3.把处理后的参数放回到请求列表里面* * @author zhaoheng**/
public class ValidatorFilter implements Filter {private static final Logger log = Logger.getLogger(ValidatorFilter.class);/*** 需要过滤的地址*/private static List<String> urlList = Arrays.asList("/pastOrder/filterCs");/*** 是否需要过滤* * @param requestUrl* 请求的url* @return*/public boolean isPast(String requestUrl) {for (String url : urlList) {if (requestUrl.equals(url)) {return true;}}return false;}@Overridepublic void destroy() {log.info("过滤器执行结束");}@SuppressWarnings("unchecked")@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {log.info("过滤器1执行开始");String url0 = ((HttpServletRequest) request).getRequestURI();String url1 = ((HttpServletRequest) request).getContextPath();System.out.println("完整地址:"+url0);System.out.println("返回当前页面所在的应用的名字:"+url1);System.out.println("返回当前页面所在的应用的名字长度:"+url1.length());// 获取请求地址String url = ((HttpServletRequest) request).getRequestURI().substring(((HttpServletRequest)request).getContextPath().length());System.out.println("截取后的地址:"+url);if (isPast(url)) {//处理json报文请求MyHttpServletRequestWrapper requestWrapper = new MyHttpServletRequestWrapper((HttpServletRequest) request);// 读取请求内容BufferedReader br;br = requestWrapper.getReader();String line = null;StringBuilder sb = new StringBuilder();while ((line = br.readLine()) != null) {sb.append(line);}// 将json字符串转换为json对象JSONObject jsonObject = JSONObject.parseObject(sb.toString());Map<String, Object> map = new HashMap<String, Object>();// 把json对象转换为Map集合map = JSON.toJavaObject(jsonObject, Map.class);for (Entry<String, Object> entry : map.entrySet()) {// 把邮箱地址转换为小写if (entry.getKey().equals("email")) {map.put(entry.getKey(), entry.getValue().toString().toLowerCase());}}// 把参数转换之后放到我们的body里面String json = JSON.toJSONString(map);requestWrapper.setBody(json.getBytes("UTF-8"));// 放行 chain.doFilter(requestWrapper, response);} else {chain.doFilter(request, response);}}@Overridepublic void init(FilterConfig arg0) throws ServletException {}}
第三步:
方法一、
在web.xml文件里面进行简单的配置
把我们的过滤器在该文件中注册
<!-- 配置过滤器 --><filter> <filter-name>ValidatorFilter</filter-name> <!-- 我们写的过滤的地址 --> <filter-class>com.zhh.filter.ValidatorFilter</filter-class> </filter> <filter-mapping> <filter-name>ValidatorFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
方法二、springboot项目的配置
新建一个配置类,加上@Configuration注解,在方法头加上@Bean注解
@Configuration
public class WebFileterConfig {/*** 配置过滤器* order属性:控制过滤器加载顺序:数字越小,加载越早* @return*/@Beanpublic FilterRegistrationBean ValidatorFilterRegistration() {//新建过滤器注册类FilterRegistrationBean registration = new FilterRegistrationBean();// 添加我们写好的过滤器registration.setFilter( new ValidatorFilter());// 设置过滤器的URL模式registration.addUrlPatterns("/*");registration.setOrder(Integer.MAX_VALUE-10);return registration;}
}
controller 接收参数代码:
/*** 过滤方法测试* @RequestBody User user 该注解用于接收json请求的参数* @return*/@ResponseBody@RequestMapping(value = "/filterCs")public User filterCs(@RequestBody User user){System.out.println(user.toString());return user;}
请求报文示例:
我这里使用的是postman工具进行json参数请求
{"email": "zhaoHENG@163.com","userName":"20181100","age":"18"
}
返回结果:
{"email": "zhaoheng@163.com","userName":"20181100","age":"18"
}
通过该过滤器,把email转换从小写成功。
通过以上操作,我们就成功的创建了一个过滤器。
通过filter过滤器对请求参数进行处理相关推荐
- Spring MVC在参数绑定前通过Filter过滤器改变请求参数的值
第一步,对request请求进行增强: /*** author: zhangxueliang* date: 2019-08-23*/ public class ParameterServletRequ ...
- vue+filter过滤器(多参数)传参 - 代码篇
vue+filter过滤器(多参数)传参 - 代码篇 传1个参数 //html {{a1 | filterAa}} //js filters:{filterAa(a1){// a1是传入的参数} } ...
- 使用过滤器(Filter)解决请求参数中文乱码问题(复杂方式)
前述: 在写这篇笔记之前,对笔记中的设计模式进行介绍: 本篇笔记中将要使用到的设计模式是:装饰(包装)设计模式 (1)装饰(包装)设计模式口诀: ①定义一个类,实现被装饰对象的接口 ②定义一个成员变量 ...
- SpringMVC表单请求参数的绑定,配置编码过滤器解决请求参数中文乱码问题,自定义类型转换器
文章目录 SpringMVC的参数绑定支持的数据类型 基本数据类型和字符串类型 JavaBean 包装类 Map类型 List类型 POST请求参数中文乱码的解决方法 自定义类型转换器(Date类 ...
- (29) JavaWeb中使用filter过滤器拦截请求、权限检查,过滤响应。
Filter 过滤器 一.Filter 什么是过滤器 二.Filter 过滤器的使用步骤: 三.Filter 的生命周期 四.FilterConfig 类 五.FilterChain 过滤器链 六.F ...
- 【SpringBoot】之自定义 Filter 过滤器
目录 一.Filter 介绍 二.Filter 的拦截过程 三.自定义 Filter 一.Filter 介绍 Filter 过滤器主要用来过滤用户的请求,允许用户对请求进行前置处理和后置处理,比如实现 ...
- 你真的了解Filter过滤器 ?
1.Filter 什么是过滤器 其中最重要的就是filter功能.它使用户可以改变一个request和修改一个response. Filter 不是一个servlet,它不能产生一个response, ...
- 前后端整合+Request(请求转发)+respon(重定向)+get+post+Filter过滤器
一.请求Request 是指 从前端浏览器 到 后端的Servlet程序 的访问过程,叫请求的过程 可以使用Servlet提供的Request对象,来解析请求中的请求参数 1.常用方法 getPara ...
- filter 拦截器 获取http请求参数
里面一些方法使用了hutool的工具类 可以替换成你自己习惯的 工具类不是记录的主要东西. 记录点 1.怎么创建拦截器 2.怎么统一管理拦截器是否启用和输用顺序 3.怎么获取传入的参数 4.怎么获取返 ...
最新文章
- 准备搭建经营分析前端试验型平台
- C语言基础-简单程序分析
- Docker 私服Registry简介与使用Docker-Compose安装Registry
- 在使用模板时遇到的错误,TypeError at /index/ context must be a dict rather than RequestContext(亲测)
- excel实战应用案例100讲(四)-Excel玩转数据:从分析到可视化
- struts 1.2配置文件
- python如何输出两列数据_Python-如何将一列分为两列?
- Python实现局域网内屏幕广播的技术要点分析
- 【我的失败人生】1105感到自己的弱小
- 牛客国庆集训派对Day3: G. Stones(博弈+SG)
- Qt Building the android package failed! 构建失败
- Grafana v5.2 设置
- chrome无法打开应用商店添加扩展程序的解决方案
- 动态规划——买卖股票系列
- 【修电脑】每次关机提示rundll32.exe程序没有响应,修改注册表解决问题
- 201421410013 唐昭靖 作业1
- android rom 制作工具,ROM工具箱(ROM Toolbox Pro)
- 千兆级LTE时代的重要技术——免许可频谱与小型基站深入解析
- java项目开发的工具选型对比,这10条建议你一定要关注!
- ERP-项目笔记—Day—08
热门文章
- 招银网科面试题汇总part1
- php excel行合并单元格
- tomcat启动出现The APR based Apache Tomcat Native library错误
- vue+elementui学生宿舍管理系统(报修,来访登记,水电费)java ssm项目介绍
- java cas volatile_VolatileCAS浅析
- 中国IT工作者35岁后的发展出路调查报告(1)
- 3、k - 最近邻分类器及使用验证集取得超参数
- 零基础学Java基础培训还是自学
- [转]移动开发者的自学宝典:十大在线编程学习网站
- 媒体报道 | 从河套出发:香港科大川藏铁路科考队用脚力探出“独家信息”