字段写了 @JSONField,接口却没有按预期输出,先确认响应究竟由谁序列化。Fastjson 的注解不会因为存在于 DTO 中,就自动影响 Jackson;Spring MVC 最终选中的 HttpMessageConverter 才决定这次响应使用哪套规则。
原问题与新增 MVC 配置有关
旧 Spring Boot 2.x 工程原本使用 Fastjson,后来加了 MVC 配置,注解表现发生变化。这里要检查新增的 @EnableWebMvc、转换器注册方法及转换器顺序,而不能简单归结为“实现 WebMvcConfigurer 会让注解失效”。
在 Boot 中,通常用 WebMvcConfigurer 做增量配置;@EnableWebMvc 则意味着接管 MVC 配置,可能改变自动配置参与方式。Boot MVC 配置说明
先选定 JSON 技术,再写对应注解
例如这个 DTO 的 display_name 是 Fastjson 注解表达的输出名:
import com.alibaba.fastjson.annotation.JSONField;
public class Profile {
@JSONField(name = "display_name")
public String displayName;
}
若接口实际使用 Jackson,应改用对应的 @JsonProperty(“display_name”),或统一既有工程的转换器配置。不要为了让一个字段生效就同时注册多套 JSON 转换器而不检查选择顺序。
下面仅用于解释已有 Fastjson 1.x、Spring 5.x 旧工程的配置方式,不作为新工程选择依赖的建议:
import java.util.Collections;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
@Configuration
public class LegacyJsonConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter json = new FastJsonHttpMessageConverter();
json.setSupportedMediaTypes(
Collections.singletonList(MediaType.APPLICATION_JSON));
converters.add(0, json);
}
}
该示例把此转换器放在首位并限于 application/json,因此会影响符合条件的其他响应,不只是一个 DTO。已有系统应用前,应确认预期的字符串、字节和 JSON 响应不会被改变。不要开启不受控的多态反序列化能力来处理注解问题。
configure 与 extend 的区别
configureMessageConverters 在配置非空列表时会影响 MVC 创建默认转换器的流程;extendMessageConverters 用于调整已经准备好的列表。随意 clear 后只放两个转换器,可能丢失其他响应格式的能力。Spring 5.3 消息转换器说明
静态资源映射也应独立检查,不能因为 JSON 异常就暴露任意磁盘目录。验证应直接观察响应 Content-Type 和原始 JSON,同时分别检查普通 DTO、字符串与错误响应;只看 Java 对象的调试视图不足以确认序列化结果。