`

注解方式的参数使用过滤器进行过滤

阅读更多

最近做项目时,页面传递给后台的特殊字符很烦人,想写一个公共方法来给需要使用的地方调用,但是后来发现,要调用的地方实在太多,万一有什么变动的话,改起来烦死人。后来发现使用过滤器可以完成这个功能。

 

过滤器中的主要代码如下:

 

	@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
分享到:
评论

相关推荐

    Spring注解 - 52注解 - 原稿笔记

    注解包含: 拦截器 , 过滤器 , 序列化 , @After , @AfterReturning , @AfterThrowing , @annotation , @Around , @Aspect , @Autowired , @Bean , @Before , @Component , @ComponentScan , @ComponentScans , @...

    SpringMVC示例

    本次实践内容包括RequestMapping关键字修饰类和方法(请求方式、请求参数&请求头、Ant风格路径)、PathVariable注解、HiddenHttpMethodFilter 过滤器(将Get请求转换成PUT、DELETE请求)、 RequestParam 注解、...

    SpringMVC Employee Demo

    本次实践内容包括RequestMapping关键字修饰类和方法(请求方式、请求参数&请求头、Ant风格路径)、PathVariable注解、HiddenHttpMethodFilter 过滤器(将Get请求转换成PUT、DELETE请求)、RequestParam 注解、...

    Java EE常用框架.xmind

    使用过滤器实现登录和退出功能 步骤 当用户没有认证时,请求loginurl进行认证【上边我们已经配置了】,用户身份和用户密码提交数据到loginurl FormAuthenticationFilter拦截住取出request中的username...

    一个简洁的java http框架.rar

    支持过滤器来过滤传入的数据 基于注解、配置化的方式定义Http请求 支持Spring和Springboot集成 JSON格式数据序列化和反序列化 XML格式数据序列化和反序列化 Protobuf格式数据序列化和反序列化 JSON、XML或其他类型...

    Spring中文帮助文档

    3.12.3. 使用过滤器自定义扫描 3.12.4. 自动检测组件的命名 3.12.5. 为自动检测的组件提供一个作用域 3.12.6. 用注解提供限定符元数据 3.13. 注册一个LoadTimeWeaver 4. 资源 4.1. 简介 4.2. Resource接口 ...

    Spring API

    3.12.3. 使用过滤器自定义扫描 3.12.4. 自动检测组件的命名 3.12.5. 为自动检测的组件提供一个作用域 3.12.6. 用注解提供限定符元数据 3.13. 注册一个LoadTimeWeaver 4. 资源 4.1. 简介 4.2. Resource接口 ...

    Hibernate Annotations 中文文档

    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. ...

    lamp-cloud微服务脚手架

    通过过滤器对所有请求中的 表单参数 进行过滤 通过Json反序列化器实现对所有 application/json 类型的参数 进行过滤 13、当前登录用户信息注入器 通过注解实现用户身份注入 14、在线API 由于原生swagger-ui某些功能...

    hibernate annotation 中文文档

    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. 什么是约束...

    hibernate annotation帮助文档

    前言 1. 翻译说明 2. 版权声明 前言 1. 创建一个注解项目 1.1. 系统需求 1.2. 系统配置 2. 实体Bean 2.1. 简介 2.2. 用EJB3注解进行映射 2.2.1. 声明实体bean ...2.4.8. 过滤器 2.4.9. 查询

    ABP开发指南

    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 开源的访问层中间件,基于java平台

    report使用方式: a)maven项目加入report依赖,普通项目则导入jar包 b)引入spring文件 spring/ankang-report.xml,web.xml依赖springMVC配置 c)继承ReportStart类, @Component//通过spring注入 可设置为单例 ...

    Swagger3 API接口文档规范课程(教学视频+源代码)

    第三步:新建HelloWorldController.java控制器类 第四步:访问swagger-ui,查看接口文档 第五步:Swagger注解描述接口 3 Swagger3 常用配置注解讲解 3.1 Swagger3常用配置如下: 3.2 实例一 `@ApiImplicitParams` 和...

    Java核心技术II(第8版)

    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:微服务spring dubbo项目:dubbo rpc;德鲁伊数据源连接池; mybatis配置集成,多数据源; jmx监控MBean;定时任务; aop; ftp;测试;指标监控;参数验证;跨域处理; shiro权限控制; consul服务注册,发现; redis分布式锁; SPI服务机制; cat监控; netty服务代理; websocket; disconf; mongodb集成;休息; docker; fescar

    spring-dubbo-service微服务一,服务模块1,服务器配置:servlet,侦听器,拦截器,过滤器,aop,定时任务mybatis配置集成,多数据源;级联查询一对一对一对多注解配置及xml配置方式;分页处理:传递Page参数或继承...

    AisMVC.zip

    我们团队开发web项目一般采用前后端分离,所以后端的的Controller层的功能仅仅只有提供ajax接口,页面集成后的跳转,过滤器和拦截器,所以我就想着自己写一款仿springmvc的mvc框架作为自己和团队以后的开发中小型项目的...

    容灾项目从入门到实战视频.rar

    │ 74-从数据库中获取过滤器参数-1.mp4 │ 75-分析编码的流程-1.mp4 │ 76-创建job类和task类-1.mp4 │ 77-创建scheduleutilsv1-1.mp4 │ 78-创建任务调度工具类-1.mp4 │ 79-整合任务管理和任务日志-1.mp4 │ 80-...

Global site tag (gtag.js) - Google Analytics