Spring MVC 映射请求
来源:原创 发布时间:2015-03-21 归档:springmvc
开发环境 :
JDK 7
Maven 3
Tomcat 7
Spring 4.1.5
Eclipse Luna
@RequestMapping
@RequestMapping 注解用于将请求映射到控制器的某个具体的处理方法上。它可以标注在方法级别上, 也可以标注在类级别上, 标注在类级别上不是必须的。
示例代码片段 1
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(method = GET) public String list() { return "class-level-mapping/list"; } @RequestMapping(value = "/pathname", method = GET) public String mappedByPathname(Model model) { model.addAttribute("message", "mapped by /pathname"); return "class-level-mapping/result"; } }@RequestMapping.value
value 用于映射请求的 url 表达式, 以缩小映射的范围。
参数类型 String[], 如 value = "/pathname", value = {"/", "/pathname"} ( 多个值时, 访问任意一个都是等效, 如 / 和 /pathname )
当注解只有一个参数 value 时, value 可以省略。
@RequestMapping("/class-level-mapping") 完整的写法是 @RequestMapping(value = "/class-level-mapping")。
@RequestMapping.method
参数类型 String[], 如 value = "/pathname", value = {"/", "/pathname"} ( 多个值时, 访问任意一个都是等效, 如 / 和 /pathname )
当注解只有一个参数 value 时, value 可以省略。
@RequestMapping("/class-level-mapping") 完整的写法是 @RequestMapping(value = "/class-level-mapping")。
method 用于映射请求的 HTTP Request Method 类型, 以缩小映射的范围。
参数类型 RequestMethod[], 如 method = GET, method = {GET, POST}
若缺省, 默认是映射所有的 HTTP Request Methods 类型 ( GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE )。
参数类型 RequestMethod[], 如 method = GET, method = {GET, POST}
若缺省, 默认是映射所有的 HTTP Request Methods 类型 ( GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE )。
@RequestMapping 注解标注在类级别上, 表明当前控制器的处理方法映射的路径均相对于 /class-level-mapping。
GET /class-level-mapping --> list
GET /class-level-mapping/pathname --> mappedByPathname
示例代码片段 2
GET /class-level-mapping --> list
GET /class-level-mapping/pathname --> mappedByPathname
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(value = "/parameter", method = GET, params = "param") public String mappedByParameter(Model model, String param) { model.addAttribute("message", "the param is " + param); return "class-level-mapping/result"; } @RequestMapping(value = "/parameter", method = GET, params = "!param") public String mappedByParameterNegation(Model model) { model.addAttribute("message", "mapped by /parameter, not supposed param"); return "class-level-mapping/result"; } @RequestMapping(value = "/argument", method = GET, params = "param=1") public String mappedByParameterEquals(Model model) { model.addAttribute("message", "mapped by /argument, only param = 1"); return "class-level-mapping/result"; } @RequestMapping(value = "/argument", method = GET, params = "param!=1") public String mappedByParameterNotEquals(Model model) { model.addAttribute("message", "mapped by /argument, only param != 1"); return "class-level-mapping/result"; } }@RequestMapping.params
params 用于映射请求的参数, 以缩小映射的范围。
参数类型 String[], 如 params = "param", params = "!param", params = "param=1", params = "param!=1", params = {"p1", "p2"}
params = "param", 表明处理方法只处理 url 中含 param 参数的请求。
params = "!param", 表明处理方法只处理 url 中不含 param 参数的请求。
params = "param=1", 表明处理方法只处理 url 中含 param=1 参数的请求。
params = "param!=1", 表明处理方法只处理 url 中不含 param=1 参数的请求。
GET /class-level-mapping/parameter --> mappedByParameterNegation
GET /class-level-mapping/parameter?p=s --> mappedByParameterNegation
GET /class-level-mapping/parameter?param --> mappedByParameter
GET /class-level-mapping/parameter?param=s --> mappedByParameter
GET /class-level-mapping/argument --> mappedByParameterNotEquals
GET /class-level-mapping/argument?param=1 --> mappedByParameterEquals
GET /class-level-mapping/argument?param=2 --> mappedByParameterNotEquals
示例代码片段 3
参数类型 String[], 如 params = "param", params = "!param", params = "param=1", params = "param!=1", params = {"p1", "p2"}
params = "param", 表明处理方法只处理 url 中含 param 参数的请求。
params = "!param", 表明处理方法只处理 url 中不含 param 参数的请求。
params = "param=1", 表明处理方法只处理 url 中含 param=1 参数的请求。
params = "param!=1", 表明处理方法只处理 url 中不含 param=1 参数的请求。
GET /class-level-mapping/parameter --> mappedByParameterNegation
GET /class-level-mapping/parameter?p=s --> mappedByParameterNegation
GET /class-level-mapping/parameter?param --> mappedByParameter
GET /class-level-mapping/parameter?param=s --> mappedByParameter
GET /class-level-mapping/argument --> mappedByParameterNotEquals
GET /class-level-mapping/argument?param=1 --> mappedByParameterEquals
GET /class-level-mapping/argument?param=2 --> mappedByParameterNotEquals
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(value = "/header", method = POST, headers = "content-type=application/*") public String mappedByHeader(Model model) { model.addAttribute("message", "mapped by /header + presence of header"); return "class-level-mapping/result"; } @RequestMapping(value = "/header", headers = "!content-type") public String mappedByHeaderNegation(Model model) { model.addAttribute("message", "mapped by /header + absence of header"); return "class-level-mapping/result"; } }@RequestMapping.headers
headers 用于映射请求的 Request Headers 内容, 以缩小映射的范围。
参数类型 String[], 如 headers = "content-type=text/html", headers = "!content-type", headers = "content-type!=text/*"
GET /class-level-mapping/header --> mappedByHeaderNegation
POST /class-level-mapping/header --> mappedByHeader
示例代码片段 4
参数类型 String[], 如 headers = "content-type=text/html", headers = "!content-type", headers = "content-type!=text/*"
GET /class-level-mapping/header --> mappedByHeaderNegation
POST /class-level-mapping/header --> mappedByHeader
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(value = "/produce", method = GET, produces = "application/json") public @ResponseBody Person mappedByProduce() { return new Person(1001, "Lychie Fan"); } public static class Person { private int id; private String name; public Person() { } public Person(int id, String name) { this.id = id; this.name = name; } // ignore getters and setters @Override public String toString() { return "[ id : " + id + ", name : " + name + " ]"; } } }@RequestMapping.produces ( 生产者 )
produces 表明处理方法产生的媒体类型, 再由请求的 Request Headers 中的 Accept 来进行匹配, 以缩小映射的范围。
参数类型 String[], 如 produces = MediaType.APPLICATION_JSON_VALUE, produces = {"text/plain", "application/*"}
produces = "application/*", 若 Request Headers 中的 Accept 含 application/xml, application/json 等都可匹配。
@ResponseBody
参数类型 String[], 如 produces = MediaType.APPLICATION_JSON_VALUE, produces = {"text/plain", "application/*"}
produces = "application/*", 若 Request Headers 中的 Accept 含 application/xml, application/json 等都可匹配。
表明处理方法的返回值绑定到 Response Body。使用时将跳过视图解析部分, 返回如 json, xml 等格式的数据。
引入依赖
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.4.1</version> </dependency>
GET /class-level-mapping/produce --> mappedByProduce --> {"id":1001,"name":"Lychie Fan"}
示例代码片段 5
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(value = "/consume", method = POST, consumes = "application/json") public String mappedByConsume(@RequestBody Person person) { System.out.println("person = " + person); return "class-level-mapping/result"; } }@RequestMapping.consumes ( 消费者 )
consumes 表明处理方法消费的媒体类型, 由请求的 Request Headers 中的 Content-Type 来进行匹配类型, 以缩小映射的范围。
参数类型 String[], 如 consumes = "application/*", consumes = {"text/plain", "application/*"}
@RequestBody
参数类型 String[], 如 consumes = "application/*", consumes = {"text/plain", "application/*"}
表明处理方法的参数是绑定到 Request Body。使用时从 Request Body 中读取绑定的数据。
<body> <h3> <p><a href="javascript:;" class="consume">class-level-mapping/consume</a></p> </h3> <textarea style="display:none">{"id":1001,"name":"Lychie Fan"}</textarea> <script type="text/javascript"> $(function(){ $(".consume").click(function(){ $.ajax({ type : "post", url : "class-level-mapping/consume", data : $("textarea").val(), contentType : "application/json", success : function(){ alert("well, now you can see the execution result on the console"); } }); }); }); </script> </body>
POST /class-level-mapping/consume --> mappedByConsume --> person = [ id : 1001, name : Lychie Fan ]
示例代码片段 6
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(value = "/foo/{bar}", method = GET) public String mappedByUriTemplate(Model model, @PathVariable String bar){ model.addAttribute("message", bar); return "class-level-mapping/result"; } @RequestMapping(value = "/food/{name}/{kind}", method = GET) public String mappedByUriTemplate(Model model, @PathVariable("name") String foodName, @PathVariable String kind) { model.addAttribute("message", foodName + ", " + kind); return "class-level-mapping/result"; } }@PathVariable
{bar} 是变量的写法, /foo/{bar} 是一个 URI 模板, bar 部分是可变的, @PathVariable 注解用于将处理方法的参数绑定到这个 URI 模板中。
如请求 /foo/foobar, 处理方法 mappedByUriTemplate 执行时, foobar 将作为处理方法参数 bar 的值被设置进去。
若处理方法的参数绑定的变量与模板中的变量名不一致, 则需要在处理方法中显式的指明参数绑定的是模板中的哪个变量, 如上述代码所示。
GET /class-level-mapping/foo/foobar --> mappedByUriTemplate(Model, String) --> foobar
GET /class-level-mapping/food/fruit/banana --> mappedByUriTemplate(Model, String, String) --> fruit, banana
示例代码片段 7
如请求 /foo/foobar, 处理方法 mappedByUriTemplate 执行时, foobar 将作为处理方法参数 bar 的值被设置进去。
若处理方法的参数绑定的变量与模板中的变量名不一致, 则需要在处理方法中显式的指明参数绑定的是模板中的哪个变量, 如上述代码所示。
GET /class-level-mapping/foo/foobar --> mappedByUriTemplate(Model, String) --> foobar
GET /class-level-mapping/food/fruit/banana --> mappedByUriTemplate(Model, String, String) --> fruit, banana
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(value = "/{filename:[a-z-_]+}{extension:\\.[a-z]+}", method = GET) public String mappedByRegular(Model model, @PathVariable String filename, @PathVariable String extension) { model.addAttribute("message", filename + extension); return "class-level-mapping/result"; } }正则表达式的运用
{filename:[a-z-_]+} 其中, filename 是变量名, [a-z-_]+ 是正则表达式的值。
GET /class-level-mapping/spring-mvc-mapping.zip --> mappedByRegular --> spring-mvc-mapping.zip
示例代码片段 8
GET /class-level-mapping/spring-mvc-mapping.zip --> mappedByRegular --> spring-mvc-mapping.zip
@Controller @RequestMapping("/class-level-mapping") public class ClassLevelMappingController { @RequestMapping(value = "/pathname", method = GET) public String mappedByPathname(Model model) { model.addAttribute("message", "mapped by /pathname"); return "class-level-mapping/result"; } @RequestMapping(value = "/pathname/*", method = GET) public String mappedByPathnamePattern(Model model) { model.addAttribute("message", "mapped by /pathname/*"); return "class-level-mapping/result"; } @RequestMapping(value = "/pathname/*.html", method = GET) public String mappedByPathnameExtension(Model model) { model.addAttribute("message", "mapped by /pathname/*.html"); return "class-level-mapping/result"; } }
/pathname/* 模式, * 匹配 0 个至多个字符, 不含路径符。
GET /class-level-mapping/pathname --> mappedByPathname
GET /class-level-mapping/pathname/public --> mappedByPathnamePattern
GET /class-level-mapping/pathname/sample.html --> mappedByPathnameExtension
GET /class-level-mapping/pathname --> mappedByPathname
GET /class-level-mapping/pathname/public --> mappedByPathnamePattern
GET /class-level-mapping/pathname/sample.html --> mappedByPathnameExtension
示例代码下载