spring Controller 之前修改/增加请求参数和值request.getParameterMap() --java

来源:互联网 发布:mysql 服务器配置 编辑:程序博客网 时间:2024/06/05 09:11

为什么会有这种需求?

比如:要求对xml类型的特殊字符进行值转换过滤,以防止XSS注入攻击。比如:在请求某些url时,全部需要新加入一个以前代码没有的参数项,其值可能是从cookie/xml/propertis 文件读取的。

 

首先,一看这个问题,会想到2个方面:

1,spring 拦截器:拦截需要的url,实现 preHandle(前置处理方法) 方法,在其中,对 request 进行处理。

2,servlet Filter过滤器:过滤需要的url,实现 doFilter 方法,在其中,对 request 进行处理。并把此 Filter 配置在 spring 的 DispatcherServlet 之前。

 

经过实验:方式1——spring 拦截器,实现不了题目上的功能。set设置不会报错,但是,spring自动参数绑定取不到 增加/修改 后的值。

 

那么,只能从 servlet Filter过滤器 入手,来解决此问题。

开始尝试模式:

1,request.setAttribute("abc", 1);  直接对 request set 一个参数项。结果,spring不鸟此值。失败!

2,request.getParameterMap().put("abc", new String[] { "1" });  给 request 的请求参数map加入一个新值。结果,直接报错:java.lang.IllegalStateException: No modifications are allowed to a locked ParameterMap  。SB了,这就是不让人修改此map啊。

3,简单的能随便想到的,都不行,那只能百度google了。果然,干货在此:

class ParameterRequestWrapper extends HttpServletRequestWrapper {private Map<String, String[]> params;public ParameterRequestWrapper(HttpServletRequest request, Map<String, String[]> newParams) {super(request);this.params = newParams;renewParameterMap(request);}@Overridepublic String getParameter(String name) {String result = "";Object v = params.get(name);if (v == null) {result = null;} else if (v instanceof String[]) {String[] strArr = (String[]) v;if (strArr.length > 0) {result = strArr[0];} else {result = null;}} else if (v instanceof String) {result = (String) v;} else {result = v.toString();}return result;}@Overridepublic Map<String, String[]> getParameterMap() {return params;}@Overridepublic Enumeration<String> getParameterNames() {return new Vector<String>(params.keySet()).elements();}@Overridepublic String[] getParameterValues(String name) {String[] result = null;Object v = params.get(name);if (v == null) {result = null;} else if (v instanceof String[]) {result = (String[]) v;} else if (v instanceof String) {result = new String[] { (String) v };} else {result = new String[] { v.toString() };}return result;}private void renewParameterMap(HttpServletRequest req) {String queryString = req.getQueryString();if (queryString != null && queryString.trim().length() > 0) {String[] params = queryString.split("&");for (int i = 0; i < params.length; i++) {int splitIndex = params[i].indexOf("=");if (splitIndex == -1) {continue;}String key = params[i].substring(0, splitIndex);if (!this.params.containsKey(key)) {if (splitIndex < params[i].length()) {String value = params[i].substring(splitIndex + 1);this.params.put(key, new String[] { value });}}}}}}

你需要这么一个辅助类,其实就是自己定义一个request啦。然后,我要加入一个新参数,然后:

Map<String, String[]> m = new HashMap<String, String[]>(request.getParameterMap());m.put("abc", new String[] { "1" });request = new ParameterRequestWrapper(request, m);

 

到此,Filter 完成,挂在web.xml 中一测试,OK,spring成功绑定到此值。

然后,如果你要修改前台传递过来的 value 值,那么,也需要如上的辅助类,原理相通。

以上内容来自分享https://my.oschina.net/sxgkwei/blog/872457

原创粉丝点击