消息转换器定义
我们可以通过重写 configureMessageConverters()
方法(替换Spring MVC创建的默认转换器)或重写extendMessageConverters()
方法(自定义默认转换器或向默认转换器添加其他转换器)在Java配置中自定义 HttpMessageConverter。
HttpMessageConverter
消息转换器 HttpMessageConverter
借口定义如下:
public interface HttpMessageConverter<T> { /** * Indicates whether the given class can be read by this converter. * @param clazz the class to test for readability * @param mediaType the media type to read (can be {@code null} if not specified); * typically the value of a {@code Content-Type} header. * @return {@code true} if readable; {@code false} otherwise */ boolean canRead(Class<?> clazz, @Nullable MediaType mediaType); /** * Indicates whether the given class can be written by this converter. * @param clazz the class to test for writability * @param mediaType the media type to write (can be {@code null} if not specified); * typically the value of an {@code Accept} header. * @return {@code true} if writable; {@code false} otherwise */ boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType); /** * Return the list of media types supported by this converter. The list may * not apply to every possible target element type and calls to this method * should typically be guarded via {@link #canWrite(Class, MediaType) * canWrite(clazz, null}. The list may also exclude MIME types supported * only for a specific class. Alternatively, use * {@link #getSupportedMediaTypes(Class)} for a more precise list. * @return the list of supported media types */ List<MediaType> getSupportedMediaTypes(); /** * Return the list of media types supported by this converter for the given * class. The list may differ from {@link #getSupportedMediaTypes()} if the * converter does not support the given Class or if it supports it only for * a subset of media types. * @param clazz the type of class to check * @return the list of media types supported for the given class * @since 5.3.4 */ default List<MediaType> getSupportedMediaTypes(Class<?> clazz) { return (canRead(clazz, null) || canWrite(clazz, null) ? getSupportedMediaTypes() : Collections.emptyList()); } /** * Read an object of the given type from the given input message, and returns it. * @param clazz the type of object to return. This type must have previously been passed to the * {@link #canRead canRead} method of this interface, which must have returned {@code true}. * @param inputMessage the HTTP input message to read from * @return the converted object * @throws IOException in case of I/O errors * @throws HttpMessageNotReadableException in case of conversion errors */ T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; /** * Write an given object to the given output message. * @param t the object to write to the output message. The type of this object must have previously been * passed to the {@link #canWrite canWrite} method of this interface, which must have returned {@code true}. * @param contentType the content type to use when writing. May be {@code null} to indicate that the * default content type of the converter must be used. If not {@code null}, this media type must have * previously been passed to the {@link #canWrite canWrite} method of this interface, which must have * returned {@code true}. * @param outputMessage the message to write to * @throws IOException in case of I/O errors * @throws HttpMessageNotWritableException in case of conversion errors */ void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException; }
自定义消息转换器
下面是一个简单的消息转换器定义,代码如下:
@Configuration @EnableWebMvc public class WebConfiguration implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder() .indentOutput(true) .dateFormat(new SimpleDateFormat("yyyy-MM-dd")) .modulesToInstall(new ParameterNamesModule()); converters.add(new MappingJackson2HttpMessageConverter(builder.build())); converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build())); } }
在前面的示例中,Jackson2ObjectMapperBuilder 用于为 MappingJackson2HttpMessageConverter 和MappingJackson2XmlHttpMessageConverter 创建公共配置,启用缩进、自定义日期格式和jackson模块参数名称注册,这增加了对访问参数名称的支持(Java8中添加的一个特性)。
配置 FastJson 为默认 JSON 解析器
其实我们在项目最最常用的还是 FastJSON 作为 Spring MVC 的默认 JSON 解析器。具体的配置如下:
<bean id="mappingJacksonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <!--class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">--> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json</value> <value>application/xml;charset=UTF-8</value> </list> </property> </bean>