深入 RequestMapping 注解 -- spring MVC 的 URL 映射

2015-11-09 00:12:06   最后更新: 2015-11-09 21:29:32   访问数量:3531




在之前的日志中,我们已经使用过了 RequestMapping 注解,用来指定 Controller 和 action 的URL 映射规则

本篇中,我们深入介绍一下这个注解

 

之前的日志中,我们使用了最简单的配置

@RequestMapping("/")

 

让网站根路径指向我们 Controller 的 action

 

还可以通过下面的方式指定多个 url 或限制访问方式:

@RequestMapping(value={"/index", "/hello"}, method = {RequestMethod.GET})

 

这样,/index 和 /hello 的 GET 请求全部会被导入到指定的 Controller 或 action

 

@Controller public class HomeController { @RequestMapping(value="/hello/{name}", method = {RequestMethod.GET}) public ModelAndView home(@PathVariable(value="name") String name) { String message = "message: Hello World " + name; ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message", message); modelAndView.setViewName("home"); return modelAndView; } }

 

通过 RequestMapping 和 PathVariable 两个注解的结合,让我们可以将URL中占位符所对应变量映射到参数 name 上

通过访问:

http://localhost:8080/hello/techlog

显示出 messgae: Hello World techlog

 

如果你需要默认的访问,可以通过 java 的重载实现:

@Controller public class HomeController { @RequestMapping(value = "/hello/{name}", method = {RequestMethod.GET}) public ModelAndView home(@PathVariable(value = "name") String name) { String message = "message: Hello World " + name; ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message", message); modelAndView.setViewName("home"); return modelAndView; } @RequestMapping(value = "/hello", method = {RequestMethod.GET}) public ModelAndView home() { return home("techlog"); } }

 

这样,在访问 /hello 或者 /hello/ 时,会显示:

 

 

我们还可以通过通配符对URL映射进行配置,通配符有“?”和“*”两个字符。其中“?”表示1个字符,“*”表示匹配多个字符,“**”表示匹配0个或多个路径

 

  • “/helloworld/index?” -- 可以匹配“/helloworld/indexA”、“/helloworld/indexB”,但不能匹配“/helloworld/index”也不能匹配“/helloworld/indexAA”;
  • “/helloworld/index*” -- 可以匹配“/helloworld/index”、“/helloworld/indexA”、“/helloworld/indexAA”但不能匹配“/helloworld/index/A”;
  • “/helloworld/index/*” -- 可以匹配“/helloworld/index/”、“/helloworld/index/A”、“/helloworld/index/AA”、“/helloworld/index/AB”但不能匹配    “/helloworld/index”、“/helloworld/index/A/B”;
  • “/helloworld/index/**” -- 可以匹配“/helloworld/index/”下的多有子路径,比如:“/helloworld/index/A/B/C/D”;

 

如果 URL 同时与多个方法匹配,Spring MVC会按照最长匹配优先原则(即和映射配置中哪个匹配的最多)来匹配

 

通过

@RequestMapping(value="/reg/{name:\\w+}-{age:\\d+}", method = {RequestMethod.GET})

 

可以匹配到

http://localhost:8080/SpringMVCLesson/helloworld/reg/Hanmeimei-18

通过 @PathVariable(value="name") String name, @PathVariable(value="age") Integer age 可以获取到 name 为 Hanmeimei,age 为 18

 

通过 GET 或 POST 参数中是否包含某个参数也可以进行映射的限制

@RequestMapping 的 params 参数实现了这个效果

 

必须包含某参数

将代码换成:

package com.hello; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; /** * Created by techlog on 15/11/5. */ @Controller public class HomeController { @RequestMapping(value = "/hello/{name}", params="example", method = {RequestMethod.GET}) public ModelAndView home(@PathVariable(value = "name") String name) { String message = "message: Hello World " + name; ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("message", message); modelAndView.setViewName("home"); return modelAndView; } @RequestMapping(value = "/hello", method = {RequestMethod.GET}) public ModelAndView home() { return home("techlog"); } }

 

这时再访问 http://localhost:8080/hello/techlog 就会出现:

 

 

因为 RequestMapping 注解中的 params 参数要求 GET 参数中必须要包含 example 参数,所以这个 action 不再能够接受这个 URL

而如果访问 http://localhost:8080/hello/techlog?example

就可以看到久违的 message: Hello World techlog 了

 

限制必须不具有某参数

与上面非常类似,只要将 RequestMapping 注解中的 params="example" 换成 params="!example" 就正好可以变成,只要有 example 参数就不映射到该 action

 

指定映射请求中某参数必须等于某个值

与上面还是很类似,只要将 RequestMapping 注解中的 params="example" 换成 params="example=techlog",那么,只有 example 参数存在并且参数值为 techlog 时才会被映射到该 action

 

指定映射请求中某参数必须不等于某个值

与上面还是很类似,只要将 RequestMapping 注解中的 params="example" 换成 params="example!=techlog",那么,只要 example 参数值为 techlog 时就不会被映射到该 action

 

限制多个参数

上面我们说了一个参数的情况,如果有多个参数都要做类似的限制呢?

参数写成:params={"example1", "example2"} 这样即可

 

有时限制 HEADER 中必须有某个参数或没有某个参数的场景也是非常必要的,比如判断是否是 ajax 请求,或实现 HEADER 中信息的校验工作

实现 HEADER 的各种限制与上面实现 GET、POST 参数的限制是完全类似的,只是将 RequestMapping 注解中的 params 换成 headers 参数即可

 






技术帖      web      mvc      框架      技术分享      java      framework      spring      注解      requestmapping     


京ICP备15018585号