Spring MVC uri映射与百分比编码字符

时间:2014-09-29 22:49:52

标签: java spring spring-mvc encoding

我有一个在Tomcat 7上运行的spring mvc应用程序,http和ajp连接器配置为URIEncoding =“UTF-8”。 我的REST控制器片段:

@Controller
@RequestMapping("")
public class ClientRestApi {
    private final String API_PREFIX = "/api/1.0/client";
    ...
    @RequestMapping(value = API_PREFIX + "/{clientId}", method = RequestMethod.GET)
    @ResponseBody
    public ClientDetails get(@PathVariable String clientId, HttpServletRequest request) {
        log.info("Client API GET [" + clientId + "] | " + request.getRequestURI());
        ...
    }
}
  • 当我去:http://www.example.pl/api/1.0/client/abc我得到 abc 客户页面 - 正确
  • 当我去:http://www.example.pl/%07api/1.0/client/abc我得到 abc 客户页面 - 错误
  • 当我去:http://www.example.pl/%0bapi/1.0/client/abc我得到 abc 客户页面 - 错误
  • 当我去:http://www.example.pl/ap%0bi/1.0/client/abc我得到http 404 - 正确

在应用程序日志中,我可以看到(前3个请求):

ClientRestApi - Client API GET [abc] | /api/1.0/client/abc
ClientRestApi - Client API GET [abc] | /%07api/1.0/client/abc
ClientRestApi - Client API GET [abc] | /%0bapi/1.0/client/abc

我的问题是为什么我的错误的示例有误? 为什么他们不是http 404?

在应用程序的web.xml文件中,我有使用UTF-8编码的CharacterEncodingFilter过滤器。在我的应用程序中,我从未遇到任何错误编码问题。

编辑: 从扩展日志中,请求http://www.example.pl/%0bapi/1.0/client/abc给出:

DEBUG RequestMappingHandlerMapping - Looking up handler method for path /^Kapi/1.0/client/abc
TRACE RequestMappingHandlerMapping - Found 1 matching mapping(s) for [/^Kapi/1.0/client/abc] : [{[/api/1.0/client/{
clientId}],methods=[GET],params=[],headers=[],consumes=[],produces=[],custom=[]}]
DEBUG RequestMappingHandlerMapping - Returning handler method [public ClientDetails ...ClientRestApi.get(java.lang.String,javax.servlet.http.HttpServletRequest)]

2 个答案:

答案 0 :(得分:1)

AntPathMatcher将路径标记化,默认情况下修剪所有段(请参阅String.trim的Javadoc)。可以控制此行为。因为您可以使用带有setTrimTokens(false)的AntPathMatcher配置RequestMappingHandlerMapping。

答案 1 :(得分:0)

这是我的访客,但似乎URL模式解析器正在搜索"/api/1.0/client"的存在。您的所有示例都包含该字符串,因此执行API_PREFIX的搜索字符串将为它们返回true。

http://www.example.pl/%07 api/1.0/client / ABC

http://www.example.pl/%0b api/1.0/client / ABC

你的最后一个例子没有确切的 /api/1.0/client字符串,而是使用0bi/1.0/client

简答:您无需为解析器定义确切的网址以进行选择。我相信没有spring的常规Java EE也是如此。如果您在web.xml文件中定义/api/1.0/client/*,则具有该字符串的任何URL都将触发您已分配给它的专用控制器。即使字符串先于,但是诸如/SDSFDFSFSFSF/api/1.0/client

之类的垃圾