Spring MVC的同声传译:HttpMessageConverter的奇幻漂流

150 阅读4分钟

🌝 Spring MVC的同声传译:HttpMessageConverter的奇幻漂流 🌝


一、开篇:程序员的"黑话翻译官"

想象一下,你正在和一位只会说"螺蛳粉语言"的广西朋友聊天,而你只会说"咖啡味英语"。这时候你需要一个翻译官——HttpMessageConverter 就是 Spring MVC 中这样的存在!它负责把 HTTP 请求的"黑话"(JSON/XML/二进制)翻译成 Java 对象,再把 Java 对象的"内心戏"转成响应格式。没有它,你的 Controller 可能连"酸笋味"都闻不到!


二、用法:让数据飞一会儿

1. 基本操作:@RequestBody & @ResponseBody

@PostMapping("/order")
public String createOrder(@RequestBody Order order) { // 自动将JSON转成Order对象
    return "Success: " + order.getId(); // 自动将返回值转成JSON
}
  • @RequestBody:把请求体的"黑话"翻译成 Java 对象。
  • @ResponseBody:把 Java 对象的"独白"转成响应格式。

2. 高级配置:自定义翻译官

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new MyCustomConverter()); // 插队到第一位
    }
}

想让你的自定义 Converter 拥有"VIP 优先权"?把它放在列表最前面!


三、经典案例:翻译官的日常

1. JSON 恋爱循环

// 自动使用MappingJackson2HttpMessageConverter
@PostMapping("/users")
public User addUser(@RequestBody User user) {
    return userService.save(user);
}

请求: {"name":"Tony", "age":30}响应: {"id":1, "name":"Tony"}

2. XML の奇妙冒险

@GetMapping(value = "/book", produces = MediaType.APPLICATION_XML_VALUE)
public Book getBook() {
    return new Book("Spring 终极奥义", "ISBN-666");
}

需要添加 Jackson XML 依赖,让翻译官学会"XML 语法"!

3. 文件上传の哲学

@PostMapping("/upload")
public String handleFile(@RequestParam("file") MultipartFile file) {
    return "File size: " + file.getSize();
}

MultipartHttpMessageConverter 默默处理了文件流的魔法。


四、原理探秘:翻译官的工作流程

  1. 请求到来:DispatcherServlet 收到 HTTP 请求
  2. 寻找翻译官:HandlerAdapter 问:"谁能处理这个 Content-Type?"
  3. 反序列化:选中的 Converter 把请求体变成 Java 对象
  4. 业务处理:Controller 方法执行
  5. 序列化:再选一个 Converter 把返回值变成响应体

冷知识AbstractMessageConverterMethodProcessor 是背后的"选妃"算法大师!


五、翻译官比武大会

Converter 类型特长弱点必杀技
MappingJackson2HttpMessageConverterJSON 处理循环引用会爆炸@JsonIgnore 救命符
GsonHttpMessageConverter轻量级 JSON功能较少配置简单就是美
StringHttpMessageConverter文本处理专家只能处理Stringtext/plain 领域无敌
ByteArrayHttpMessageConverter二进制忍者内存可能爆炸小文件瞬移术

选择困难症患者指南:默认用 Jackson,要轻量选 Gson,处理文本用 String,二进制用 ByteArray。


六、避坑指南:翻译官的恶作剧

1. 中文乱码の诅咒

// 解决方案:强制 UTF-8
@Bean
StringHttpMessageConverter stringConverter() {
    return new StringHttpMessageConverter(StandardCharsets.UTF_8);
}

现象:前端收到浣犲ソ的神秘代码
原因:默认使用 ISO-8859-1 编码的傲娇设定

2. 日期格式的时空错乱

// 在 application.properties 中
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

否则你的日期可能变成"火星时间"!

3. 循环引用の无限月读

@Entity
public class User {
    @ManyToOne
    @JsonIgnore // 用这个符咒打断循环
    private Department department;
}

否则 JSON 会变成"我中有你,你中有我"的莫比乌斯环!


七、最佳实践:与翻译官和谐相处

  1. 统一数据格式:团队约定只用 JSON,避免 XML 的"方言战争"
  2. 自定义配置:给 Jackson 穿上定制西装(配置日期格式、NULL 处理等)
  3. 异常处理:用@ExceptionHandler捕捉转换失败的异常
  4. 文件上传防护
    spring.servlet.multipart.max-file-size=10MB
    spring.servlet.multipart.max-request-size=10MB
    
    防止有人上传《清明上河图》高清扫描版!

八、面试考点:翻译官的秘密档案

Q1:HttpMessageConverter 的作用是什么?

:它是 HTTP 消息与 Java 对象之间的转换器,处理序列化与反序列化。(加分项:能说出处理流程)

Q2:如何自定义一个 Converter?

:继承AbstractHttpMessageConverter,重写readInternal()writeInternal()方法,然后注册到配置中。

Q3:文件上传用什么 Converter?

MultipartFile 类型由MultipartHttpMessageConverter处理,需要配合MultipartResolver使用。


九、终章:翻译官的生存哲学

HttpMessageConverter 就像程序世界的巴别鱼(《银河系漫游指南》中能实时翻译任何语言的生物),让不同的数据格式在 HTTP 的海洋中自由遨游。记住:

  • 不要挑战默认配置(除非你知道自己在做什么)
  • 统一格式是团队协作的基石
  • 异常处理是避免线上事故的护城河

最后送大家一句编程哲学:"好的框架设计,应该让复杂的事情变得像喝奶茶一样简单——你只需要关心珍珠要加多少,而不是怎么制作珍珠。" 🥤


🎉 彩蛋:试试在 Controller 返回Map<String, Object>,看看翻译官会怎么处理你的"即兴表演"?