18.6 请求参数和路径变量
18.6 请求参数和路径变量
请求参数和路径变量都可以用于发送值给服务器。二者都是URL
的一部分。请求参数采用key=value
形式,并用“&
”分隔。例如,下面的URL
带有一个名为productId
的请求参数,其值为3
:
1 | http://localhost:8080/app18b/product_retrieve?productId=3 |
在传统的Servlet
编程中,可以使用HttpServletRequest
的getParameter
方法来获取一个请求参数值:
1 | String productId = httpServletRequest.getParameter("productId"); |
Spring MVC
提供了一个更简单的方法来获取请求参数值:通过使用org.springframework.web.bind.annotation.RequestParam
注解类型来注解方法参数。例如,下面的方法包含了一个获取请求参数productId
值的参数:
1 | public void sendProduct(int productId) |
正如你所看到的,@RequestParam
注解的参数类型不一定是字符串。
路径变量类似请求参数,但没有key
部分,只是一个值。例如,在app18b
中,product_view
动作映射到如下URL
:
1 | /product_view/productId |
其中的productId
是表示产品标识符的整数。在Spring MVC
中,productId
被称作路径变量,用来发送一个值到服务器。
下面的viewProduct
方法演示了一个路径变量的使用。
使用路径变量
1 |
|
为了使用路径变量,首先需要在RequestMapping
注解的值属性中添加一个变量,该变量必须放在花括号之间。例如,下面的RequestMapping
注解定义了一个名为id
的路径变量:
1 |
然后,在方法签名中添加一个同名变量
,并加上@PathVariable
注解。上面的中viewProduct
的方法签名。当该方法被调用时,请求URL
的id
值将被复制到路径变量中,并可以在方法中使用。路径变量的类型可以不是字符串。Spring MVC
将尽力转换为非字符串类型。这个Spring MVC
的强大功能会在第19章中详细讨论。
可以在请求映射中使用多个路径变量。例如,下面定义了userId
和orderId
两个路径变量:
1 |
请直接将浏览器输入到如下URL
,来测试viewProduct
方法的路径变量:
http://localhost:8080/app18b/product_view/1
有时,使用路径变量时会遇到一个小问题:在某些情况下,浏览器可能会误解路径变量。考虑下面的URL
:
1 | http://example.com/context/abc |
浏览器会(正确)认为abc
是一个动作。任何静态文件路径的解析,如CSS
文件时,将使用http://example.com/context作为基本路径。这就是说,若服务器发送的网页包含如下`img`元素:
1 | <img src="logo.png"/> |
该浏览器将试图通过http://example.com/context/logo.png
来加载logo.png
。
然而,若一个应用程序被部署为默认上下文(默认上下文路径是一个空字符串),则对于同一个目标的URL
,会是这样的:
1 | http://example.com/abc |
下面是在带有路径变量的URL
:
1 | http://example.com/abc/1 |
在这种情况下,浏览器会认为abc
是上下文,没有动作。
如果在页面中使用<img src="logo. png"/>
,浏览器将试图通过http://example.com/abc/logo.png
来寻找图像,最终它将找不到该图像。
幸运的是,我们有一个简单的解决方案,即通过使用JSTL
标记的URL
(我们已经在第5章中详细讨论了JSTL
)。标签会通过正确解析URL
来修复该问题。例如,app18b
中所有的JSP
页面导入的所有CSS
,从
1 | <style type="text/css">@import url(css/main.css);</style> |
修改为
1 | <style type="text/css"> |
若程序部署为默认上下文,链接标签会将该URL
转换成如下形式:
1 | <style type="text/css">@import url("/css/main.css");</style> |
若程序不在默认上下文中,则它会被转换成如下形式:
1 | <style type="text/css">@import url("/app18b/css/main.css");</style> |