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

springmvc 3.2 @MatrixVariable bug 2

 
阅读更多

之前遇到过一个bug,《spring3.2 带matrix变量的URL匹配问题》(spring3.2.3已经修复该bug),今天看到问答又有人遇到一个,在此记录下,bug可真不少,测试用例看了下,写的并不是很全面。

 

问题:

http://www.iteye.com/problems/95247

 

@RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET)  
    public void findPet(@MatrixVariable Map<String, String> matrixVars, @MatrixVariable(pathVar = "petId") Map<String, String> petMatrixVars) {  
        System.out.println(matrixVars);  
        System.out.println(petMatrixVars);  
    }  

 上面代码是spring文档中的例子,浏览器中输入:http://localhost:8080/owners/44/pets/55;q=22,33;s=23时,控制台输出:

 

{q=[22, 33], s=[23]}  
{q=[22, 33], s=[23]}  

但是当输入http://localhost:8080/owners/42;q=11;r=12/pets/55;q=22,33;s=23则findPet方法没有执行,难道spring文档有错误?还是少了什么配置?

 

目前不支持

 

分析:

1、先看下springmvc官网的单元测试用例

@Test
	public void getLookupPathWithSemicolonContent() {
		helper.setRemoveSemicolonContent(false);

		request.setContextPath("/petclinic");
		request.setServletPath("/main");
		request.setRequestURI("/petclinic;a=b/main;b=c/welcome.html;c=d");

		assertEquals("/welcome.html;c=d", helper.getLookupPathForRequest(request));
	}

	@Test
	public void getLookupPathWithSemicolonContentAndNullPathInfo() {
		helper.setRemoveSemicolonContent(false);

		request.setContextPath("/petclinic");
		request.setServletPath("/welcome.html");
		request.setRequestURI("/petclinic;a=b/welcome.html;c=d");

		assertEquals("/welcome.html;c=d", helper.getLookupPathForRequest(request));
	}

 https://github.com/SpringSource/spring-framework/blob/master/spring-web/src/test/java/org/springframework/web/util/UrlPathHelperTests.java

 

此处可以看到,如果请求的uri是/owners/42;q=11;r=12/pets/55;q=22,33;s=23,那么request.getServletPath()实际是/owners/42,而不是期待的/owners/42/pets/55;可以参考

https://java.net/jira/browse/SERVLET_SPEC-67?page=com.atlassian.streams.streams-jira-plugin%3Aactivity-stream-issue-tab

 

接下来看下springmvc如何进行url匹配的,假设此处使用的是RequestMappingHandlerMapping(http://jinnianshilongnian.iteye.com/blog/1682510):

1、

protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		if (logger.isDebugEnabled()) {
			logger.debug("Looking up handler method for path " + lookupPath);
		}

		HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);

 此处委托给UrlPathHelper去查找path

2、

public String getLookupPathForRequest(HttpServletRequest request) {
		// Always use full path within current servlet context?
		if (this.alwaysUseFullPath) {
			return getPathWithinApplication(request);
		}
		// Else, use path within current servlet mapping if applicable
		String rest = getPathWithinServletMapping(request);
		if (!"".equals(rest)) {
			return rest;
		}
		else {
			return getPathWithinApplication(request);
		}
	}

 此处因为默认不开启alwaysUseFullPath,因此会执行getPathWithinServletMapping()

3、

public String getPathWithinServletMapping(HttpServletRequest request) {
		String pathWithinApp = getPathWithinApplication(request);
		String servletPath = getServletPath(request);
		String path = getRemainingPath(pathWithinApp, servletPath, false);
		if (path != null) {
			// Normal case: URI contains servlet path.
			return path;
		}
		else {
			// Special case: URI is different from servlet path.
			// Can happen e.g. with index page: URI="/", servletPath="/index.html"
			// Use path info if available, as it indicates an index page within
			// a servlet mapping. Otherwise, use the full servlet path.
			String pathInfo = request.getPathInfo();
			return (pathInfo != null ? pathInfo : servletPath);
		}
	}

