如何处理包含正斜杠(/)的请求?

我需要处理如下请求:

www.example.com/show/abcd/efg?name=alex&family=moore (does not work) www.example.com/show/abcdefg?name=alex&family=moore (works) www.example.com/show/abcd-efg?name=alex&family=moore (works) 

它应该接受来自www.example.com/show/?之间的值的任何类型的字符? 。 请注意,那里的值将是单个值而不是操作的名称。

例如: /show/abcd/efg/show/lkikf?name=Jack ,其中第一个请求应该将用户重定向到页面abcd/efg (因为这是一个名称),第二个请求应该将用户重定向到页面lkikf具有参数名称的值。

我有跟随控制器来处理它,但问题是当我有/在地址控制器无法处理它。

 @RequestMapping(value = "/{mystring:.*}", method = RequestMethod.GET) public String handleReqShow( @PathVariable String mystring, @RequestParam(required = false) String name, @RequestParam(required = false) String family, Model model) { 

我使用了以下正则表达式,但没有用。

  /^[ A-Za-z0-9_@./#&+-]*$/ 

你必须创建两个方法,然后一个方法具有@RequestMapping(value = { "/{string:.+}" })注释,另一个方法具有@RequestMapping(value = { "/{string:.+}", "/{string:.+}/{mystring:.+}" })然后在每个中相应地执行操作,因为您不能拥有可选的路径变量。

 import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller @RequestMapping("/show") public class HelloController { @RequestMapping(value = { "/{string:.+}" }) public String handleReqShow(@PathVariable String string, @RequestParam(required = false) String name, @RequestParam(required = false) String family, Model model) { System.out.println(string); model.addAttribute("message", "I am called!"); return "hello"; } @RequestMapping(value = { "/{string:.+}", "/{string:.+}/{mystring:.+}" }) public String whatever(@PathVariable String string, @PathVariable String mystring, @RequestParam(required = false) String name, @RequestParam(required = false) String family, Model model) { System.out.println(string); System.out.println(mystring); model.addAttribute("message", "I am called!"); return "hello"; } } 

我做的另一种方式是:

 @RequestMapping(value = "test_handler/**", method = RequestMethod.GET) 

…并且您的测试处理程序可以是“/ test_hanlder / a / b / c”,您将使用以下机制获得整个值。

 requestedUri = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); 

第一个不起作用,因为您正在尝试处理一个实际上没有映射到您的控制器的全新URL。

 www.example.com/show/abcd/efg?name=alex&family=moore (does not work) 

上述URL的正确映射可能类似于下面的代码。

 @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) { 

当我的一个控制器用于处理多种类型的请求时,我尝试过类似的概念。

您可以定义规则以避免这种情况

  UrlRewriteFilter org.tuckey.web.filters.urlrewrite.UrlRewriteFilter   UrlRewriteFilter /* REQUEST FORWARD  

rules.xml将此添加到您的WEB-INF

   ^/(10\..*)$  /Show?temp=$1   

尝试逃避正斜杠。 正则表达式: /^[ A-Za-z0-9_@.\/#&+-]*$/

默认的Spring MVC路径映射器使用/作为路径变量的分隔符,无论如何。

处理此请求的正确方法是编写自定义路径映射器,这将为特定处理程序方法更改此逻辑,并将其委托为其他处理程序方法的默认值。

但是,如果你知道值中最大可能的斜杠数,你实际上可以编写一个接受可选路径变量的处理程序,而不是在方法本身中,从路径变量部分组装值,这里有一个可行的例子对于最多一个斜杠,您可以轻松地将其扩展为三个或四个

 @RequestMapping(value = {"/{part1}", "/{part1}/{part2}"}, method = RequestMethod.GET) public String handleReqShow( @PathVariable Map 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 } 

你可以捕获地图中的所有路径变量,地图@PathVariable Map pathVariables ,但缺点是映射的静态部分必须包含所有可能的变化

您可以使用%2f在UI上对斜杠进行编码: http://www.example.com/show/abcd%2fefg?name=alex&family=moorehttp://www.example.com/show/abcd%2fefg?name=alex&family=moore ?name http://www.example.com/show/abcd%2fefg?name=alex&family=moore alex&family + quick。 现在你应该配置Spring来处理斜杠。 简单的配置示例:

 @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); } } }