Spring中@RequestBody无法反序列化含别名的JSON字段问题
Patch请求DTO多字段反序列化问题分析与解决
问题原因
你在DTO中使用了Gson的@SerializedName(alternate)注解来支持多字段名映射,但Spring Boot默认使用Jackson作为@RequestBody的JSON反序列化器,Jackson并不识别Gson的@SerializedName注解。因此当请求传入requestNo时,Jackson找不到对应的映射字段,导致requestNumber始终为null;而requestNumber能正常工作,是因为Jackson默认会匹配字段名(或@JsonProperty指定的名称)。
解决办法
有两种可行方案,可根据你的实际需求选择:
方案1:切换Spring Boot的JSON处理器为Gson
既然你的DTO原本是为Gson设计的,可以让Spring Boot使用Gson处理JSON序列化/反序列化,这样@SerializedName(alternate)的配置就能直接生效。
配置方式一:通过application.properties
在配置文件中添加以下配置:
spring.http.converters.preferred-json-mapper=gson
配置方式二:通过Java配置类
自定义Gson消息转换器,还可按需配置Gson的序列化规则:
@Configuration public class GsonConverterConfig { @Bean public GsonHttpMessageConverter gsonHttpMessageConverter() { GsonHttpMessageConverter converter = new GsonHttpMessageConverter(); converter.setGson(new GsonBuilder().create()); return converter; } }
方案2:改用Jackson的注解实现多字段映射
如果不想替换默认的Jackson,可以使用Jackson的@JsonAlias注解实现多字段名映射,同时保留Gson注解以兼容其他系统。
修改后的RequestDTO代码:
@Data public class RequestDTO { String name; // 保留Gson注解以兼容其他使用Gson的系统 @SerializedName(value = "requestNumber", alternate = {"requestNo"}) // Jackson主字段名配置+别名配置 @JsonProperty("requestNumber") @JsonAlias({"requestNo"}) String requestNumber; }
这样Jackson会同时识别requestNumber和requestNo两个字段名,Gson也能正常解析,满足多系统兼容的需求。
内容的提问来源于stack exchange,提问作者Mandar
相关产品推荐
相关产品推荐