此处调用String servletPath = getServletPath(request); 出问题了,如果我们的url是 http://localhost:8080/owners/44;a=123/pets/55;q=22,33;s=23,那么获取的将是/owners/44,而不是/owners/42/pets/55,此处有说明:

https://java.net/jira/browse/SERVLET_SPEC-67?page=com.atlassian.streams.streams-jira-plugin%3Aactivity-stream-issue-tab

 

接着执行getRemainingPath则获取到剩余部分 /pets/55;q=22,33;s=23,即和之前的单元测试一样。 所以得到的path不可能匹配模式/owners/{ownerId}/pets/{petId},但是匹配/pets/{petId}(但没有意义了),所以失败了。

 

@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET)  
    public void findPet(@MatrixVariable Map<String, String> matrixVars, @MatrixVariable(pathVar = "petId") Map<String, String> petMatrixVars) {  
        System.out.println(matrixVars);  
        System.out.println(petMatrixVars);  
    }  

 

已提交给springsource。

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

9
9
分享到:
评论
14 楼 wangxiang243 2013-06-09  
jinnianshilongnian 写道
http://jinnianshilongnian.iteye.com/blog/1831408

这个修复了

谢谢你
13 楼 jinnianshilongnian 2013-06-09  
http://jinnianshilongnian.iteye.com/blog/1831408

这个修复了
12 楼 wangxiang243 2013-06-08  
jinnianshilongnian 写道
wangxiang243 写道
jinnianshilongnian 写道
wangxiang243 写道
我用的是spring3.2.3,也开启了enableMatrixVariables,怎么还是不行啊?

你怎么用的?


@RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET)
	public void findPet(@MatrixVariable Map<String, String> matrixVars,
			@MatrixVariable(pathVar = "petId") Map<String, String> petMatrixVars) {
		logger.error("matrixVars:" + matrixVars);
		logger.error("petMatrixVars" + petMatrixVars);
	}


http://localhost:8080/owners/42;q=11;r=12/pets/55;q=22,33;s=23

进不到controller

这个是bug 



啊!? 不是修复了吗?如果修复的不是这个bug,你们说的修复的什么bug?
11 楼 jinnianshilongnian 2013-06-08  
wangxiang243 写道
jinnianshilongnian 写道
wangxiang243 写道
我用的是spring3.2.3,也开启了enableMatrixVariables,怎么还是不行啊?

你怎么用的?


@RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET)
	public void findPet(@MatrixVariable Map<String, String> matrixVars,
			@MatrixVariable(pathVar = "petId") Map<String, String> petMatrixVars) {
		logger.error("matrixVars:" + matrixVars);
		logger.error("petMatrixVars" + petMatrixVars);
	}


http://localhost:8080/owners/42;q=11;r=12/pets/55;q=22,33;s=23

进不到controller

这个是bug 
10 楼 wangxiang243 2013-06-08  
jinnianshilongnian 写道
wangxiang243 写道
我用的是spring3.2.3,也开启了enableMatrixVariables,怎么还是不行啊?

你怎么用的?


@RequestMapping(value = "/owners/{ownerId}/pets/{petId}", method = RequestMethod.GET)
	public void findPet(@MatrixVariable Map<String, String> matrixVars,
			@MatrixVariable(pathVar = "petId") Map<String, String> petMatrixVars) {
		logger.error("matrixVars:" + matrixVars);
		logger.error("petMatrixVars" + petMatrixVars);
	}


http://localhost:8080/owners/42;q=11;r=12/pets/55;q=22,33;s=23

进不到controller
9 楼 jinnianshilongnian 2013-06-08  
wangxiang243 写道
我用的是spring3.2.3,也开启了enableMatrixVariables,怎么还是不行啊?

你怎么用的?
8 楼 wangxiang243 2013-06-08  
我用的是spring3.2.3,也开启了enableMatrixVariables,怎么还是不行啊?
7 楼 wangxiang243 2013-06-08  
我用的是spring3.2.3,也开启了enableMatrixVariables,怎么还是不行啊?
6 楼 jinnianshilongnian 2013-05-21  
spring 3.2.3 默认是禁用matrix variable的

