我正在尝试将@RequestMapping
与consumes
- 元素一起使用。阅读API-document它可以在请求的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
- 部分,如果我指定
@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
- 元素上的文档也未提及charset
的使用,但根据Google的说法,有人使用它。
这里发生了什么或者我做错了什么的线索?
BTW,这是Spring 3.1.1.RELEASE。
答案 0 :(得分:12)
我认为您已经回答了您的问题,因此从代码的角度来看,这更像是一个确认,为什么在解析映射时不会考虑charset
。
在深入研究Spring代码时,罪魁祸首似乎是MediaType#includes()
。方法
更多挖掘揭示了与方法的RequestMappingInfo
注释相关联地创建了RequestMapping
。此RequestMappingInfo
存储了一系列AbstractRequestCondition
个对象,其中一个是ConsumesRequestCondition
,其中包含在注释的consumes
部分中定义的MediaType
(即{ {1}})。
稍后当发出请求时,此application/x-www-form-urlencoded;charset=UTF-8
有一个inner ConsumeMediaTypeExpression
class with a matchMediaType()
method,可以提取ConsumesRequestCondition
的{{1}}并根据它自己的MediaType
进行检查看看它是否包括在内。
如果查看HttpServletRequest
实现(第426行到第428行),则在MediaType
(即MediaType#includes()
)和type
(即application
时返回true }}是相等的,完全忽略了subtype
映射,在这种情况下
持有残余x-www-form-urlencoded
组合。
挖掘parameters
曲目似乎显示了类似的结果,但在这种情况下,它涉及的是MediaType#isCompatibleWith()
方法,而且只会到达"charset","UTF-8"
和produces
如果他们是平等的。
如果您在Google上发现type
正在为charset请求映射工作的证据,我会怀疑它(除非他们更改了Spring的核心内容)
至于为什么它是这样设计的,那么这是另一个问题:)