-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Description
Ulrich Hecht opened SPR-14646 and commented
@PathVariable
's named-value-method-argument-resolver (PathVariableMethodArgumentResolver
) defines it always as 'required'. In general this makes sense, because if you use @PathVariable
then the path variable is expected to be available in the @RequestMapping
's path value.
But consider the usage of @PathVariable
in @ModelAttribute
annotated methods. Those methods are called for all handlers and not all handlers provide the same path variables.
In my case I have a controller in which 4 of 5 methods provide a specific path variable. In order to avoid duplicate code I collect view variables in @ModelAttribute
-methods.
This is, how it would look like if @PathVariable
had a "required"-attribute:
@RequestMapping("/activity-recordings")
public String getActivityRecordingsAction(/*...*/) { /* This method doesn't have and need path variables */ }
@RequestMapping("/activity-recordings/{purchasePositionNumber}-{index}")
public String getActivityRecordingAction(/*...*/) { /* ... */ }
@PostMapping("/activity-recordings/{purchasePositionNumber}-{index}")
public String updateActivityRecordingAction(/*...*/) { /* ... */ }
@RequestMapping("/activity-recordings/{purchasePositionNumber}-new")
public String newActivityRecordingAction(/*...*/) { /* ... */ }
@PostMapping("/activity-recordings/{purchasePositionNumber}-new")
public String addActivityRecordingAction(/*...*/) { /* ... */ }
@ModelAttribute("activityRecordingPriceLimit")
public Double getActivityRecordingPriceLimit(@PathVariable(name = "purchasePositionNumber", required = "false") String purchasePositionNumber) {
if (purchasePositionNumber == null) return null;
/* Some code calculating the value. I don't want to duplicate it 4 times */
}
/* Lots of other @ModelAttribute methods. If I cannot use them I will need to have a block of multiple "modelMap.put(...)" lines that I need to duplicate in the last 4 request handlers */
At the moment, this code will throw a MissingPathVariableException
when the first handler is called. My workaround is to define the @ModelAttribute
method's argument as Map
:
@ModelAttribute("activityRecordingPriceLimit")
public Double getActivityRecordingPriceLimit(@PathVariable Map<String, String> pathVariableMap) {
/* Look up required path variable in the map */
}
However, I don't like this solution.
Affects: 4.3.2
Issue Links:
- Provide @ModelAttribute(required="false") for session attributes [SPR-11546] #16171 Provide
@ModelAttribute
(required="false") for session attributes - Convenient access to session and request attributes in controller methods [SPR-13894] #18468 Convenient access to session and request attributes in controller methods
- Using PathVariable in ModelAttribute method [SPR-5500] #10172 Using PathVariable in ModelAttribute method