前提:
spring版本:
<spring.version>4.3.22.RELEASE</spring.version>
JDK1.8
代码说明:
- 由于使用了一个SVN库,因此将代码导出来吧,可以共大家参考。
- 关注点:
- 代码zip压缩包。
实操步骤:
- 按照官方文档增加【org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter 】bean(在xml文件中配置),并不能实现增加自定义的HttpMessageConverter,并且还会使SpringWEB容器中存在两个RequestMappingHandlerAdapter 对象,从而引发异常。
官方配置文档地址https://docs.spring.io/spring/docs/4.3.22.RELEASE/spring-framework-reference/htmlsingle/#mvc-ann-requestbody
章节:
示例配置:
我的spring配置文件:<!-- 增加解析xml --> <bean id="requestMappingHandlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter" p:messageConverters-ref="messageConverters"></bean> <util:list id="messageConverters"> <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <property name="marshaller" ref="xStreamMarshaller"></property> <property name="unmarshaller" ref="xStreamMarshaller"></property> </bean> <bean class="org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean> <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"></bean> </util:list> <bean id="xStreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"> <property name="streamDriver"> <!-- stax对XML消息进行处理,占用内存少,响应速度也快 --> <bean class="com.thoughtworks.xstream.io.xml.StaxDriver"> </bean> </property> </bean>
实际使用会引发异常。由于想使用XML返回值,因此按照官方文档,并参照《精通Spring 4.x 企业应用开发实战》章节17.2.5中关于使用HttpMessageConverter,进行配置,跑起来并不能返回XML,如下是我的代码及测试:
期望能够响应XML,但是未能如愿。为了查看一下RequestMappingHandlerAdapter中是否,已经有了我增加的解析XML的HttpMessageConverter,将注释掉拿掉,代码如下:
@PostMapping("handleBodyStudentJson") @ResponseBody public Student handleBodyStudentJson(HttpServletRequest httpServletRequest) { RequestMappingHandlerAdapter adapter = applicationContext.getBean(RequestMappingHandlerAdapter.class); logger.info("请求期望响应类型:{}", httpServletRequest.getHeader("Accept")); return new Student("小安", 25, new ArrayList<>()); }
目标是调试,然后看一下变量adapter中是否有解析XML的 org.springframework.http.converter.xml.MarshallingHttpMessageConverter,再次请求,响应,及结果如图。
这就出现了上面我提到的异常。 - 看来这样子是不行的,继续查找Spring的官方文档(还是同一份官方文档),发现了如下:
- 再次修改配置文件如下:
<mvc:annotation-driven conversion-service="conversionService"> <mvc:message-converters> <ref bean="marshallingHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven> <bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <property name="marshaller" ref="xStreamMarshaller" /> <property name="unmarshaller" ref="xStreamMarshaller" /> </bean> <bean id="xStreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"> <property name="streamDriver"> <!-- stax对XML消息进行处理,占用内存少,响应速度也快 --> <bean class="com.thoughtworks.xstream.io.xml.StaxDriver"> </bean> </property> </bean>
- 再次请求,可以获取到XML响应。
- 若想获取JSON数据,只需将Accept修改为application/json,当然pom文件得增加jackson依赖。测试如下:
- 完整的POM提供一份:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.an</groupId> <artifactId>spring-mvc-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <java.version>1.8</java.version> <spring.version>4.3.22.RELEASE</spring.version> <commons-logging.version>1.2</commons-logging.version> <log4j.version>2.11.1</log4j.version> <jackson.version>2.9.8</jackson.version> <validation-api.version>2.0.1.Final</validation-api.version> <hibernate-validator.version>6.0.8.Final</hibernate-validator.version> </properties> <dependencies> <!-- 数据校验支持 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate-validator.version}</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>${validation-api.version}</version> </dependency> <!-- JSON支持 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>${jackson.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <!-- WEB项目,log4j2配置 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>${log4j.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j.version}</version> </dependency> <!-- 增加JSON --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- commons logs --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commons-logging.version}</version> </dependency> <!-- Spring 相关 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.11.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <source>1.8</source> <target>1.8</target> <debug>true</debug> </configuration> </plugin> </plugins> </build> </project>