Spring MVC消息转换器的扩展

消息转换器是 Spring MVC 中用于实现 HTTP 请求/响应报文与 Java 对象相互转换的核心组件。它解决了控制器方法参数和返回值与不同数据格式(JSON、XML、文本等)的适配问题。

如果要单独指定一个属性的格式,可以为其添加@JsonFormat(pattern = "目标格式")注解来实现。但是在项目实际开发中,面对众多的实体类,这种方法显然不现实,此时就要来扩展MVC中的消息转换器,为全局 LocalDateTime指定格式。

java 复制代码
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")  
private LocalDateTime createTime;

本文以格式化时间数据为例,来简述如何实现消息转换器的扩展。

首先,我们要在继承了WebMvcConfigurationSupport类的配置类中重写extendMessageConverters方法,在方法体中实现扩展。

java 复制代码
/**  
 * 配置类,注册web层相关组件  
 */  
@Slf4j  
@Configuration  
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
	  
    /**  
     * 扩展Spring MVC框架的消息转换器  
     * @param converters  
     */  
    @Override  
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {  
        log.info("扩展消息转换器...");
        
        //创建消息转换器对象  
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();  
  
        //为消息转换器设置一个对象转换器,对象转换器可以将java对象转为json  
        messageConverter.setObjectMapper(new JacksonObjectMapper());  
  
        //将上面的消息转换器对象追加到mvc框架的转换器集合中  
        converters.add(0,messageConverter);  
    }  
}

方法体中,先new一个空白的消息转换器对象,再为其设置对象转换器,并将自己设置的消息转换器加入框架的转换器集合中,同时设置高优先级确保其生效。

对象转换器的实现:

java 复制代码
/**  
 * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象  
 * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]  
 * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]  
 */public class JacksonObjectMapper extends ObjectMapper {  
  
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";  
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";  
    public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";  
  
    public JacksonObjectMapper() {  
        super();  
        //收到未知属性时不报异常  
        this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);  
  
        //反序列化时,属性不存在的兼容处理  
        this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);  
  
        SimpleModule simpleModule = new SimpleModule()  
                .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))  
                .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))  
                .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))  
                .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))  
                .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))  
                .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));  
  
        //注册功能模块 例如,可以添加自定义序列化器和反序列化器  
        this.registerModule(simpleModule);  
    }  
}

通过继承ObjectMapper类自定义一个对象映射其,实现在序列化和反序列化过程中强行设置时间格式:

  1. 定义三种时间类型的默认格式。
  2. 忽略其他属性,避免在序列化过程中出现异常
  3. 注册时间类型的自定义序列化器/反序列化器
  4. 注册模块

特别注意:

  1. 对象转换器部分的代码较为固定,可以直接CV
  2. 由于本文的时间格式在序列化和反序列化中实现,所以在接收请求体参数,响应Java对象等大部分场景都有效。但是,当在Controller层接收Query参数和路径参数时,由于不涉及序列化和反序列化,依然需要手动添加注解来为其指定正确的格式
相关推荐
azhou的代码园30 分钟前
基于SpringBoot+微信小程序的图片识别科普系统
spring boot·后端·微信小程序
Tony Bai1 小时前
Rust 看了流泪,AI 看了沉默:扒开 Go 泛型最让你抓狂的“残疾”类型推断
开发语言·人工智能·后端·golang·rust
用户3167361303421 小时前
javaLangchain4j从官方文档入手,看他做了什么——具体使用(二)
后端
無名路人1 小时前
Zsh 脚本 + VS Code 任务:NestJS + Vue3 一键部署到 1Panel
运维·后端·自动化运维
ybwycx2 小时前
springboot之集成Elasticsearch
spring boot·后端·elasticsearch
程途知微2 小时前
AQS 同步器——Java 并发框架的核心底座全解析
java·后端
iPadiPhone3 小时前
分布式架构的“润滑剂”:RabbitMQ 核心原理与大厂面试避坑指南
分布式·后端·面试·架构·rabbitmq
武子康3 小时前
大数据-255 离线数仓 - Apache Atlas 数据血缘与元数据管理实战指南
大数据·后端·apache hive
javaTodo3 小时前
IntelliJ IDEA 2026.1 上强度了:Spring 运行时 Debug + AI 全面接入,太香了
后端
晴栀ay4 小时前
Generator + RxJS 重构 LLM 流式输出的“丝滑”架构
javascript·后端·llm