With Spring can I make an optional path variable?
You can't have optional path variables, but you can have two controller methods which call the same service code:
@RequestMapping(value = "/json/{type}", method = RequestMethod.GET)public @ResponseBody TestBean typedTestBean( HttpServletRequest req, @PathVariable String type, @RequestParam("track") String track) { return getTestBean(type);}@RequestMapping(value = "/json", method = RequestMethod.GET)public @ResponseBody TestBean testBean( HttpServletRequest req, @RequestParam("track") String track) { return getTestBean();}
If you are using Spring 4.1 and Java 8 you can use java.util.Optional
which is supported in @RequestParam
, @PathVariable
, @RequestHeader
and @MatrixVariable
in Spring MVC -
@RequestMapping(value = {"/json/{type}", "/json" }, method = RequestMethod.GET)public @ResponseBody TestBean typedTestBean( @PathVariable Optional<String> type, @RequestParam("track") String track) { if (type.isPresent()) { //type.get() will return type value //corresponds to path "/json/{type}" } else { //corresponds to path "/json" } }
It's not well known that you can also inject a Map of the path variables using the @PathVariable annotation. I'm not sure if this feature is available in Spring 3.0 or if it was added later, but here is another way to solve the example:
@RequestMapping(value={ "/json/{type}", "/json" }, method=RequestMethod.GET)public @ResponseBody TestBean typedTestBean( @PathVariable Map<String, String> pathVariables, @RequestParam("track") String track) { if (pathVariables.containsKey("type")) { return new TestBean(pathVariables.get("type")); } else { return new TestBean(); }}