How does Spring call these @RequestMappings

2019-08-13 18:34发布

The source code for Spring OAuth2's AuthorizationEndpoint contains two redundant @RequestMapping annotations for the same /oauth/authorize endpoint. One of them specifies the POST method, while the other does not specify a method.

How are the two @RequestMapping annotations interpreted? Does the one that specifies POST exclusively handle all POST /oauth/authorize requests, and does the one that does not specify a method exclusively handle any non-POST requests to /oauth/authorize? Or do both methods overlap, with both methods being called for certain requests?

This is probably a Spring MVC question, though the source code on GitHub uses Spring MVC to define what is Spring OAuth2.

Though the complete source code is available on GitHub at the link that the top of this OP, the headers for the two relevant methods are summarized here as follows:

@RequestMapping(value = "/oauth/authorize")
public ModelAndView authorize(Map<String, Object> model, @RequestParam Map<String, String> parameters,
        SessionStatus sessionStatus, Principal principal) {

  //other stuff
}


@RequestMapping(value = "/oauth/authorize", method = RequestMethod.POST, params = OAuth2Utils.USER_OAUTH_APPROVAL)
public View approveOrDeny(@RequestParam Map<String, String> approvalParameters, Map<String, ?> model,
        SessionStatus sessionStatus, Principal principal) {

  //other stuff
}  

3条回答
混吃等死
2楼-- · 2019-08-13 19:27

How are the two @RequestMapping annotations interpreted?

First of, from http://javatechig.com/java/spring/how-spring-controller-request-mapping-works-in-spring-mvc the default is interpreted as a GET. This is the first distinction. Second the paramaters of both methods are slightly different where method 1 requests a Map<String, String> and the other method Map<String, ?>. So even if both methods were GET, it would still make the distinction on parameter level.

Does the one that specifies POST exclusively handle all POST /oauth/authorize requests, and does the one that does not specify a method exclusively handle any non-POST requests to /oauth/authorize? Or do both methods overlap, with both methods being called for certain requests?

The POST exclusively handles post and nothing else. The other method only handles GET requests. They never overlap. As is java's law and Spring is still bound by the rules of the java overlords =)

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-08-13 19:28

This is already explained in the official documentation: if you provide the values for the method field, they'll be used to narrow the mapping. In other words: Spring MVC will use these hints to find the most precise match for each request.

It's also easy to build a simple proof-of-concept application that demonstrates it in practice:

@RequestMapping("/foo")
@ResponseBody
public String hello() {
  return "hello, default";
}

@RequestMapping(value="/foo", method = RequestMethod.GET)
@ResponseBody
public String helloGet() {
  return "hello, GET";
}

Hitting /foo with a GET request, for instance using Postman, will return "hello, GET". All other supported HTTP methods (POST, PUT, DELETE, etc.) will result in "hello, default".

查看更多
爱情/是我丢掉的垃圾
4楼-- · 2019-08-13 19:30

The default method used by Spring request mapping is GET, so if you specify a request mapping with only @RequestMapping annotation, Spring will route all GET requests for the value of the annotation to this method.

To use any other method you basically need to say the method in the annotation. like @RequestMapping(method = RequestMethod.POST)

So for your example the first method will only handle the GET requests, while the other will handle the POST requests exclusively.

Usually GET in OAuth is used for normal interpretations, while the POST is used to authenticate un-authenticated users using the param passed to the method, which in this case is OAuth2Utils.USER_OAUTH_APPROVAL.

查看更多
登录 后发表回答