关于annotation-driven配置问题的说明

现象

mvc-dispatch-servlet.xml中的配置:

测试接口controller,返回值类型为String:

其中入参queryNewsListReqVo的属性包括:

测试请求以及响应:

此时的Header:

当设置返回对象为Object时:

请求以及响应:

此时的Header:

Controller返回String时中文乱码,返回Object时中文正常,造成此问题的原因是:

当设置返回值为String类型时,Response的content-type被SpringMVC自动设置为

text/plain;charset=ISO-8859-1

当返回值类型为Object时,返回值会被json格式化,并使用UTF-8编码

application/json;charset=UTF-8

以上这些都是spring的默认设置

如果我们希望当返回值为string类型时也进行json格式化就需要在RequestMappingHandlerAdapter中设置Convert类:

org.springframework.http.converter.json.MappingJackson2HttpMessageConverter

原因分析

现在回过头看我们的配置:

可以看出配置的本意确实是想要配置返回值的转换类,但是从上面的实验结果看出,并没有生效。

原因是:

通过查看AnnotationDrivenBeanDefinitionParser的源码:

源码在org.springframework.web.servlet.config包中

在<mvc:annotation-driver/>的解析器AnnotationDrivenBeanDefinitionParser中已经进行了这个bean的初始化并注入到了容器中。

在</mvc:annotation-driver>之后自定义的RequestMappingHandlerMapping和RequestMappingHandlerAdapter这两个bean并没有被注入到spring的容器中,因此,上述配置并未生效。

当我们修改配置,在annotation-driven中配置converter类:

此配置的含义就是在解析<mvc:annotation-dirven/>配置并加载RequestMappingHandlerAdapter的时候设置对应的Converter类

再次请求返回值string类型的接口时:

返回值为中文时不再乱码

Header中的content-type也正确:


结论:

我们当前配置:

红框中的内容完全没有任何作用,如果希望配置返回值json化,可以改为如下配置:


引申内容

从上述的分析中,可以看出在spring的xml中配置的bean,靠前配置的会优先加载,靠后加载的相同的bean不会被注入容器。

如果我们颠倒原有的配置方式,将<mvc:annotation-driver/>配置在后面的时候,也是可以达到返回值json化的目的,但是此时的造成其他问题。因为通过上面解析类的源码可以看到在加载RequestMappingHandlerAdapter的时候除了加载converter类之外,还加载了其他类:

其中的bindingDef的一个作用就是解析请求vo上的注解的:

当配置如下时:

请求返回值为String的接口正常:

但是当请求带有注解属性的参数时:

返回了400错误,如果打印了spring日志的话,也可以看到spring已经给出提示:

10:24:51,255 [ WARN] [org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver] :186 - Handler execution resulted in exception: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'queryNewsListReqVo' on field 'beginTime': rejected value [2019-05-05 10:10:10]; codes [typeMismatch.queryNewsListReqVo.beginTime,typeMismatch.beginTime,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [queryNewsListReqVo.beginTime,beginTime]; arguments []; default message [beginTime]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'beginTime'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'beginTime': no matching editors or conversion strategy found]

猜你喜欢

转载自blog.csdn.net/tfvglin/article/details/90023634