spring mvc中converter和formatter用于请求参数的类型转换:converter专注通用类型映射(如string→date),formatter支持locale感知的格式化类型(如日期、货币)。

在 Spring MVC 中,类型转换器(Converter 和 Formatter)主要用于将 HTTP 请求中的字符串参数,按业务规则转成控制器方法所需的任意 Java 类型。它不处理复杂对象构建逻辑(那是 HandlerMethodArgumentResolver 的职责),而是专注“类型到类型”的干净映射,比如 String → Date、String → Product 或 String → Enum。
明确 Converter 和 Formatter 的分工
Converter 是通用类型转换接口,适用于任意源类型 S 到目标类型 T 的转换,不依赖格式化上下文。适合结构固定、无 locale/时区敏感的场景,例如:
- 把
"1-zhangsan-23"解析为Student对象 - 把
"Num1000-9999"拆解为Product(number="Num1000", qty=9999) - 把 Base64 编码字符串还原为 byte[]
Formatter
-
"2026-08-13"→LocalDate(按当前语言环境解析) -
"¥1,234.50"→BigDecimal - 输出时自动补零、千分位、时区适配
实现并注册自定义 Converter
以 String → Date 为例,定义一个严格模式的日期转换器:
public class DateConverter implements Converter<string date> {
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Override
public Date convert(String source) {
if (source == null || source.trim().isEmpty()) {
return null;
}
try {
return sdf.parse(source.trim());
} catch (ParseException e) {
throw new IllegalArgumentException("日期格式错误,应为 yyyy-MM-dd,实际值:" + source);
}
}
}</string>
注册方式(Java Config):
- 创建
ConversionServicebean,并注入你的 Converter - 确保该 bean 被 Spring MVC 自动识别(ID 必须是
conversionService,或通过@Bean显式声明)
示例配置:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public ConversionService conversionService() {
DefaultConversionService service = new DefaultConversionService();
service.addConverter(new DateConverter());
return service;
}
}
注意:Spring Boot 2.0+ 默认启用 @EnableWebMvc 等效行为,直接定义 @Bean ConversionService 即可生效;传统 Spring MVC 需在 <annotation-driven conversion-service="conversionService"></annotation-driven> 中指定。
使用 Formatter 处理带 locale 的格式化类型
若需支持多语言日期显示(如中文环境用“2026年8月13日”),推荐用 Formatter:
public class LocalDateFormatter implements Formatter<localdate> {
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
@Override
public LocalDate parse(String text, Locale locale) throws ParseException {
return LocalDate.parse(text, formatter);
}
@Override
public String print(LocalDate object, Locale locale) {
return object.format(formatter);
}
}</localdate>
注册方式类似,但需通过 FormattingConversionServiceFactoryBean 或在 WebMvcConfigurer.addFormatters() 中添加:
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new LocalDateFormatter());
// 或 registry.addConverter(new MyCustomConverter());
}
这样,控制器中直接写 @RequestParam LocalDate birthday 就能自动解析。
让转换器生效的关键细节
不是所有参数都走 Converter —— 它只作用于 简单类型绑定(即请求参数、表单字段、路径变量等经 WebDataBinder 处理的场景),不用于 @RequestBody JSON 解析(那是 Jackson 的事)。
- 确保目标字段类型与 Converter 的
T一致,且没有其他更高优先级的内置转换器覆盖 - 异常要抛
IllegalArgumentException,Spring 会统一转为 400 Bad Request - 多个 Converter 共存时,注册顺序不影响匹配逻辑,Spring 按类型精确匹配;Formatter 则按类型 + locale 组合查找
- 避免在 Converter 中做数据库查询、远程调用等重操作——那是参数解析器(
HandlerMethodArgumentResolver)该干的事
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