可以通过<mvc:annotation-driven enableMatrixVariables="true"> 开启
5 楼 jinnianshilongnian 2013-05-21  
之前遇到过一个bug,《spring3.2 带matrix变量的URL匹配问题》(spring3.2.3已经修复该bug)

这个已经修复;

不过当前这个还是不行
4 楼 jinnianshilongnian 2013-05-21  
weishuwei 写道
对于/owners/44;m=1/pets/55;q=22,33;s=23,getServletPath不应该是只取路径,不取参数的么??没用过martin变量的场景,个人觉得后面一部分应该算参数

getServletPath取到的是/owners/44 即忽略“;”后面的,如使用jsessionid的场景;因此就出现这个问题了,如果其使用getRequestURI 就没有问题,不过如下地址也提供了解决方案
https://java.net/jira/browse/SERVLET_SPEC-67?page=com.atlassian.streams.streams-jira-plugin%3Aactivity-stream-issue-tab
3 楼 weishuwei 2013-05-21  
对于/owners/44;m=1/pets/55;q=22,33;s=23,getServletPath不应该是只取路径,不取参数的么??没用过martin变量的场景,个人觉得后面一部分应该算参数
2 楼 jinnianshilongnian 2013-05-21  
mlw2000 写道
不担心,spring改bug的速度还是很快的

之前提交一个 好久都没反应,连个回复都没有,不过他们的spring data项目 很活跃
https://jira.springsource.org/browse/SPR-10549
1 楼 mlw2000 2013-05-21  
不担心,spring改bug的速度还是很快的

