我需要处理以下请求:
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
(因为这是一个名称),第二个请求应将用户重定向到页面{ {1}}以及参数名称的值。
我有以下控制器来处理它,但问题是当我在地址中时控制器无法处理它。
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) {
答案 0 :(得分:19)
我的另一种方式是:
@RequestMapping(value = "test_handler/**", method = RequestMethod.GET)
...并且您的测试处理程序可以是“/ test_hanlder / a / b / c”,您将使用以下机制获得整个值。
requestedUri = (String)
request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
答案 1 :(得分:18)
您必须创建两个方法,然后一个方法具有@RequestMapping(value = { "/{string:.+}" })
注释,另一个方法具有@RequestMapping(value = { "/{string:.+}", "/{string:.+}/{mystring:.+}" })
,然后在每个方法中相应地执行操作,因为您无法选择path variables. < / p>
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";
}
}
答案 2 :(得分:4)
第一个无法正常工作,因为您正在尝试处理一个实际上并未映射到控制器的全新URL。
www.example.com/show/abcd/efg?name=alex&family=moore (does not work)
上述网址的正确映射可能类似于以下代码。
@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) {
当我的一个控制器用于处理多种类型的请求时,我尝试过类似的概念。
答案 3 :(得分:3)
您可以定义规则以避免
<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将此添加到您的WEB-INF
<urlrewrite>
<rule>
<from>^/(10\..*)$</from> <!-- tweak this rule to meet your needs -->
<to>/Show?temp=$1</to>
</rule>
</urlrewrite>
答案 4 :(得分:2)
尝试转义正斜杠。
正则表达式:masterData = [
{
"name": "pdf",
"description" : "file format for PDF file",
"category":"fileType"
},
{
"name": "video",
"description" : "file format for mov, mp4 files",
"category":"fileType"
},
{
"name": "html",
"description" : "file format for html documents ",
"category":"fileType"
}
];
答案 5 :(得分:2)
默认的Spring MVC路径映射器使用/
作为路径变量的分隔符,无论如何。
处理此请求的正确方法是编写自定义路径映射器,这将为特定处理程序方法更改此逻辑,并将其委托为其他处理程序方法的默认值。
但是,如果你知道值中最大可能的斜杠数,你实际上可以编写一个接受可选路径变量的处理程序,而不是在方法本身中,从路径变量部分组装值,这里是一个例子这将适用于最多一个斜杠,您可以轻松地将其扩展到三个或四个
@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
}
您可以捕获地图中的所有路径变量,即地图@PathVariable Map<String, String> pathVariables
,但缺点是地图的静态部分必须包含所有可能的变化
答案 6 :(得分:2)
您可以使用%2f:http://www.example.com/show/abcd%2fefg?name=alex&family=moore
对UI进行斜杠编码。
现在你应该配置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);
}
}
}