带有包含 URL 的字符串参数的 RequestMapping
RequestMapping with String parameter containing URL
我有一个 Spring 控制器,有两个参数 long 和 String:
@RequestMapping(value = "/webpage")
@Controller
public class WebpageContentController {
//...
@RequestMapping(value = "{webpageId}/{webpageAddress}", method = RequestMethod.GET)
public String contentWebpageById(@PathVariable long webpageId, @PathVariable String webpageAddress) {
System.out.println("webpageId=" + webpageId);
System.out.println("webpageAddress=" + webpageAddress);
//...
}
//...
如果我这样调用它:
http://localhost:8080/webarch/webpage/1/blahblah
一切都很好:
webpageId=1
webpageAddress=blahblah
但是如果我用斜杠传递字符串参数(在这种情况下 URL 地址):
http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page
我得到一个错误:
org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page] in DispatcherServlet with name 'appServlet'
如何传递这样的参数?
这个错误是由 spring 的控制器映射引起的,当 Spring 看到 url 喜欢
http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page
'know'“https://en.wikipedia.org/wiki/Main_Page”不应作为参数映射到“{webpageId}/{webpageAddress}”映射,因为每个斜杠都被解释为更深层次的控制器方法映射.它寻找像 (webpage/1/http:{anotherMapping}/wiki{anotherMapping}/Main_Page{anotherMapping})
这样的控制器方法映射,这种映射显然不是由“{webpageId}/{webpageAddress}”
处理的
编辑
根据您的评论,您可以尝试这样的操作
@RequestMapping(value = "/{webpageId}/**", method = RequestMethod.GET)
public String contentWebpageById(HttpServletRequest request) {
String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
String extractedPathParam = pathMatcher.extractPathWithinPattern(pattern, request.getServletPath());
extractedPathParam = extractedPathParam.replace("http:/", "http://");
extractedPathParam = extractedPathParam.replace("https:/", "https://");
//do whatever you want with parsed string..
}
使用 spring 4.2.1
SomeParsing 应该使用一些正则表达式来仅提取 URL 'variable'
只需对 URL 中的所有特殊字符进行编码。
https://en.wikipedia.org/wiki/Main_Page
变成这样:
https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMain_Page
并且您可以毫无问题地将其作为 URL 参数传递。解码是自动完成的,因此如果您在控制器中将参数作为变量访问,它包含已经解码的 URL 并且您可以使用它而无需任何转换。
有关 URL 编码的更多信息:https://en.wikipedia.org/wiki/Percent-encoding
我有一个 Spring 控制器,有两个参数 long 和 String:
@RequestMapping(value = "/webpage")
@Controller
public class WebpageContentController {
//...
@RequestMapping(value = "{webpageId}/{webpageAddress}", method = RequestMethod.GET)
public String contentWebpageById(@PathVariable long webpageId, @PathVariable String webpageAddress) {
System.out.println("webpageId=" + webpageId);
System.out.println("webpageAddress=" + webpageAddress);
//...
}
//...
如果我这样调用它:
http://localhost:8080/webarch/webpage/1/blahblah
一切都很好:
webpageId=1
webpageAddress=blahblah
但是如果我用斜杠传递字符串参数(在这种情况下 URL 地址):
http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page
我得到一个错误:
org.springframework.web.servlet.PageNotFound.noHandlerFound No mapping found for HTTP request with URI [/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page] in DispatcherServlet with name 'appServlet'
如何传递这样的参数?
这个错误是由 spring 的控制器映射引起的,当 Spring 看到 url 喜欢
http://localhost:8080/webarch/webpage/1/https://en.wikipedia.org/wiki/Main_Page
'know'“https://en.wikipedia.org/wiki/Main_Page”不应作为参数映射到“{webpageId}/{webpageAddress}”映射,因为每个斜杠都被解释为更深层次的控制器方法映射.它寻找像 (webpage/1/http:{anotherMapping}/wiki{anotherMapping}/Main_Page{anotherMapping})
这样的控制器方法映射,这种映射显然不是由“{webpageId}/{webpageAddress}”
编辑
根据您的评论,您可以尝试这样的操作
@RequestMapping(value = "/{webpageId}/**", method = RequestMethod.GET)
public String contentWebpageById(HttpServletRequest request) {
String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
String extractedPathParam = pathMatcher.extractPathWithinPattern(pattern, request.getServletPath());
extractedPathParam = extractedPathParam.replace("http:/", "http://");
extractedPathParam = extractedPathParam.replace("https:/", "https://");
//do whatever you want with parsed string..
}
使用 spring 4.2.1
SomeParsing 应该使用一些正则表达式来仅提取 URL 'variable'
只需对 URL 中的所有特殊字符进行编码。
https://en.wikipedia.org/wiki/Main_Page
变成这样:
https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMain_Page
并且您可以毫无问题地将其作为 URL 参数传递。解码是自动完成的,因此如果您在控制器中将参数作为变量访问,它包含已经解码的 URL 并且您可以使用它而无需任何转换。
有关 URL 编码的更多信息:https://en.wikipedia.org/wiki/Percent-encoding