Is it possible to map a nested mapping in spring-mvc to a global path?

Roman Puchkovskiy :

I have something like this:

@RestController
@RequestMapping("/{id}")
public class MyController {
    @GetMapping
    public String get(@PathVariable String id) {
        ...
    }

    @PostMapping
    public String post(@PathVariable String id, Payload payload) {
        ...
    }

    @GetMapping("/deeper/{id}")
    public String getDeeper(@PathVariable String id) {
        ....
    }
}

This gives 3 mappings:

  • /{id} (GET)
  • /{id} (POST)
  • /{id}/deeper/{id} (GET)

I would like the third of them to be just /deeper/{id} (GET).

Is it possible to do this leaving the method in the same controller and leaving that controller-wise @RequestMapping annotation?

Blazerg :

What you request is not possible because you cannot avoid a requestMapping on a class level which makes no sense because being on class level means that you want that path to affect to all your methods.

Keep in mind that a RestController is RESTful and a class level requestMapping is used to avoid adding the same resource path to every method, so it does not make sense to have a method that can't fit in within that resource (you should move it to another controller instead).

This being said, there are a few things you can try:

1 This is not recommended. Use more than one path value on your class @ResquestMapping, in your case:

@RestController
@RequestMapping("/{id}", "/")
public class MyController{...}

You can kinda achieve what you want with this but this is extremely discouraged and a code smell because basically means that all your methods will accept url paths either starting with id or with /, think carefully if you want to use this approach.

2 The recommended one, Remove the @RequestMapping in the class level and just update the path on every method, in your case:

@RestController
public class MyController {
    @GetMapping(value = /{id})
    public String get(@PathVariable String id) {
        ...
    }

    @PostMapping(value = "/{id}")
    public String post(@PathVariable String id, Payload payload) {
        ...
    }

    @GetMapping("/deeper/{id}")
    public String getDeeper(@PathVariable String id) {
       ....
    }
    }

3 also a recommended one Just move the method that does not fit in your controller "general logic" to another controller class which make's sense since that method is not affected by the controller general logic.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=113697&siteId=1