最近在做一个微信相关的网站,很多地方涉及到微信表情的输入,导致内容无法插入到数据库,虽然有用到一个表情过滤的工具类,但是需要过滤的地方比较多,于是想到在过滤器中过滤用户请求的内容。  

  request这个方法里,有getParameter(String name)、getParameterValues(String name)、getParameterNames()以及getParameterMap()是可以获得参数键值对的,Servlet自带的HttpServletRequest的方法是不支持修改用户请求类型的,我也尝试过直接去修改,都以异常收尾,后面我想到HttpServletRequest既然是一个接口,那我去实现它,然后直接用我们实现的类传到filterChain.doFilter(servletRequest, servletResponse)里面不也可以么,可是要实现的方法也太多了,好在ServletApi提供了一个class HttpServletRequestWrapper封装了这些方法,我们可以通过extends这个类,然后重写一些重要的方法来修改用户的请求,下面就开始我们的改造吧。 

  1.新建一个Filter,我给这个类命名为RequestFilter

public class RequestFilter implements Filter {
private final Logger logger = LoggerFactory.getLogger(RequestWrapper.class); @Override
public void init(FilterConfig filterConfig) throws ServletException {
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { } @Override
public void destroy() {
} }
  2.新建一个类,通过继承HttpServletRequestWrapper来实现request的作用。
class RequestWrapper extends HttpServletRequestWrapper {

    }

  3.新建一个private属性:private Map<String, String[]> paramMap;用这个paramMap来存储用户请求的内容,并且在构造方法中初始化paramMap,初始化的方法为

paramMap = new HashMap<>();//定义
paramMap.putAll(request.getParameterMap());//初始化

  4.重写上面提到的四个方法,

 @Override
public String getParameter(String name) {
String[] values = paramMap.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
} @Override
public String[] getParameterValues(String name) {
return paramMap.get(name);
} @Override
public Enumeration<String> getParameterNames() {
return new Enumeration<String>() {
private Iterator<String> iterator = paramMap.keySet().iterator(); @Override
public boolean hasMoreElements() {
return iterator.hasNext();
} @Override
public String nextElement() {
return iterator.next();
}
};
} @Override
public Map<String, String[]> getParameterMap() {
return paramMap;
}

  5.通过以上这些操作,我们就可以实现对用户请求进行修改。

  

public class RequestFilter implements Filter {
private final Logger logger = LoggerFactory.getLogger(RequestWrapper.class); @Override
public void init(FilterConfig filterConfig) throws ServletException {
} @Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
RequestWrapper requestWrapper = new RequestWrapper(request);
if (request.getMethod().equals("POST")) {
logger.debug("开始过滤请求中的表情字符");
requestWrapper.emojiFilter();
}
filterChain.doFilter(requestWrapper, servletResponse);
} @Override
public void destroy() {
} class RequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> paramMap; RequestWrapper(HttpServletRequest request) {
super(request);
paramMap = new HashMap<>();
paramMap.putAll(request.getParameterMap());
} @Override
public String getParameter(String name) {
String[] values = paramMap.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
} @Override
public String[] getParameterValues(String name) {
return paramMap.get(name);
} @Override
public Enumeration<String> getParameterNames() {
return new Enumeration<String>() {
private Iterator<String> iterator = paramMap.keySet().iterator(); @Override
public boolean hasMoreElements() {
return iterator.hasNext();
} @Override
public String nextElement() {
return iterator.next();
}
};
} @Override
public Map<String, String[]> getParameterMap() {
return paramMap;
} private void resetParamMap(String key, String[] value) {
paramMap.put(key, value);
} //过滤表情
void emojiFilter() {
for (String key : paramMap.keySet()) {
String[] valueSet = paramMap.get(key);
if (BeanUtil.nonNull(valueSet) && valueSet.length > 0) {
logger.debug("过滤前:" + valueSet[0]);
valueSet[0] = EmojiFilter.filterEmoji(valueSet[0]);
logger.debug("过滤后:" + valueSet[0]);
resetParamMap(key, valueSet);
}
}
}
}
}
 
 

