最近做项目时,页面传递给后台的特殊字符很烦人,想写一个公共方法来给需要使用的地方调用,但是后来发现,要调用的地方实在太多,万一有什么变动的话,改起来烦死人。后来发现使用过滤器可以完成这个功能。
过滤器中的主要代码如下:
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
chain.doFilter(new HTMLCharacterRequest(req), resp);
}
其中 HTMLCharacterRequest 是继承与 HttpServletRequest包装类的:
public class HTMLCharacterRequest extends HttpServletRequestWrapper {
public HTMLCharacterRequest(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name){
return filter(super.getParameter(name));
}
/**
* 过滤请求参数值
* @param parameter
* @return
*/
private String filter(String parameter) {
if(StringHelper.isNullOrEmpty(parameter)){
return null;
}
return StringEscapeUtils.escapeSql(StringHelper.unescape(parameter));
}
}
StringHelper.unescape()方法内容如下:
public static String unescape(String src) {
StringBuffer tmp = new StringBuffer();
tmp.ensureCapacity(src.length());
int lastPos = 0, pos = 0;
char ch;
while (lastPos < src.length()) {
pos = src.indexOf("%", lastPos);
if (pos == lastPos) {
if (src.charAt(pos + 1) == 'u') {
ch = (char) Integer.parseInt(
src.substring(pos + 2, pos + 6), 16);
tmp.append(ch);
lastPos = pos + 6;
} else {
ch = (char) Integer.parseInt(
src.substring(pos + 1, pos + 3), 16);
tmp.append(ch);
lastPos = pos + 3;
}
} else {
if (pos == -1) {
tmp.append(src.substring(lastPos));
lastPos = src.length();
} else {
tmp.append(src.substring(lastPos, pos));
lastPos = pos;
}
}
}
return tmp.toString();
}
这样做完之后,前端传递过来的escape("xxx") 就可以在Controller中可以使用request.getParameter("xxx")的形式获取到解码之后并且对数据库操作无影响的字符串了。
截图如下:
可以看到request的真正类型是
HTMLCharacterRequest ,并且 通过 request.getParameter("provinceName") 获取到的值 也是 解码并且对数据库无影响的值。
但是,这个时候就有个问题了,如下:
方法参数列表中 使用 @RequestParam 获取到的参数 却是未解码的。
为什么呢???
后来跟踪Annotation源码发现了如下的一段代码:
(详见:org.springframework.web.bind.annotation.support.HandlerMethodInvoker 的 resolveRequestParam方法)
if (paramValue == null) {
String[] paramValues = webRequest.getParameterValues(paramName);
if (paramValues != null) {
paramValue = (paramValues.length == 1 ? paramValues[0] : paramValues);
}
}
if (paramValue == null) {
if (defaultValue != null) {
paramValue = resolveDefaultValue(defaultValue);
}
else if (required) {
raiseMissingParameterException(paramName, paramType);
}
paramValue = checkValue(paramName, paramValue, paramType);
}
由此发现,在源码中是使用 getParameterValues 方法来获取参数值的,而不是 getParameter方法
所以需要在 HTMLCharacterRequest 中再 @override 一下 getParameterValues 的方法:
@Override
public String[] getParameterValues(String name) {
return filter(super.getParameterValues(name));
}
/**
* 过滤请求参数值
* @param parameters
* @return
*/
private String[] filter(String[] parameters) {
if(parameters.length == 0){
return null;
}
for (int i=0; i<parameters.length; i++) {
parameters[i] = StringEscapeUtils.escapeSql(StringHelper.unescape(parameters[i]));
}
return parameters;
}
这个时候再来看 @RequestParam 注解的参数值 就是 解码之后的了:
- 大小: 12.8 KB
- 大小: 10.3 KB
- 大小: 18.2 KB
- 大小: 20.3 KB
分享到:
相关推荐
注解包含: 拦截器 , 过滤器 , 序列化 , @After , @AfterReturning , @AfterThrowing , @annotation , @Around , @Aspect , @Autowired , @Bean , @Before , @Component , @ComponentScan , @ComponentScans , @...
本次实践内容包括RequestMapping关键字修饰类和方法(请求方式、请求参数&请求头、Ant风格路径)、PathVariable注解、HiddenHttpMethodFilter 过滤器(将Get请求转换成PUT、DELETE请求)、 RequestParam 注解、...
本次实践内容包括RequestMapping关键字修饰类和方法(请求方式、请求参数&请求头、Ant风格路径)、PathVariable注解、HiddenHttpMethodFilter 过滤器(将Get请求转换成PUT、DELETE请求)、RequestParam 注解、...
使用过滤器实现登录和退出功能 步骤 当用户没有认证时,请求loginurl进行认证【上边我们已经配置了】,用户身份和用户密码提交数据到loginurl FormAuthenticationFilter拦截住取出request中的username...
支持过滤器来过滤传入的数据 基于注解、配置化的方式定义Http请求 支持Spring和Springboot集成 JSON格式数据序列化和反序列化 XML格式数据序列化和反序列化 Protobuf格式数据序列化和反序列化 JSON、XML或其他类型...
3.12.3. 使用过滤器自定义扫描 3.12.4. 自动检测组件的命名 3.12.5. 为自动检测的组件提供一个作用域 3.12.6. 用注解提供限定符元数据 3.13. 注册一个LoadTimeWeaver 4. 资源 4.1. 简介 4.2. Resource接口 ...
3.12.3. 使用过滤器自定义扫描 3.12.4. 自动检测组件的命名 3.12.5. 为自动检测的组件提供一个作用域 3.12.6. 用注解提供限定符元数据 3.13. 注册一个LoadTimeWeaver 4. 资源 4.1. 简介 4.2. Resource接口 ...
2.4.8. 过滤器 2.4.9. 查询 3. 通过XML覆写元数据 3.1. 原则 3.1.1. 全局级别的元数据 3.1.2. 实体级别的元数据 3.1.3. 属性级别的元数据 3.1.4. 关联级别的元数据 4. Hibernate验证器 4.1. 约束 4.1.1. ...
通过过滤器对所有请求中的 表单参数 进行过滤 通过Json反序列化器实现对所有 application/json 类型的参数 进行过滤 13、当前登录用户信息注入器 通过注解实现用户身份注入 14、在线API 由于原生swagger-ui某些功能...
2.4.8. 过滤器 2.4.9. 查询 3. 通过XML覆写元数据 3.1. 原则 3.1.1. 全局级别的元数据 3.1.2. 实体级别的元数据 3.1.3. 属性级别的元数据 3.1.4. 关联级别的元数据 4. Hibernate验证器 4.1. 约束 4.1.1. 什么是约束...
前言 1. 翻译说明 2. 版权声明 前言 1. 创建一个注解项目 1.1. 系统需求 1.2. 系统配置 2. 实体Bean 2.1. 简介 2.2. 用EJB3注解进行映射 2.2.1. 声明实体bean ...2.4.8. 过滤器 2.4.9. 查询
3.4.5 设定过滤器参数 62 3.4.6 自定义过滤器 62 3.4.7 其它对象关系映射工具 64 3.5 ABP领域层—领域事件 64 3.5.1 事件总线 64 3.5.2 定义事件 65 3.5.3 触发事件 65 3.5.4 事件处理 66 3.5.5 注册处理器 68 3.5.6...
report使用方式: a)maven项目加入report依赖,普通项目则导入jar包 b)引入spring文件 spring/ankang-report.xml,web.xml依赖springMVC配置 c)继承ReportStart类, @Component//通过spring注入 可设置为单例 ...
第三步:新建HelloWorldController.java控制器类 第四步:访问swagger-ui,查看接口文档 第五步:Swagger注解描述接口 3 Swagger3 常用配置注解讲解 3.1 Swagger3常用配置如下: 3.2 实例一 `@ApiImplicitParams` 和...
2.6.1 使用SAX解析器 2.6.2 使用StAX解析器 2.7 生成XML文档 2.7.1 使用StAX写出XML文档 2.8 XSL转换 第三章 网络 3.1 连接到服务器 3.1.1 套接字超时 3.1.2 因特网地址 3.2 实现服务器 3.2.1 为多个客户端服务 ...
spring-dubbo-service微服务一,服务模块1,服务器配置:servlet,侦听器,拦截器,过滤器,aop,定时任务mybatis配置集成,多数据源;级联查询一对一对一对多注解配置及xml配置方式;分页处理:传递Page参数或继承...
我们团队开发web项目一般采用前后端分离,所以后端的的Controller层的功能仅仅只有提供ajax接口,页面集成后的跳转,过滤器和拦截器,所以我就想着自己写一款仿springmvc的mvc框架作为自己和团队以后的开发中小型项目的...
│ 74-从数据库中获取过滤器参数-1.mp4 │ 75-分析编码的流程-1.mp4 │ 76-创建job类和task类-1.mp4 │ 77-创建scheduleutilsv1-1.mp4 │ 78-创建任务调度工具类-1.mp4 │ 79-整合任务管理和任务日志-1.mp4 │ 80-...