`
jinnianshilongnian
  • 浏览: 21424158 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2403122
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2996146
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5630387
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257181
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1592644
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248792
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5845630
Group-logo
跟我学Nginx+Lua开...
浏览量:697465
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:779839
社区版块
存档分类
最新评论

Spring3.2.3 绑定参数bug

 
阅读更多

今天早上看到一个问题:http://www.iteye.com/problems/95447

 

@Controller
public class ExampleController {

    @RequestMapping("/index")
    public String index(Long id) {
        System.out.println(id);
        return "index";
    }

}

  使用spring3.2.3时,在浏览器输入:http://localhost/index?id= 会报如下错误:

 

写道
HTTP ERROR 400

Problem accessing /es-web/monitor. Reason:

Required Long parameter 'userId' is not present
Powered by Jetty://

而spring3.2.3之前的版本是没有问题的。

 

spring3.2.3做了点小改变:

在其org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver的resolveArgument方法中:

                Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
		if (arg == null) {
			if (namedValueInfo.defaultValue != null) {
				arg = resolveDefaultValue(namedValueInfo.defaultValue);
			}
			else if (namedValueInfo.required) {
				handleMissingValue(namedValueInfo.name, parameter);
			}
			arg = handleNullValue(namedValueInfo.name, arg, paramType);
		}
		else if ("".equals(arg) && (namedValueInfo.defaultValue != null)) {
			arg = resolveDefaultValue(namedValueInfo.defaultValue);
		}

		boolean emptyArgValue = "".equals(arg);

		if (binderFactory != null) {
			WebDataBinder binder = binderFactory.createBinder(webRequest, null, namedValueInfo.name);
			arg = binder.convertIfNecessary(arg, paramType, parameter);
		}

		if (emptyArgValue && (arg == null)) {
			handleMissingValue(namedValueInfo.name, parameter);
		}

		handleResolvedValue(arg, namedValueInfo.name, parameter, mavContainer, webRequest);

		return arg;

多添加了如下代码来处理null的情况,而handleMissingValue默认是抛异常的:

if (emptyArgValue && (arg == null)) {
   handleMissingValue(namedValueInfo.name, parameter);
}

但是如果之前版本就不处理此情况。

 

所以综上,不管你是不是有如下代码参数都是必须的。。。

@RequestParam(value="username", required=false)  

 

这是个bug。。提交了其jira

https://jira.springsource.org/browse/SPR-10592

 

8
4
分享到:
评论
24 楼 aihaozhe101 2015-05-29  
请教个问题,在spring做参数绑定的时候怎么对这些参数进行一些特殊字符处理啊?
23 楼 jettys 2013-12-24  
今年是龙年,哦不,Tao哥 -:)。
22 楼 jettys 2013-12-24  
public String[] getParameterValues(String name); 感谢龙哥了,已经找出来了。没想到Spring会调这个方法,一直局限在拿到整个请求参数的map,忽略了getParameterValues。
21 楼 jettys 2013-12-23  
注入后在Controller 里面用传进来的request获取getParameter getParameterMap 可以进入debug。不知道它的id到底是怎么获取的。
20 楼 jinnianshilongnian 2013-12-23  
jettys 写道
http://www.iteye.com/problems/99448
就是请求参数 id; 你要是替换的话 需要把替换的request传入chain

chain.doFilter(new RequestWrapper(request,func.getWrapper(),func.getCookie(),func.getInputStream()), wrapper);


我chain传入的实际上是请求的包装类,RequestWrapper里面我重写了几个Spring可能调用的方法:

public String getParameter(String name) {
		String value = super.getParameter(name);
		if(map!=null&&map.get(name)!=null){
			value = (String)map.get(name);
		}
		return value;
	}
	
	/**
	 * ParameterMap
	 */
	public Map<String, String[]> getParameterMap() {
		Map<String, String[]> map = new HashMap<String, String[]>();
		map.putAll(super.getParameterMap());
		try {
			List<String> ls = new ArrayList<String>();
			for (String str : map.keySet()) {
				String[] s = map.get(str);
				for (String v : s) {
					ls.add(new XssFilter().filter(v));
				}
				map.put(str, ls.toArray(new String[ls.size()]));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}


目的是为了过滤XSS攻击,在Controller里面如果用SpringMvc传进来的HttpServletRequest的去取参数的话获取到都的是我包装类替换后的数据。
request.getParameter("xxx") 和 request.getParameterMap() 都是正常的获取到替换后的参数。
但是SpringMvc自动注入的参数弄死都不对,有点没招了。现在想做的就是想办法让SpringMvc拿到替换后的参数,而不是未过滤之前的。


你先debug看看走了你的代码吗?
19 楼 jettys 2013-12-23  
http://www.iteye.com/problems/99448
就是请求参数 id; 你要是替换的话 需要把替换的request传入chain

chain.doFilter(new RequestWrapper(request,func.getWrapper(),func.getCookie(),func.getInputStream()), wrapper);


我chain传入的实际上是请求的包装类,RequestWrapper里面我重写了几个Spring可能调用的方法:

public String getParameter(String name) {
		String value = super.getParameter(name);
		if(map!=null&&map.get(name)!=null){
			value = (String)map.get(name);
		}
		return value;
	}
	
	/**
	 * ParameterMap
	 */
	public Map<String, String[]> getParameterMap() {
		Map<String, String[]> map = new HashMap<String, String[]>();
		map.putAll(super.getParameterMap());
		try {
			List<String> ls = new ArrayList<String>();
			for (String str : map.keySet()) {
				String[] s = map.get(str);
				for (String v : s) {
					ls.add(new XssFilter().filter(v));
				}
				map.put(str, ls.toArray(new String[ls.size()]));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;
	}


目的是为了过滤XSS攻击,在Controller里面如果用SpringMvc传进来的HttpServletRequest的去取参数的话获取到都的是我包装类替换后的数据。
request.getParameter("xxx") 和 request.getParameterMap() 都是正常的获取到替换后的参数。
但是SpringMvc自动注入的参数弄死都不对,有点没招了。现在想做的就是想办法让SpringMvc拿到替换后的参数,而不是未过滤之前的。

18 楼 jinnianshilongnian 2013-12-23  
jettys 写道
请教下:
@Controller
public class ExampleController {

    @RequestMapping("/index")
    public String index(Long id) {
        System.out.println(id);
        return "index";
    }

}


这个id是怎样注入的?Spring是怎么从请求中取出这个id并注入的?

我在Spring的上一层做了一个Filter,尝试替换了getParameterMap、getParameter的内容,但是SpringMVC拿到的内容依旧是替换之前的。

request.getParameterMap()、request.getParameter();、request.getReader()都不是,求解。

刚提了一个问题,就看到老大的这文章。http://www.iteye.com/problems/99448

就是请求参数 id; 你要是替换的话 需要把替换的request传入chain
17 楼 jettys 2013-12-23  
请教下:
@Controller
public class ExampleController {

    @RequestMapping("/index")
    public String index(Long id) {
        System.out.println(id);
        return "index";
    }

}


这个id是怎样注入的?Spring是怎么从请求中取出这个id并注入的?

我在Spring的上一层做了一个Filter,尝试替换了getParameterMap、getParameter的内容,但是SpringMVC拿到的内容依旧是替换之前的。

request.getParameterMap()、request.getParameter();、request.getReader()都不是,求解。

刚提了一个问题,就看到老大的这文章。http://www.iteye.com/problems/99448
16 楼 sgq0085 2013-08-22  
遇到了相同问题,解决的方法是用String去接该数据
15 楼 jinnianshilongnian 2013-05-28  
lanhuidong 写道
jinnianshilongnian 写道
lanhuidong 写道
我还有个spring mvc testframework的问题,能否帮忙看下,http://www.iteye.com/problems/95405

我没用过 springmvc + freemarker的测试
如果方便 可否把代码发我 我跟踪下问题

代码我发消息个给你了,麻烦看下,谢谢

maven 多module时测试springmvc+freemarker的问题总结

搞定
14 楼 lanhuidong 2013-05-28  
jinnianshilongnian 写道
之前就有人提交了bug。 3.2.4会修复。
https://jira.springsource.org/browse/SPR-10578

这个我上午看到过
13 楼 jinnianshilongnian 2013-05-28  
之前就有人提交了bug。 3.2.4会修复。
https://jira.springsource.org/browse/SPR-10578
12 楼 lanhuidong 2013-05-28  
jinnianshilongnian 写道
lanhuidong 写道
我还有个spring mvc testframework的问题,能否帮忙看下,http://www.iteye.com/problems/95405

我没用过 springmvc + freemarker的测试
如果方便 可否把代码发我 我跟踪下问题

代码我发消息个给你了,麻烦看下,谢谢
11 楼 jinnianshilongnian 2013-05-28  
还一个类似的,不过是相同的bug
https://jira.springsource.org/browse/SPR-10404
10 楼 jinnianshilongnian 2013-05-28  
lanhuidong 写道
我还有个spring mvc testframework的问题,能否帮忙看下,http://www.iteye.com/problems/95405

我没用过 springmvc + freemarker的测试
如果方便 可否把代码发我 我跟踪下问题
9 楼 jinnianshilongnian 2013-05-28  
Saro 写道
boolean emptyArgValue = "".equals(arg); 
if (emptyArgValue && (arg == null)) {
}
//
这代码怎么这么怪异?
arg为""并且为null???

下边执行类型转换了
arg = binder.convertIfNecessary(arg, paramType, parameter); 
8 楼 Saro 2013-05-28  
boolean emptyArgValue = "".equals(arg); 
if (emptyArgValue && (arg == null)) {
}
//
这代码怎么这么怪异?
arg为""并且为null???
7 楼 lanhuidong 2013-05-28  
我还有个spring mvc testframework的问题,能否帮忙看下,http://www.iteye.com/problems/95405
6 楼 lanhuidong 2013-05-28  
jinnianshilongnian 写道
lanhuidong 写道
你测试过@RequestParam(value="username", required=false)吗?我这边怎么还是一样的错误?

先换到3.2.1吧(3.2.2的我没看) 我看了下这个版的没事

我觉得这个改变不合理,还是以前的版本比较适合。比如用jQuery:$(elem).find('form').serialize();这样获取表单数据就回出现id=这种参数。也就是说3.2.3不能这么干了,得自己获取参数。
5 楼 jinnianshilongnian 2013-05-28  
lanhuidong 写道
你测试过@RequestParam(value="username", required=false)吗?我这边怎么还是一样的错误?

先换到3.2.1吧(3.2.2的我没看) 我看了下这个版的没事

相关推荐

Global site tag (gtag.js) - Google Analytics