J2EE Filter中修改request内容的更多相关文章

  1. 解决在Filter中读取Request中的流后,后续controller或restful接口中无法获取流的问题

    首先我们来描述一下在开发中遇到的问题,场景如下: 比如我们要拦截所有请求,获取请求中的某个参数,进行相应的逻辑处理:比如我要获取所有请求中的公共参数 token,clientVersion等等:这个时 ...

  2. 解决在Filter中读取Request中的流后, 然后再Control中读取不到的做法

    摘要: 大家知道, StringMVC中@RequestBody是读取的流的方式, 如果在之前有读取过流后, 发现就没有了. 我们来看一下核心代码: filter中主要做的事情, 就是来校验请求是否合 ...

  3. InstallShield2015制作安装包----------安装过程中修改文件内容

    //修改安装目录下autostart.vbs里的路径 //打开文件 OpenFileMode(FILE_MODE_NORMAL); strPath=INSTALLDIR+"centerAut ...

  4. 修改Request 中的数据

    拦截器修改参数 今天一位网友开发中遇到一个需求,他需要在Request中修改传递过来的数据.开始的时候他在拦截器中修改,在拦截器中可以获取到从前台request中 传递过来的数据.他写法大致如下:自定 ...

  5. Fiddler设置断点修改Request和Response

    一.Fiddler中修改Request有两种方法:  点击Rules-> Automatic Breakpoint ->Before Requset (这种方法会中断所有的会话) 消除命令 ...

  6. 使用HttpServletRequestWrapper在filter修改request参数

    javax.servlet.ServletRequest中的 Map<String, String[]> parameterMap = request.getParameterMap(); ...

  7. 如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容?

    原文:如何在ASP.NET Core自定义中间件中读取Request.Body和Response.Body的内容? 文章名称: 如何在ASP.NET Core自定义中间件读取Request.Body和 ...

  8. Visual Studio 2017中使用正则修改部分内容 如何使用ILAsm与ILDasm修改.Net exe(dll)文件 C#学习-图解教程(1):格式化数字字符串 小程序开发之图片转Base64(C#、.Net) jquery遍历table为每一个单元格取值及赋值 。net加密解密相关方法 .net关于坐标之间一些简单操作

    Visual Studio 2017中使用正则修改部分内容   最近在项目中想实现一个小工具,需要根据类的属性<summary>的内容加上相应的[Description]特性,需要实现的效 ...

  9. OC中加载html5调用html方法和修改HTML5内容

    1.利用webView控件加载本地html5或者网络上html5 2.设置控制器为webView的代理,遵守协议 3.实现代理方法webViewDidFinishLoad: 4.在代理方法中进行操作H ...

随机推荐

  1. java中字面量,常量和变量之间的区别(附:Integer缓存机制)

    一.引子 在各种教科书和博客中这三者经常被引用,今天复习到内存区域,想起常量池中就是存着字面量和符号引用,其实这三者并不是只在java中才有,各个语言中都有类似的定义,所以做一下总结,以示区分. 二. ...

  2. 读underscore

    最近在拜读只有1700行(含注释)代码的Underscore.js 1.9.1,记录一些东西 (参考https://underscorejs.org/underscore.js,https://git ...

  3. 【SQL Server高可用性】数据库复制:SQL Server 2008R2中数据库复制

    经常在论坛中看到有人问数据同步的技术,如果只是同步少量的表,那么可以考虑使用链接服务器+触发器,来实现数据同步,但当要同步的数据表比较多,那么可以考虑用数据库复制技术,来实现数据的同步. 一.使用场景 ...

  4. Appium 自动化测试(8) -- Appium Python client -- API

    最好的学习方法,就是看源码! 在  \appium\webdriver\webdriver.py ,新增了两个封装好定位安卓元素的方法,如  find_element_by_accessibility ...

  5. UVA-1604 Cubic Eight-Puzzle (双向BFS+状态压缩+限制搜索层数)

    题目大意:立体的八数码问题,一次操作是滚动一次方块,问从初始状态到目标状态的最少滚动次数. 题目分析:这道题已知初始状态和目标状态,且又状态数目庞大,适宜用双向BFS.每个小方块有6种状态,整个大方格 ...

  6. JAVA中的>>和>>>号以及<<号的作用

    public static void main(String[] args) { //右移2位,输出结果为2.二进制1000右移2位变为0010 System.out.println(8>> ...

  7. python学习笔记(二)---编辑工具sublimeText3运行python

    转载地址:https://blog.csdn.net/Maek_Tyx/article/details/76933897 1. 打开Sublime text 3 安装package controlSu ...

  8. POJ 3126 primepath bfs

    题目链接:http://poj.org/problem?id=3126 题意:1维的坐标轴,给出起点和终点,求从起点到终点变换经历的最短的步数.起点,终点和中间变换的数字都是4位,而且都是质数. 思路 ...

  9. vue2 过渡动画

    <body> <div id="app"> <transition name="move"> // transition里面 ...

  10. 利用Sonar定制自定义JS扫描规则(二)——自定义JS扫描规则

    在上一篇blog中,我们将sonar几个需要的环境都搭建好了,包括sonar的服务器,sonar runner,sonar的javascript插件.现在我们就来讲如何自定义JS扫描规则. 实际上有3 ...