相关推荐

    springMVC3.2+Hibernate4的基本配置

    在本文中,我们将深入探讨如何配置一个基于SpringMVC 3.2和Hibernate 4的基础项目。这个项目配置涵盖了核心的框架组件,如数据库连接池、事务管理、缓存策略以及拦截器,这些是构建现代Java Web应用的关键要素。我们...

    框架springmvc3.2+spring3.2+mybatis3.11+maven整合

    SSM(Spring MVC + Spring + MyBatis)是Java Web开发中常见的三层架构组合,而Spring MVC 3.2、Spring 3.2和MyBatis 3.11是这套框架组合的特定版本。本项目是将这些框架通过Maven进行整合,方便在MyEclipse环境中...

    springmvc 3.2(jar包)

    2. **Model-View-Controller (MVC) 设计模式**: SpringMVC遵循MVC模式,将业务逻辑(Model)、数据呈现(View)和用户交互(Controller)分离,提高代码的可维护性和可测试性。 3. **@Controller注解**: 用于标记一...

    SpringMVC3.2+JPA使用注解的方式环境搭建

    ### SpringMVC3.2与JPA结合使用注解方式的环境搭建详解 在现代的Java Web开发中,SpringMVC框架与JPA(Java Persistence API)的结合使用已成为构建企业级应用的标准模式之一。SpringMVC负责处理前端请求与后端业务...

    springMVC3.2+Hibernate4+freemarker

    springMVC3.2+Hibernate4+freemarker 代码框架采用springMVC3.2.4+hibernate4.2.8+freemarker2.3.16 功能方面只是一个简单的注册登录,前台使用freemarker渲染,使用了freemarker自定义标签。

    基于springMVC3.2的REST源码,结合了jquery和json

    **SpringMVC 3.2 RESTful服务** SpringMVC是Spring框架的一部分,它是一个用于构建Web应用程序的轻量级MVC(Model-View-Controller)框架。在SpringMVC 3.2版本中,引入了对RESTful Web服务的强大支持,这使得开发...

    (SSM)springmvc3.2+spring3.2+mybatis3.11(带jar包)

    在“springmvc3.2+spring3.2+mybatis3.11”这个版本中: - Spring MVC 3.2带来了更多的注解支持,改进了异常处理机制,以及对RESTful风格的支持。 - Spring 3.2版本提供了更多性能优化,提升了对Java EE 6的兼容性,...

    【免费】Springmvc3.2所需要的全部jar包

    在3.2版本中,它提供了许多增强的功能和优化,使得开发人员能够更高效、更灵活地处理Web请求和响应。本压缩包包含Spring MVC 3.2运行所需的所有jar包,确保了项目的完整性和兼容性。 1. **Spring Framework 3.2.0....

    maven3.05+springmvc3.2+spring3.2+hibernate3.6重写传智播客OA源代码(包含数据库)

    maven3.05+springmvc3.2+spring3.2+hibernate3.6重写传智播客OA源代码。菜单部分采用ztree.界面有一部分使用bootstrap3.11。听了汤阳光大神的视频收获很大,也学习springmvc,期间有一个想法用springmvc来改写汤大神...

    SpringMVC3.2 demo

    SpringMVC 3.2 是一个强大的Java web开发框架,由Spring.IO团队维护,用于构建高效、模块化且易于测试的Web应用程序。该框架的核心功能是处理HTTP请求和响应,提供了一个模型-视图-控制器(MVC)架构,使得开发者...

    springMVC3.2实现后台校验

    2. `@Null`: 检查字段是否为空。 3. `@Min(value)`: 检查数值型字段是否大于等于指定的最小值。 4. `@Max(value)`: 棨查数值型字段是否小于等于指定的最大值。 5. `@Size(min, max)`: 检查字符串、数组或集合字段的...

    springMVC3.2+Rest+jquery1.9+json实现的入门例子

    入门例子,可以运行,完整的包,具体代码说明可见:【http://wenku.baidu.com/view/0ab26ef4f705cc175527096b?fr=prin】,一样的。代码虽然不大,但可运行,有一定的启发性。

    框架springmvc3.2+spring3.2+mybatis3.11整合附带jar包

    2. **Spring**: Spring是一个全面的后端开发框架,提供了依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)等核心特性。它使得开发者能够轻松管理对象之间的依赖关系,...

    springmvc3.2_practice

    《SpringMVC 3.2 实战指南》 在Java Web开发领域,SpringMVC作为Spring框架的一部分,已经成为构建高效、灵活的Web应用程序的重要选择。本实战指南将深入探讨SpringMVC 3.2版本的核心特性,帮助开发者掌握这一强大...

    springMVC3.2 简单实现文件的上传和下载

    2. **Spring MVC的MultipartFile接口**: Spring MVC提供了`MultipartFile`接口,用于处理上传的文件。它包含了文件名、大小、类型等信息,可以方便地将上传的文件内容存储到服务器上。 3. **配置Spring MVC**: ...

    jack-json包和配置,springmvc3.2及以下json格式支持

    2. **配置Spring MVC**: 在Spring的配置文件(如`xml配置.txt`中)中,我们需要添加一个自定义的消息转换器,通常是`Jackson2JsonMessageConverter`,并将其添加到`messageConverters`列表中。示例配置如下: ```...

    详解SpringMVC注解@initbinder解决类型转换问题

    SpringMVC 注解 @InitBinder 解决类型转换问题 在使用 SpringMVC 框架时,经常会遇到表单中的日期字符串和 JavaBean 的 Date 类型的转换问题。 SpringMVC 默认不支持这个格式的转换,因此需要手动配置,自定义数据...

    springmvc3.2

    2. **移动设备支持**:此版本引入了对移动设备的支持,通过`@RequestMapping`注解的`produces`和`consumes`属性,可以指定响应的MIME类型,从而根据不同的设备返回适应的视图。 3. **RESTful风格的支持**:Spring ...

    SpringMVC的@InitBinder参数转换代码实例

    SpringMVC的@InitBinder参数转换代码实例 本文主要介绍了SpringMVC的@InitBinder参数转换代码实例,通过示例代码详细介绍了@InitBinder的使用方法和原理,对大家的学习或者工作具有一定的参考学习价值。 一、什么...

Global site tag (gtag.js) - Google Analytics