GSON序列化DTO输出为空的原因及解决方案咨询
问题分析与解决方案
问题场景
你的代码如下:
@Bean public GsonBuilder gsonBuilder(List <GsonBuilderCustomizer> customizers) { GsonBuilder builder = new GsonBuilder(); customizers.forEach((c) -> c.customize(builder)); builder .serializeNulls() .excludeFieldsWithoutExposeAnnotation() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES); } @AllArgsConstructor @Getter @Setter @NoArgsConstructor public class ModelStepInfo { public boolean isSuccessed; public String description; public LocalDateTime startTime; public LocalDateTime endTime; } gson.toJson(new ModelStepInfo(false, "dasdsada", LocalDateTime.now(), LocalDateTime.now()))
Gson版本2.10.1,执行后输出{},序列化结果为空。
核心问题
GsonBuilder配置方法未返回实例
你的@Bean方法定义返回GsonBuilder,但代码末尾没有return builder;语句,导致Spring无法注入正确的配置实例,实际使用的Gson可能不符合预期。字段被强制排除序列化
配置了.excludeFieldsWithoutExposeAnnotation(),但ModelStepInfo的所有字段都未添加@Expose注解,Gson会排除所有未标记的字段,最终输出空对象。Java 8时间类型不支持
Gson默认无法序列化LocalDateTime,即使字段问题解决,也会出现序列化异常或无效结果。
解决方案
步骤1:修复GsonBuilder的返回问题
确保@Bean方法返回配置完成的GsonBuilder实例:
@Bean public GsonBuilder gsonBuilder(List<GsonBuilderCustomizer> customizers) { GsonBuilder builder = new GsonBuilder(); customizers.forEach(c -> c.customize(builder)); builder .serializeNulls() .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .registerModule(new JavaTimeModule()); // 注册Java 8时间模块 // 可选:如果需要保留字段排除规则,后续给实体字段加@Expose注解 // .excludeFieldsWithoutExposeAnnotation(); return builder; // 必须返回builder实例 }
步骤2:解决字段被排除问题
有两种可选方案:
方案A:移除字段排除配置
不需要仅序列化带@Expose的字段时,直接删除.excludeFieldsWithoutExposeAnnotation(),Gson会自动序列化所有public字段或通过@Getter可访问的字段。方案B:给实体字段添加@Expose注解
必须保留字段排除规则时,给ModelStepInfo的每个字段添加@Expose:import com.google.gson.annotations.Expose; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import java.time.LocalDateTime; @AllArgsConstructor @Getter @Setter @NoArgsConstructor public class ModelStepInfo { @Expose public boolean isSuccessed; @Expose public String description; @Expose public LocalDateTime startTime; @Expose public LocalDateTime endTime; }
步骤3:处理LocalDateTime序列化
Gson 2.10.1内置了JavaTimeModule,只需在GsonBuilder中注册该模块,即可正确序列化/反序列化Java 8日期时间类型。
验证效果
修正后执行序列化代码,会得到类似如下的有效输出:
{ "is_successed": false, "description": "dasdsada", "start_time": "2024-05-20T14:30:00", "end_time": "2024-05-20T14:30:00" }
内容的提问来源于stack exchange,提问作者JOJU
相关产品推荐
相关产品推荐

