How to read a variable number of @RequestMapping paths from properties

how to pass multiple path variables in url
spring path variable special characters
spring @requestmapping regex
spring optional path variable
path variable in post method
requestmapping produces
multiple path variables spring
path variable in spring boot

In Spring (Boot) I can externalize annotation values to application / environment properties using the ${...} syntax:

@RequestMapping("${some.path.property}")

I can also map a controller to more than one path:

@RequestMapping("/one", "/two")

How do I combine the two? I would like to define a list of paths in my properties, either as comma-separated /one, /two or (preferably) as a list in my application.yaml:

some.path.property:
    - /one
    - /two

But how can I interpolate either kind of list into the annotation?

@RequestMapping(???)

Edit: I couldn't figure out how to read the entire list from YAML (maybe because it's turned into separate properties some.path.property[0], some.path.property[1]... at YAML parse time?)

For the simpler case of a single CSV property, say:

some.csv.property: /one, /two

I can use a property substitution: "${some.csv.property}" or an explicit SpEL split: "#{'${some.csv.property}'.split('[, ]+')}" to convert it into an array, but in both cases it only work for @Value annotations. If I try it on @RequestMapping, I always end up with a single path.


Edit2: I can do this, where -- is just a random string that is not a valid path, but it's super ugly:

@RequestMapping(
    "${some.path.property[0]:--}",
    "${some.path.property[1]:--}",
    "${some.path.property[2]:--}",
    "${some.path.property[3]:--}",
    "${some.path.property[4]:--}",
    "${some.path.property[5]:--}",
    "${some.path.property[6]:--}",
    "${some.path.property[7]:--}",
    "${some.path.property[8]:--}",
    "${some.path.property[9]:--}"
)

Have You tried this?:

some:
  path:
    property: /one, /two

And then

@RequestMapping("${some.path.property}") 

Based on this answer https://stackoverflow.com/a/41462567/7425783 it should work fine

How to read a variable number of #RequestMapping paths from , In Spring (Boot) I can externalize annotation values to application / environment properties using the ${} syntax: #RequestMapping("${some.path.property}") I� @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.

If you have a yaml property file (don't repeat your self principle :) ), you can do it like so:

some:
  path:
    property:
      one: /path1
      two: /path2

If you're using @GetMapping ( or @RequestMapping ) you can do it like this in your controller :

@GetMapping(value={"${some.path.property.one}", "${some.path.property.two}"})

And here is the log

 Mapped "{[/path1 || /path2],methods=[GET]}" onto public java.util.List<com.zero.SimpleController> com.zero.SimpleController.hello()

Spring Boot @PathVariable, Spring Boot @PathVariable tutorial shows how to read an URL template < maven.compiler.target>11</maven.compiler.target> </properties> public class MyController { @RequestMapping(path="/{name}/{age}") public� The @RequestMapping annotation is a versatile tool. See it used to configure traditional web page requests as well as RESTFul web services in Spring MVC.

You can try create HandlerMapping to add urls, here is just an example to use SimpleUrlHandlerMapping

@RestController
public class WelcomeController {

    public String ping() {
        return "pong";
    }
}

@SpringBootApplication
@Slf4j
@RestController
public class StackOverflowApplication {

    @Autowired
    WelcomeController welcomeController;

    @Value("${paths}")
    List<String> paths;


    public static void main(String[] args) {
        SpringApplication.run(StackOverflowApplication.class, args);
    }



    @Bean
    public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
        SimpleUrlHandlerMapping simpleUrlHandlerMapping = new SimpleUrlHandlerMapping();
        Map<String, Object> map = new HashMap<>();
        final Method getUser = ReflectionUtils.findMethod(WelcomeController.class, "ping");
        final HandlerMethod handlerMethod = new HandlerMethod(welcomeController, getUser);
        for (String path : paths) {
            map.put(path, handlerMethod);
        }
        simpleUrlHandlerMapping.setUrlMap(map);
        simpleUrlHandlerMapping.setOrder(Ordered.HIGHEST_PRECEDENCE);

        return simpleUrlHandlerMapping;
    }


}

yml file

paths: ping, ping1, ping2, ping3

Here is the code in github

Spring MVC - @PathVariable Examples, A method can have any number of @PathVariable annotations: output: java. lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path Template URI can also be specified in @RequestMapping at controller class level. http://localhost:8080/spring-mvc-path-variable/users/234 If you will look at the source code of RequestMapping annotation, you will see that all of it’s variables are arrays. We can create String array for the URI mappings for the handler method. @RequestMapping with HTTP Method: Sometimes we want to perform different operations based on the HTTP method used, even though request URI remains same

Spring @RequestMapping, Spring @RequestMapping - Basic Example, @RequestParam, now has the produces and the consumes attributes, specifically for this purpose: @ RequestMapping – Multiple Paths Mapped to the Same Controller Method A careful reading of the error message points to the fact that Spring is unable� 5. RequestMapping Corner Cases 5.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.

Spring @RequestMapping @RequestParam @PathVariable Example, Spring MVC @RequestMapping Annotation Example with Controller, Methods, Headers, Params, @RequestParam, @PathVariable @RequestMapping with Multiple URI: We can use a single method for handling multiple shell script springTest.sh to invoke all the above methods and print their output. The classes or methods that are annotated with @RequestMapping will be scanned and registered as the URI mappings for that specific class or method. Any future web requests will be redirected to that class or method. This annotation is part of Spring MVC module. Also Read: Spring Boot Tutorials; Spring Data JPA Tutorials

How to read values from application.properties file in Spring Boot , How to read values from application.properties file in Spring Boot In Spring Boot, we can use properties files, YAML files, environment variables, RequestMapping; JavaScript, C#, PHP and many more popular programming languages. @RequestMapping is one of the most common annotation used in Spring Web applications. This annotation maps HTTP requests to handler methods of MVC and REST controllers. In this post, you’ll see how versatile the @RequestMapping annotation is when used to map Spring MVC controller methods.

Comments
  • Yes, I tried it (with and without a space after the comma) and it doesn't work. I'm on the latest Spring Boot 2.1.2
  • To expand, I tried setting an array from a CSV property and it works: @Value("${some.csv.property}") String[] myValue; but when I use the same property for an annotation itself, it is not split on commas, but is just taken as a single string: @RequestMapping("${some.csv.property}") sets a single path with value "/one, /two"
  • I figured out how to use SpEL to explicitly split a string into an array: "#{'${some.csv.property}'.split('[, ]+')}" but again, it works for @Value but not for @RequestMapping
  • Yes, I have application.yaml. I can do that, but then I cannot change the number of paths from the config file
  • I think @Michal solution is more suited for your case, the only issue is that you can't inherit path from super class ( if you have an AbstractController with RequestMapping("/api/v1" ) and your SimpleController extends AbstractController), in this case either you set the full path in your property file or prefix/suffix the value from property file with another part of the complete path
  • In my case don't have the issue of inheriting the path from a super class. But @Michal's solution is simply not working. I can use it to initialize an array: @Value("${some.csv.property}") String[] myValue; but not an annotation value itself. In that case the string is not split into an array.
  • Yes, that's certainly an option. A bit heavy handed though.