Spring MVC 对象转换器:初级开发者入门指南

Spring MVC 对象转换器:初级开发者入门指南

为什么需要对象转换器?

在 Web 应用中,我们经常需要处理不同类型的对象。例如:前端数据到后端对象 :用户通过表单提交的数据通常是HttpServletRequest 对象,我们需要将其转换为 Java 对象(如 POJO)以便进行业务处理。后端对象到前端展示 :在将数据返回给前端时,可能需要将 Java 对象转换为适合前端展示的格式(如 JSON 或 XML)。对象转换是一个常见且重要的任务。它允许我们将一种类型的对象转换为另一种类型,以便在不同的层(如控制器、服务和视图)之间进行数据传递和处理。本文将详细介绍 Spring MVC 中的对象转换器,帮助初级开发者理解和掌握这一关键概念。


一、使用 Converter 接口

Converter<S, T> 接口用于将类型 S 转换为类型 T,适用于简单类型或自定义对象转换。

1. 实现自定义 Converter
java 复制代码
import org.springframework.core.convert.converter.Converter;

// 示例:将字符串 "yyyy-MM-dd" 转换为 Date 对象
public class StringToDateConverter implements Converter<String, Date> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date convert(String source) {
        try {
            return dateFormat.parse(source);
        } catch (ParseException e) {
            throw new IllegalArgumentException("无效的日期格式,请使用 yyyy-MM-dd");
        }
    }
}
2. 注册 Converter

通过 WebMvcConfigurer 配置类注册自定义转换器:

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToDateConverter());
    }
}

二、使用 Formatter 接口

Formatter<T> 专门用于处理字符串与对象的转换(如 HTTP 请求参数的转换)。

1. 实现自定义 Formatter
java 复制代码
import org.springframework.format.Formatter;
import java.text.ParseException;
import java.util.Locale;

public class DateFormatter implements Formatter<Date> {
    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    public Date parse(String text, Locale locale) throws ParseException {
        return dateFormat.parse(text);
    }

    @Override
    public String print(Date date, Locale locale) {
        return dateFormat.format(date);
    }
}
2. 注册 Formatter

同样通过 WebMvcConfigurer 注册:

java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addFormatter(new DateFormatter());
    }
}

三、使用 HttpMessageConverter(处理 JSON/XML)

当使用 @RequestBody@ResponseBody 时,Spring 使用 HttpMessageConverter 进行对象与 JSON/XML 的转换。常用的是 Jackson 的 MappingJackson2HttpMessageConverter

1. 自定义 Jackson 的 ObjectMapper
java 复制代码
@Configuration
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper;
    }

    @Bean
    public MappingJackson2HttpMessageConverter jacksonConverter(ObjectMapper objectMapper) {
        return new MappingJackson2HttpMessageConverter(objectMapper);
    }
}
2. 注册自定义 HttpMessageConverter
java 复制代码
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(new MappingJackson2HttpMessageConverter(objectMapper()));
    }

    @Bean
    public ObjectMapper objectMapper() {
        // 同上
    }
}

四、使用 @InitBinder(局部绑定)

在控制器中为特定字段注册自定义编辑器。

示例:绑定日期格式
java 复制代码
@Controller
public class MyController {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }
}

五、常见场景示例

1. 枚举类型转换

将请求参数转换为枚举:

java 复制代码
public enum Status {
    ACTIVE, INACTIVE;
}

// 自定义 Converter
public class StringToStatusConverter implements Converter<String, Status> {
    @Override
    public Status convert(String source) {
        return Status.valueOf(source.toUpperCase());
    }
}
2. 自定义对象转换

String 转换为 User 对象:

java 复制代码
public class StringToUserConverter implements Converter<String, User> {
    @Override
    public User convert(String source) {
        String[] parts = source.split(",");
        User user = new User();
        user.setName(parts[0]);
        user.setAge(Integer.parseInt(parts[1]));
        return user;
    }
}

六、注意事项

  1. 优先级ConverterFormatter 的注册顺序可能影响结果。

  2. 全局 vs 局部@InitBinder 仅作用于当前控制器,而 Converter/Formatter 是全局的。

  3. JSON 配置 :在 Spring Boot 中,可以通过 application.properties 配置 Jackson:

    properties 复制代码
    spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
    spring.jackson.time-zone=GMT+8

通过合理使用这些转换器,可以灵活处理 Spring MVC 中的数据类型转换需求。

相关推荐
九转苍翎12 分钟前
Java SE(10)——抽象类&接口
java
明月与玄武12 分钟前
Spring Boot中的拦截器!
java·spring boot·后端
矢鱼13 分钟前
单调栈模版型题目(3)
java·开发语言
n33(NK)20 分钟前
Java中的内部类详解
java·开发语言
为美好的生活献上中指22 分钟前
java每日精进 5.07【框架之数据权限】
java·开发语言·mysql·spring·spring cloud·数据权限
菲兹园长34 分钟前
SpringBoot统一功能处理
java·spring boot·后端
一刀到底21143 分钟前
spring ai alibaba 使用 SystemPromptTemplate 很方便的集成 系统提示词
spring·ai alibaba
一刀到底2111 小时前
java 多核,多线程,分布式 并发编程的现状 :从本身的jdk ,到 spring ,到其它第三方。
java·分布式·高并发
Kendra9191 小时前
Docker 容器 - Dockerfile
java·docker·eureka
Auc241 小时前
Java 原生实现代码沙箱(OJ判题系统第1期)——设计思路、实现步骤、代码实现
java·开发语言·python