3

我正在尝试@RequestMappingconsumes-element 一起使用。读取它在请求的 -header 上工作的API 文档。Content-Type但是,使用

@RequestMapping(consumes = "application/x-www-form-urlencoded;charset=UTF-8", value = "/test")
public void test() {
  :
}

或者

@RequestMapping(consumes = "application/x-www-form-urlencoded;charset=ISO-8859-1", value = "/test")
public void test() {
  :
}

没有什么区别。请求中的标头看起来像

Content-Type: application/x-www-form-urlencoded;charset=UTF-8

或者

Content-Type: application/x-www-form-urlencoded

test()将在所有四个可能的星座中被调用。

但是,这向我证明了 Spring 看到并尝试使用charset-part,如果我指定

@RequestMapping(consumes = "application/x-www-form-urlencoded;charset=UTF-x8", value = "/test")
public void test() {
  :
}

在网络应用程序的启动(!)期间出现异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0': Initialization of bean failed;
    nested exception is java.nio.charset.UnsupportedCharsetException: UTF-x8

请注意,关于produces-element 的文档也没有提到使用charset,但根据谷歌的一些使用它。

关于这里发生的事情或我做错了什么的任何线索?

顺便说一句,这是 Spring 3.1.1.RELEASE。

4

1 回答 1

13

我认为您已经回答了您的问题,所以从代码的角度来看,这更像是一个确认,为什么charset在解析映射时没有考虑到。

在深入研究 Spring 代码时,罪魁祸首似乎是MediaType#includes(). 方法

更多的挖掘揭示了 aRequestMappingInfo是与RequestMapping方法的注释相关联的。这存储RequestMappingInfo了一系列AbstractRequestCondition对象,其中一个是在注释部分(即)中定义的对象。ConsumesRequestConditionMediaTypeconsumesapplication/x-www-form-urlencoded;charset=UTF-8

稍后,当发出请求时,它ConsumesRequestCondition有一个内部ConsumeMediaTypeExpression类,其中包含一个matchMediaType()提取 的MediaType方法HttpServletRequest对照它自己的方法检查它MediaType以查看它是否包含在内。

如果您查看实现(第 426 到 428 行),它会在(ie ) 和(ie ) 相等MediaType#includes()时返回 true ,完全忽略在这种情况下保存剩余组合的 Map。typeapplicationsubtypex-www-form-urlencodedparameters"charset","UTF-8"

深入研究produces轨道似乎显示了类似的结果,但在这种情况下,它是所MediaType#isCompatibleWith()涉及的方法,并且再次,它仅达到type并且subtype如果它们相等。

如果你在谷歌上找到produces了字符集请求映射工作的证据,我会怀疑(除非他们改变了核心 Spring 的东西)

至于为什么这样设计,那是另一个问题:)

于 2012-10-09T19:59:03.143 回答