I need to handle requests as following:
www.example.com/show/abcd/efg?name=alex&family=moore (does not work)
www.example.com/show/abcdefg?name=alex&
You could encode slashes on UI with %2f: http://www.example.com/show/abcd%2fefg?name=alex&family=moore
.
Now you should configure Spring to handle slashes. Simple config example:
@RestController
public class TestController {
@GetMapping("{testId:.+}")
public String test(@PathVariable String testId) {
return testId;
}
@GetMapping("{testId:.+}/test/{messageId}")
public String test2(@PathVariable String testId, @PathVariable String messageId) {
return testId + " " + messageId;
}
//Only if using Spring Security
@Configuration
public static class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
DefaultHttpFirewall firewall = new DefaultHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
@Override
public void configure(WebSecurity web) throws Exception {
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
}
}
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public static class SpringMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setUrlDecode(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
}
Try escaping forward slash.
Regex: /^[ A-Za-z0-9_@.\/#&+-]*$/
Another way I do is:
@RequestMapping(value = "test_handler/**", method = RequestMethod.GET)
...and your test handler can be "/test_hanlder/a/b/c" and you will get the whole value using following mechanism.
requestedUri = (String)
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
The first one is not working because you are trying to handle an entirely new URL which is not actually mapped your controller.
www.example.com/show/abcd/efg?name=alex&family=moore (does not work)
The correct mapping for the above URL could be like the below code.
@RequestMapping(value = {"/{mystring:.*}" , "/{mystring:.*}/{mystring2:.*}"}, method = RequestMethod.GET)
public String handleReqShow(
@PathVariable String mystring,
@PathVariable String mystring2,
@RequestParam(required = false) String name,
@RequestParam(required = false) String family, Model model) {
I have tried the similar concept when my one controller is used to handle multiple types of request.
The default Spring MVC path mapper uses the /
as a delimiter for path variables, no matter what.
The proper way to handle this request would be to write a custom path mapper, that would change this logic for the particular handler method and delegate to default for other handler methods.
However, if you know the max possible count of slashes in your value, you can in fact write a handler that accepts optional path variables, and than in the method itself, assemble the value from path variable parts, here is an example that would work for max one slash, you can easily extend it to three or four
@RequestMapping(value = {"/{part1}", "/{part1}/{part2}"}, method = RequestMethod.GET)
public String handleReqShow(
@PathVariable Map<String, String> pathVariables,
@RequestParam(required = false) String name,
@RequestParam(required = false) String family, Model model) {
String yourValue = "";
if (pathVariables.containsKey("part1")) {
String part = pathVariables.get("part1");
yourValue += " " + part;
}
if (pathVariables.containsKey("part2")) {
String part = pathVariables.get("part2");
yourValue += " /" + part;
}
// do your stuff
}
You can catch all the path variables inside the map, the map @PathVariable Map<String, String> pathVariables
, but the downside is that the static part of the mapping has to enumarate all the possible variations
You can define rules to avoid that
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
rules.xml add this to your WEB-INF
<urlrewrite>
<rule>
<from>^/(10\..*)$</from> <!-- tweak this rule to meet your needs -->
<to>/Show?temp=$1</to>
</rule>
</urlrewrite>