Spring @RequestMapping
来源:互联网 发布:卓奇电脑网络服务中心 编辑:程序博客网 时间:2024/06/09 18:38
http://www.baeldung.com/spring-requestmapping
1. Overview
In this article, we’ll focus on one of the main annotations in Spring MVC –@RequestMapping.
Simply put, the annotation is used to map web requests to Spring Controller methods.
2. @RequestMapping Basics
Let’s start with a simple example – mapping an HTTP request to a method using some basic criteria.
2.1. @RequestMapping – by Path
@RequestMapping
(value =
"/ex/foos"
, method = RequestMethod.GET)
@ResponseBody
public
String getFoosBySimplePath() {
return
"Get some Foos"
;
}
To test out this mapping with a simple curl command, run:
curl -i http:
//localhost
:8080
/spring-rest/ex/foos
2.2. @RequestMapping – the HTTP Method
The HTTP method parameter has no default – so if we don’t specify a value, it’s going to map to any HTTP request.
Here’s a simple example, similar to the previous one – but this time mapped to an HTTP POST request:
@RequestMapping
(value =
"/ex/foos"
, method = POST)
@ResponseBody
public
String postFoos() {
return
"Post some Foos"
;
}
To test the POST via a curl command:
curl -i -X POST http:
//localhost
:8080
/spring-rest/ex/foos
3. RequestMapping and HTTP Headers
3.1. @RequestMapping with the headers Attribute
The mapping can be narrowed even further by specifying a header for the request:
@RequestMapping
(value =
"/ex/foos"
, headers =
"key=val"
, method = GET)
@ResponseBody
public
String getFoosWithHeader() {
return
"Get some Foos with Header"
;
}
And even multiple headers via the header attribute of @RequestMapping:
@RequestMapping
(
value =
"/ex/foos"
,
headers = {
"key1=val1"
,
"key2=val2"
}, method = GET)
@ResponseBody
public
String getFoosWithHeaders() {
return
"Get some Foos with Header"
;
}
To test the operation, we’re going to use the curl header support:
curl -i -H
"key:val"
http:
//localhost
:8080
/spring-rest/ex/foos
Note that for the curl syntax for separating the header key and the header value is a colon, same as in the HTTP spec, while in Spring the equals sign is used.
3.2. @RequestMapping Consumes and Produces
Mapping media types produced by a controller method is worth special attention – we can map a request based on its Accept header via the@RequestMapping headers attribute introduced above:
@RequestMapping
(
value =
"/ex/foos"
,
method = GET,
headers =
"Accept=application/json"
)
@ResponseBody
public
String getFoosAsJsonFromBrowser() {
return
"Get some Foos with Header Old"
;
}
The matching for this way of defining the Accept header is flexible – it uses contains instead of equals, so a request such as the following would still map correctly:
curl -H
"Accept:application/json,text/html"
http:
//localhost
:8080
/spring-rest/ex/foos
Starting with Spring 3.1, the @RequestMapping annotation now has the producesand the consumes attributes, specifically for this purpose:
@RequestMapping
(
value =
"/ex/foos"
,
method = RequestMethod.GET,
produces =
"application/json"
)
@ResponseBody
public
String getFoosAsJsonFromREST() {
return
"Get some Foos with Header New"
;
}
Also, the old type of mapping with the headers attribute will automatically be converted to the new produces mechanism starting with Spring 3.1, so the results will be identical.
This is consumed via curl in the same way:
curl -H
"Accept:application/json"
http:
//localhost
:8080
/spring-rest/ex/foos
Additionally, produces support multiple values as well:
@RequestMapping
(
value =
"/ex/foos"
,
method = GET,
produces = {
"application/json"
,
"application/xml"
}
)
Keep in mind that these – the old way and the new way of specifying the acceptheader – are basically the same mapping, so Spring won’t allow them together – having both these methods active would result in:
Caused by: java.lang.IllegalStateException: Ambiguous mapping found.
Cannot map
'fooController'
bean method
java.lang.String
org.baeldung.spring.web.controller
.FooController.getFoosAsJsonFromREST()
to
{ [
/ex/foos
],
methods=[GET],params=[],headers=[],
consumes=[],produces=[application
/json
],custom=[]
}:
There is already
'fooController'
bean method
java.lang.String
org.baeldung.spring.web.controller
.FooController.getFoosAsJsonFromBrowser()
mapped.
A final note on the new produces and consumes mechanism – these behave differently from most other annotations: when specified at the type level, the method level annotations do not complement but override the type level information.
And of course, if you want to dig deeper into building a REST API with Spring –check out the new REST with Spring course.
4. RequestMapping with Path Variables
Parts of the mapping URI can be bound to variables via the @PathVariableannotation.
4.1. Single @PathVariable
A simple example with a single path variable:
@RequestMapping
(value =
"/ex/foos/{id}"
, method = GET)
@ResponseBody
public
String getFoosBySimplePathWithPathVariable(
@PathVariable
(
"id"
)
long
id) {
return
"Get a specific Foo with id="
+ id;
}
This can be tested with curl:
curl http:
//localhost
:8080
/spring-rest/ex/foos/1
If the name of the method argument matches the name of the path variable exactly, then this can be simplified by using @PathVariable with no value:
@RequestMapping
(value =
"/ex/foos/{id}"
, method = GET)
@ResponseBody
public
String getFoosBySimplePathWithPathVariable(
@PathVariable
String id) {
return
"Get a specific Foo with id="
+ id;
}
Note that @PathVariable benefits from automatic type conversion, so we could have also declared the id as:
@PathVariable
long
id
4.2. Multiple @PathVariable
More complex URI may need to map multiple parts of the URI to multiple values:
@RequestMapping
(value =
"/ex/foos/{fooid}/bar/{barid}"
, method = GET)
@ResponseBody
public
String getFoosBySimplePathWithPathVariables
(
@PathVariable
long
fooid,
@PathVariable
long
barid) {
return
"Get a specific Bar with id="
+ barid +
" from a Foo with id="
+ fooid;
}
This is easily tested with a curl in the same way:
curl http:
//localhost
:8080
/spring-rest/ex/foos/1/bar/2
4.3. @PathVariable with RegEx
Regular expressions can also be used when mapping the @PathVariable; for example, we will restrict the mapping to only accept numerical values for the id:
@RequestMapping(value =
"/ex/bars/{numericId:[\\d]+}"
, method = GET)
@ResponseBody
public
String
getBarsBySimplePathWithPathVariable(
@PathVariable long numericId) {
return
"Get a specific Bar with id="
+ numericId;
}
This will mean that the following URIs will match:
http:
//localhost
:8080
/spring-rest/ex/bars/1
But this will not:
http:
//localhost
:8080
/spring-rest/ex/bars/abc
Further reading:
Serve Static Resources with Spring
How to map and handle static resources with Spring MVC - use the simple configuration, then the 3.1 more flexible one and finally the new 4.1 resource resolvers.
Read more →
Getting Started with Forms in Spring MVC
Learn how to work with forms using Spring MVC - mapping a basic entity, submit, displaying errors.
Read more →
Http Message Converters with the Spring Framework
How to configure HttpMessageConverters for a REST API with Spring, and how to use these converters with the RestTemplate.
Read more →
5. RequestMapping with Request Parameters
@RequestMapping allows easy mapping of URL parameters with the@RequestParam annotation.
We are now mapping a request to a URI such as:
http:
//localhost
:8080
/spring-rest/ex/bars
?
id
=100
@RequestMapping
(value =
"/ex/bars"
, method = GET)
@ResponseBody
public
String getBarBySimplePathWithRequestParam(
@RequestParam
(
"id"
)
long
id) {
return
"Get a specific Bar with id="
+ id;
}
We are then extracting the value of the id parameter using the@RequestParam(“id”) annotation in the controller method signature.
The send a request with the id parameter, we’ll use the parameter support incurl:
curl -i -d
id
=100 http:
//localhost
:8080
/spring-rest/ex/bars
In this example, the parameter was bound directly without having been declared first.
For more advanced scenarios, @RequestMapping can optionally define the parameters – as yet another way of narrowing the request mapping:
@RequestMapping
(value =
"/ex/bars"
, params =
"id"
, method = GET)
@ResponseBody
public
String getBarBySimplePathWithExplicitRequestParam(
@RequestParam
(
"id"
)
long
id) {
return
"Get a specific Bar with id="
+ id;
}
Even more flexible mappings are allowed – multiple params values can be set, and not all of them have to be used:
@RequestMapping
(
value =
"/ex/bars"
,
params = {
"id"
,
"second"
},
method = GET)
@ResponseBody
public
String getBarBySimplePathWithExplicitRequestParams(
@RequestParam
(
"id"
)
long
id) {
return
"Narrow Get a specific Bar with id="
+ id;
}
And of course, a request to a URI such as:
http:
//localhost
:8080
/spring-rest/ex/bars
?
id
=100&second=something
Will always be mapped to the best match – which is the narrower match, which defines both the id and the second parameter.
6. RequestMapping Corner Cases
6.1. @RequestMapping – multiple paths mapped to the same controller method
Although a single @RequestMapping path value is usually used for a single controller method, this is just good practice, not a hard and fast rule – there are some cases where mapping multiple requests to the same method may be necessary. For that case, the value attribute of @RequestMapping does accept multiple mappings, not just a single one:
@RequestMapping
(
value = {
"/ex/advanced/bars"
,
"/ex/advanced/foos"
},
method = GET)
@ResponseBody
public
String getFoosOrBarsByPath() {
return
"Advanced - Get some Foos or Bars"
;
}
Now, both of these curl commands should hit the same method:
curl -i http:
//localhost
:8080
/spring-rest/ex/advanced/foos
curl -i http:
//localhost
:8080
/spring-rest/ex/advanced/bars
6.2. @RequestMapping – multiple HTTP request methods to the same controller method
Multiple requests using different HTTP verbs can be mapped to the same controller method:
@RequestMapping
(
value =
"/ex/foos/multiple"
,
method = { RequestMethod.PUT, RequestMethod.POST }
)
@ResponseBody
public
String putAndPostFoos() {
return
"Advanced - PUT and POST within single method"
;
}
With curl, both of these will now hit the same method:
curl -i -X POST http:
//localhost
:8080
/spring-rest/ex/foos/multiple
curl -i -X PUT http:
//localhost
:8080
/spring-rest/ex/foos/multiple
6.3. @RequestMapping – a fallback for all requests
To implement a simple fallback for all requests using a particular HTTP method – for example, for a GET:
@RequestMapping
(value =
"*"
, method = RequestMethod.GET)
@ResponseBody
public
String getFallback() {
return
"Fallback for GET Requests"
;
}
Or even for all requests:
@RequestMapping
(
value =
"*"
,
method = { RequestMethod.GET, RequestMethod.POST ... })
@ResponseBody
public
String allFallback() {
return
"Fallback for All Requests"
;
}
7. New Request Mapping Shortcuts
Spring Framework 4.3 introduced a few new HTTP mapping annotations, all based on @RequestMapping:
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
These new annotations can improve the readability and reduce the verbosity of the code. Let us look at these new annotations in action by creating a RESTful API that supports CRUD operations:
@GetMapping
(
"/{id}"
)
public
ResponseEntity<?> getBazz(
@PathVariable
String id){
return
new
ResponseEntity<>(
new
Bazz(id,
"Bazz"
+id), HttpStatus.OK);
}
@PostMapping
public
ResponseEntity<?> newBazz(
@RequestParam
(
"name"
) String name){
return
new
ResponseEntity<>(
new
Bazz(
"5"
, name), HttpStatus.OK);
}
@PutMapping
(
"/{id}"
)
public
ResponseEntity<?> updateBazz(
@PathVariable
String id,
@RequestParam
(
"name"
) String name) {
return
new
ResponseEntity<>(
new
Bazz(id, name), HttpStatus.OK);
}
@DeleteMapping
(
"/{id}"
)
public
ResponseEntity<?> deleteBazz(
@PathVariable
String id){
return
new
ResponseEntity<>(
new
Bazz(id), HttpStatus.OK);
}
A deep dive into these can be found here.
8. Spring Configuration
The Spring MVC Configuration is simple enough – considering that ourFooController is defined in the following package:
package
org.baeldung.spring.web.controller;
@Controller
public
class
FooController { ... }
We simply need a @Configuration class to enable the full MVC support and configure classpath scanning for the controller:
@Configuration
@EnableWebMvc
@ComponentScan
({
"org.baeldung.spring.web.controller"
})
public
class
MvcConfig {
//
}
9. Conclusion
This article focus on the @RequestMapping annotation in Spring – discussing a simple use case, the mapping of HTTP headers, binding parts of the URI with@PathVariable and working with URI parameters and the @RequestParamannotation.
If you’d like to learn how to use another core annotation in Spring MVC, you can explore the @ModelAttribute annotation here.
The full code from the article is available on Github. This is a Maven project, so it should be easy to import and run as it is.
- Pham Vu Minh Hoang
- Eugen Paraschiv
- Cody Burleson
- Eugen Paraschiv
- Lajos Incze
- Jonathan Gibran Hernandez Antu
- grooha
- Eugen Paraschiv
- grooha
- Manish Sahni
- Eugen Paraschiv
- Tobi Bod
- Eugen Paraschiv
- Sanjay Patel
- Eugen Paraschiv
- Rubén Pahíno Verdugo
- Eugen Paraschiv
- venkat
- Eugen Paraschiv
- Kisna
- Eugen Paraschiv
- Kisna
- Eugen Paraschiv
- Grant Lay
- Eugen Paraschiv
- Grant Lay
- Scott Stanlick
- Eugen Paraschiv卓奇电脑网络服务中心原创粉丝点击热门IT博客js while sleep软件测试程序连接不上魔法学园网络英文软件界面翻译手机网络电视直播下载京东 省市区数据库mysql查询最小时间获取百度指数的源数据幸福 哲学书 知乎梅原大吾背水逆转 知乎国防科大 知乎植丽素怎么样知乎女生学javaseo原创怎么写c语言单词大连房价 知乎用excel预测数据淘一兔淘宝号查询网络加速浏览器大数据部门职责热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 周健紫砂壶 周健医生 周天李若雪免 周全 周全的意思 护你周全 周全保险 周全艺简介 周全紫砂 考虑周全 李周全 怀孕1一40周全过程图 周全的近义词 上海新科周全 护你一生周全的原句 我护你周全的唯美句子 形容想得周全的成语 让我护你一世周全 德胜门医院皮肤科周全 欧莱雅男士控油周全理肤露 让阳光替我护你的周全 周工 姬旦 周兰 周兴哲 周兴 周兴才让 周兴驰 怎么了周兴哲 周兴哲为什么不红 周兴哲你好不好数字简谱 周兵 周兵有被判刑吗 周冰 周冲 周凤国书法 周凯 时代周刊 财新周刊 新周刊 壹周刊