Java JSON解析:忽略部分参数及字符串转Date适配不可修改POJO
解决方案:忽略JSON冗余参数 + 带时区日期转Date(不修改POJO)
没问题,这两个需求都有成熟的实现方案,我分场景给你详细说明:
一、忽略JSON中无需使用的参数
这取决于你使用的JSON序列化/反序列化库,主流的Jackson和Gson都有对应的配置方式,而且完全不需要修改原有POJO:
1. 如果你用Jackson
有两种灵活的方式:
- 全局配置(推荐):在初始化
ObjectMapper时关闭“未知字段报错”的特性,这样所有反序列化操作都会自动忽略POJO中不存在的JSON参数:ObjectMapper objectMapper = new ObjectMapper(); // 关闭未知字段导致反序列化失败的特性 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - 局部类配置(如果不想全局生效):如果只想针对某个POJO忽略未知字段,但又不能修改POJO本身,可以用MixIn特性:
先创建一个MixIn接口,加上@JsonIgnoreProperties(ignoreUnknown = true)注解:
然后把这个MixIn绑定到目标POJO:@JsonIgnoreProperties(ignoreUnknown = true) public interface YourPOJOMixIn {}objectMapper.addMixIn(YourPOJO.class, YourPOJOMixIn.class);
2. 如果你用Gson
Gson默认就会自动忽略POJO中不存在的JSON参数,不需要额外配置。如果之前修改过默认设置,重置一下即可:
Gson gson = new GsonBuilder().create();
二、处理带时区的字符串转Date(不修改POJO)
如果不想忽略这个日期字段,而是要把"2018-02-09 03:05:20 EST"这样的字符串转成Date类型,同样可以通过自定义反序列化器实现,完全不影响原有POJO的使用:
1. Jackson实现
自定义一个日期反序列化器,然后注册到ObjectMapper:
public class ESTDateDeserializer extends JsonDeserializer<Date> { // 匹配目标日期格式,指定Locale.US避免EST时区解析出错 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z") .withLocale(Locale.US); @Override public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String dateStr = p.getText(); // 解析为带时区的时间,再转成Date类型 ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStr, FORMATTER); return Date.from(zonedDateTime.toInstant()); } }
然后注册到ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); // 给Date类型绑定自定义反序列化器 module.addDeserializer(Date.class, new ESTDateDeserializer()); objectMapper.registerModule(module);
用这个配置好的objectMapper反序列化时,就会自动把目标格式的字符串转成Date,原有POJO完全不用改,其他地方使用POJO也不受影响。
2. Gson实现
类似地,自定义Gson的日期反序列化器:
Gson gson = new GsonBuilder() .registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { private final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z") .withLocale(Locale.US); @Override public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String dateStr = json.getAsString(); ZonedDateTime zonedDateTime = ZonedDateTime.parse(dateStr, FORMATTER); return Date.from(zonedDateTime.toInstant()); } }) .create();
用这个gson实例反序列化即可完成格式转换。
三、如果想直接忽略这个日期字段
如果完全不需要这个日期参数,可以针对性地排除它,同样不用修改POJO:
- Jackson:用MixIn给目标字段加
@JsonIgnore:
然后绑定到ObjectMapper:public interface YourPOJOMixIn { @JsonIgnore Date getDateFieldName(); // 替换成POJO中对应日期字段的getter方法名 }objectMapper.addMixIn(YourPOJO.class, YourPOJOMixIn.class); - Gson:用
ExclusionStrategy排除指定字段:Gson gson = new GsonBuilder() .setExclusionStrategies(new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { // 替换成POJO中日期字段的名称 return "dateFieldName".equals(f.getName()); } @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } }) .create();
内容的提问来源于stack exchange,提问作者newbee
相关产品推荐
相关产品推荐

