Spring MVC 消息转换器扩展
# Spring MVC 消息转换器扩展
前言
在 Spring MVC 中,消息转换器(HttpMessageConverter
)用于在请求和响应中处理请求体和响应体的序列化与反序列化。通过扩展 extendMessageConverters(List<HttpMessageConverter<?>> converters)
方法,可以在不影响默认转换器的前提下,自定义处理特定数据格式的逻辑。
# 1. 扩展消息转换器的配置
推荐使用 extendMessageConverters
方法来添加自定义转换器,而不是使用 configureMessageConverters
,因为后者会完全覆盖 Spring MVC 的默认转换器。
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 创建一个新的 Jackson 消息转换器实例,用于处理 JSON 数据
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
// 配置 ObjectMapper 自定义 JSON 序列化和反序列化规则
ObjectMapper objectMapper = new ObjectMapper();
// 自定义序列化器:将 Integer 类型转换为 String,避免 JS 精度丢失
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Integer.class, ToStringSerializer.instance); // 自定义 Integer 类型的序列化
simpleModule.addSerializer(Integer.TYPE, ToStringSerializer.instance); // 自定义 int 类型的序列化
objectMapper.registerModule(simpleModule);
// 将配置好的 ObjectMapper 设置到 Jackson 消息转换器中
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
// 将自定义的消息转换器添加到转换器列表的首位,确保优先应用
converters.add(0, jackson2HttpMessageConverter);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2. 关键参数与配置说明
extendMessageConverters
方法:此方法在保留 Spring 默认转换器的基础上进行扩展,不会替换或删除默认的转换器,非常适合需要在已有转换器基础上添加新功能的场景。MappingJackson2HttpMessageConverter
:Spring 提供的用于处理 JSON 格式数据的转换器。通过自定义ObjectMapper
,可以控制序列化和反序列化的行为。SimpleModule
和ToStringSerializer
:自定义序列化逻辑的模块配置。例如,将Integer
类型数据转换为字符串,避免 JavaScript 在处理大整数时出现精度丢失的问题。converters.add(0, jackson2HttpMessageConverter)
:将自定义的转换器放在转换器列表的首位,确保它在默认转换器之前被使用。这种方式可以优先处理请求和响应中的数据,确保自定义逻辑生效。
# 3. 默认转换器与自定义转换器的优先级
在 Spring MVC 中,消息转换器的顺序非常重要。默认的转换器列表中包含了一些常用的转换器(如 JSON、XML、文本等)。如果自定义转换器的优先级低于默认转换器,它可能不会被应用。因此,将自定义转换器放在列表的首位是确保其生效的关键。
# 4. 常见应用场景
- 处理大数值的序列化问题:例如在金融系统中,JavaScript 不能正确处理超过
Number.MAX_SAFE_INTEGER
的数值,因此需要将Long
或Integer
类型的数据转换为字符串。 - 统一日期格式:可以配置
ObjectMapper
,确保所有的日期类型在 JSON 序列化时使用相同的格式(如"yyyy-MM-dd HH:mm:ss"
)。 - 过滤或处理特定字段:例如,可以通过自定义序列化器在序列化过程中动态添加或删除某些字段。
# 5. 示例接口与测试
定义一个简单的控制器方法,返回一个包含整数和日期的对象:
@RestController
public class TestController {
@GetMapping("/test")
public Map<String, Object> test() {
Map<String, Object> response = new HashMap<>();
response.put("id", 123456789);
response.put("timestamp", new Date());
return response;
}
}
2
3
4
5
6
7
8
9
10
11
启动应用后,访问 http://localhost:8080/test
,你将会看到返回的数据中 id
是字符串格式的数字,而日期是格式化后的字符串。这说明自定义的消息转换器已经生效。
# 6. 注意事项
- 使用
extendMessageConverters
方法时,确保自定义转换器的顺序正确,以避免与默认转换器的冲突。 - 如果你的自定义转换器不需要覆盖默认转换器的行为,推荐使用
extendMessageConverters
,以便与 Spring 的默认配置兼容。
总结
通过 extendMessageConverters
方法,Spring MVC 提供了一种灵活且不影响默认配置的方式来扩展消息转换器。无论是处理特殊数据类型还是自定义序列化规则,这种配置方式都能满足复杂的业务需求,同时保持代码简洁与可维护性。