Multiple request assignment with path variables

@RequestMapping(value = {"/abcd", "/employees/{value}/{id}"}) public String getEmployees( @PathVariable(value = "value") String val, @PathVariable(value = "id") String id, @RequestParam(value = "param", required = false) String value) { // ******** } 

For one URL, I pass a path variable, but for one I don’t. But I want both URLs to fall into the same API. How can i achieve this?

+11
source share
5 answers

You can now have optional path variables through Java 8 support. Optional . A minimum version of Spring 4.x is required.

 @RequestMapping({"/abcd", "/employees/{value}/{id}"}) public String getEmployees( @PathVariable("value") Optional<String> val, @PathVariable("id") Optional<String> id, @RequestParam("param") Optional<String> value ) { // ******** } 

Note: this does not work with optional primitives ( OptionalInt , etc.).

+8
source

We cannot have optional path variables , you can have two controller methods that can call the same service.

First method

 @RequestMapping("/abcd") public String getEmployees(@RequestParam(value="param", required=false)String value){} 

Second method

 @RequestMapping("/employees/{value}/{id}") public String getEmployees(@PathVariable(value="value") String val, @PathVariable(value="id") String id, @RequestParam(value="param", required=false) String value){} 

For @RequestParam we can use

@RequestParam(value="somevalue",required=false)

for optional params , not pathVariable

+5
source

Just found a way to do this without using multiple methods.

First, create a simple class to store the path variables:

 public class EmployeesRequest { private String value; private String id; public String getValue() { return this.value; } public void setValue(String value) { this.value = value; } public String getId() { return this.id; } public void setId(String id) { this.id = id; } } 

Then define your controller method as follows:

 @RequestMapping(value={ "/abcd", "/employees/{value}/{id}" }) public String getEmployees(@RequestParam(value="param", required=false) String param, EmployeesRequest request) { if (request.getValue() != null) { // do something } else { // do something else } } 

Spring automatically maps any path variables available to the EmployeesRequest class. Spring will also do this for any query parameters, so you can simplify things by adding a query parameter to EmployeesRequest :

 public class EmployeesRequest { private String value; private String id; private String param; public String getValue() { return this.value; } public void setValue(String value) { this.value = value; } public String getId() { return this.id; } public void setId(String id) { this.id = id; } public String getParam() { return this.param; } public void setParam(String param) { this.param = param; } } 

And finally:

 @RequestMapping(value={ "/abcd", "/employees/{value}/{id}" }) public String getEmployees(EmployeesRequest request) { if (request.getValue() != null) { // do something } else { // do something else } } 

An additional advantage of this solution is that now you can support both variables and query parameters. The meaning of all of them would be correct:

  • /abcd
  • /abcd?param=123
  • /abcd?value=123&id=456¶m=789
  • /employees/123/456
  • /employees/123/456?param=123
+5
source

You cannot have optional PathVariables in Spring Mvc. Just create 2 methods for two Request mappings .

 @RequestMapping("/abcd") public String getEmployees(@RequestParam(value="param", required=false)String value){} @RequestMapping("/employees/{value}/{id}") public String getEmployees(@PathVariable(value="value") String val,PathVariable(value="id")String id,@RequestParam(value="param", required=false)String value){} 
+1
source

I had a similar problem and I found this solution:

 @GetMapping(value = {"/clients/page", "/clients/page/{page}"}) public Page<Client> index(@PathVariable Optional<Integer> page) { PageRequest pageRequest = page.map(integer -> PageRequest.of(integer, 4)) .orElseGet(() -> PageRequest.of(0, 4)); return clientService.showAll(pageRequest); } 

Intellij helped me get such a compact result. Although Intellij throw this message:

'' Reports any use of java.util.Optional, java.util.OptionalDouble, java.util.OptionalInt, java.util.OptionalLong or com.google.common.base.Optional as a type for a field or parameter. Optional was designed to provide a limited mechanism for returning library method types, where there should have been a clear way to represent "no result." Using a field of type java.util.Optional is also problematic if the class should be Serializable and java.util.Optional not. ''

To be honest, I'm new to this business and don't quite understand what the IDE tells me. If someone with much experience can help clarify this message, it would be great.

0
source

All Articles