I am trying to upgrade from 5.0.2.RELEASE
to 5.2.7.RELEASE
.
We have some controllers laying around that accepts path variables with semicolon. For the compatibility we need these variables as full string ( aa=123;bb=456
). Previously we had this configuration:
// OLD
@Configuration
public class CustomRequestHandlerMapping extends WebMvcConfigurationSupport {
@Override
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
handlerMapping.setRemoveSemicolonContent(false);
return handlerMapping;
}
}
Now that the method signature of WebMvcConfigurationSupport.requestMappingHandlerMapping()
has changed, we have been looking for alternate solutions. We have tried to extend WebMvcConfigurer
:
// NEW
@Configuration
public class CustomRequestHandlerMapping implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
I have checked and saw that shouldRemoveSemicolonContent()
is in fact true
. But the variable is still cut off. See the controller:
@Controller
@RequestMapping("/accounts/{accountId}/items")
public class ItemController {
@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;
@RequestMapping(value = "/{itemId}", method = RequestMethod.GET)
@ResponseBody
@PreAuthorize("hasAnyRole('Admin', 'User')")
public ItemDTO getItem(
@PathVariable String accountId,
@PathVariable String itemId) {
System.out.println("pathVariable: " + itemId);
System.out.println("shouldRemoveSemicolonContent: " + requestMappingHandlerMapping.getUrlPathHelper().shouldRemoveSemicolonContent());
// ....
}
}
Logs show that:
Request url: "/accounts/123/items/itemid=234;type=bigitem"
pathVariable: itemid=234
shouldRemoveSemicolonContent: false
But I want pathVariable
to be itemid=234;type=bigitem
. What am I missing and what do I need to do to achieve this?
Is there a possible bug?
Edit: If we extend UrlPathHelper
with following values and use it in configurer.setUrlPathHelper(new CustomUrlPathHelper())
, we get the desired result. But it really feels like a hack.
public class CustomUrlPathHelper extends UrlPathHelper {
public DeceivingSemicolonFriendlyUrlPathHelper() {
setRemoveSemicolonContent(false);
}
@Override
public boolean shouldRemoveSemicolonContent() {
return true;
}
}
Comment From: rstoyanchev
I don't know if anything changed but the way to do this is:
@GetMapping("/{itemId}")
public ItemDTO getItem(
@PathVariable String accountId,
@PathVariable String itemId,
@MatrixVariable("type") String type) {
// ...
}
There are several options. Please read https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-matrix-variables.
Comment From: salemdar
I was possible to get the whole path variable as one string before, now it is not. Not at least without the hack I posted in the edit.
Comment From: rstoyanchev
Yes indeed it was possible but it is debatable whether it should have been. Is there a reason why using @MatrxVariable
to access individual values or all as a Map<String, String>
is not adequate?
Comment From: maxhertrampf
I ran into the same problem.
It seems like the bug is just ignored here.
UrlPathHelper.removeSemicolonContent() still exists but does not do what its documentation says. That is clearly a bug. Please either fix the code so that UrlPathHelper.removeSemicolonContent() works again or remove it if you are unable to get it to work again.