当参数以(.pl)结尾时,为什么Spring MVC @RequestMapping会因映射(/user/{username:.+})而抛出406错误

mat*_*gul 6 java spring spring-mvc spring-boot

@RequestMapping(value = "/user/{username:.+}", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
User user(@PathVariable String username) {
    User user = userRepository.findByUsername(username);
    if (user == null)
        throw new UserNotFoundException("User not found");

    return user;
}
Run Code Online (Sandbox Code Playgroud)

这是表示该动作的方法.控制器注释为@RestController

解决了

应覆盖内容类型协商机制.

Explonation:http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc

码:

@Override
  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.mediaType("pl", MediaType.APPLICATION_JSON);
  }
Run Code Online (Sandbox Code Playgroud)

the*_*dam 4

更新的答案

PathMatchConfigurer正在尝试将每个 /controller/path.* 与每个后缀进行匹配,尝试查找带有ContentNegotiationManager. 您可以通过禁用此功能或使其仅在 .* 是注册后缀时尝试来更改此行为。请参阅此处: http: //docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config-path-matching

您应该调用pathMatchConfigurer.setUseRegisteredSuffixPatternMatch(true)pathMatchConfigurer. setUseSuffixPatternMatch(false)

旧答案:)

我认为 Spring MVC 错误地认为 .pl 是扩展,并查找此媒体类型的 HTTPMessageConverter。在这种情况下,在这里创建转换器没有意义,但也许将其标记为不同的媒体类型会起作用?不过,我认为这只是一种解决方法。

我还认为你的@RequestMapping值可能很简单:value = "/user/{username}"- 你正在使用 RegEx .+ 作为你的用户名变量,这实际上意味着你无论如何都匹配整个模式。