首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

引文方式的参数使用过滤器进行过滤

2013-01-01 
注解方式的参数使用过滤器进行过滤最近做项目时,页面传递给后台的特殊字符很烦人,想写一个公共方法来给需

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

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

?

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

?

@Overridepublic 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);}@Overridepublic 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 注解的参数值 就是 解码之后的了:


引文方式的参数使用过滤器进行过滤

热点排行