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

Why does Spring MVC @RequestMapping throws 406 error for mapping (/user/{username:.+}) when parameter ends with (.pl)

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

这是表示该操作的方法。控制器用 @RestController

注释

已解决

应该覆盖内容类型协商机制。

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

代码:

@Override
  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    configurer.mediaType("pl", MediaType.APPLICATION_JSON);
  }

更新答案

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 .+ 作为您的用户名变量,这实际上意味着您匹配整个模式。