自定义反序列化器在杰克逊的任何名单

我有一个列表中的错误对象的问题。 例如我有一个JSON模型:

{ "items": [ { "id": 1, "name": "Item1" }, { "id": 2, "name": "Item2" }, { "id": [], "name": "Item3" } ] } 

和两个POJO

 data class BadList(val items: List<BadItem>) data class BadItem(val id: Int, val name: String) 

当然,当解析器绊倒第三个元素时,我会得到异常

 com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.Integer out of START_ARRAY token at [Source: {"items":[{"id":1,"name":"Item1"},{"id":2,"name":"Item2"},{"id":[],"name":"Item3"}]}; line: 1, column: 19] (through reference chain: my.package.BadList["items"]->java.util.ArrayList[2]->my.package.BadItem["id"]) 

谁知道如何解决这个问题? 我想跳过那个错误的项目。

你可以编写一个自定义的deserializer并在其中实现反序列化逻辑,例如:

 class ItemIdDeserialiser extends JsonDeserializer<Integer> { @Override public Integer deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException { Object value = p.getCurrentValue(); //Check if it's Integer if(value instanceof Integer){ return (Integer) value; } return null; //Or return first element if it's a non empty list } } 

一旦完成,你可以使用@JsonDeserialise来注释这个字段来指导jackson使用你的类,例如:

 class Item { @JsonDeserialize(using = ItemIdDeserialiser.class) private Integer id; } 

更新

如果你只是想在序列化/反序列化中忽略这个字段,那么你可以用@JsonIgnore注释它,例如

 class Item { @JsonIgnore private Integer id; } 

或者更好,从pojo中删除id ,并在类上添加@JsonIgnoreProperties ,例如:

 @JsonIgnoreProperties(ignoreUnknown = true) class Item { } 

它会自动忽略json的属性,但在类中找不到。

您可以使用“HidableSerializer”来检查序列化过程中的数据

1.创建一个IHidable接口

该接口有一个在序列化过程中被调用的isHidden方法

 package ch.hasselba.jackson.test; public interface IHidable { public boolean isHidden(); } 

2.更改您的BadItem

添加接口并更改id的setter。 当属性id被反序列化时,会测试它是否为Integer。 如果不是,则该项目被标记为不良。

 package ch.hasselba.jackson.test; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties( {"hidden"} ) public class BadItem implements IHidable{ private Integer id; public String name; private boolean isBadItem; public Integer getId(){ return id; } public void setId(Object value){ if( value instanceof Integer ){ this.id = (Integer) value; }else{ this.isBadItem = true; } } public boolean isHidden() { return isBadItem; } } 

3.创建一个HidableSerializer

 package ch.hasselba.jackson.test; import java.io.IOException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; @SuppressWarnings("serial") public class HidableSerializer<T> extends StdSerializer<T> { private JsonSerializer<T> defaultSerializer; protected HidableSerializer(Class<T> t) { super(t); } public JsonSerializer<T> getDefaultSerializer() { return defaultSerializer; } public void setDefaultSerializer(JsonSerializer<T> defaultSerializer) { this.defaultSerializer = defaultSerializer; } @Override public void serialize(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { if( value instanceof IHidable ){ IHidable hidableValue = (IHidable) value; if( hidableValue.isHidden() ) return; } defaultSerializer.serialize(value, jgen, provider); } } 

4.注册HidableSerializer就是这样

 package ch.hasselba.jackson.test; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationConfig; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; public class Demo { @SuppressWarnings("serial") public static void main(String[] args) { // register the HidableSerializer ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_EMPTY); mapper.registerModule(new SimpleModule() { @Override public void setupModule(SetupContext context) { super.setupModule(context); context.addBeanSerializerModifier(new BeanSerializerModifier() { @Override public JsonSerializer<?> modifySerializer( SerializationConfig config, BeanDescription desc, JsonSerializer<?> serializer) { if (BadItem.class.isAssignableFrom(desc.getBeanClass())) { HidableSerializer ser = new HidableSerializer(BadItem.class); ser.setDefaultSerializer(serializer); return ser; } return serializer; } }); } }); String content = "{ \"items\": [ { \"id\": 1, \"name\": \"Item1\" }, { \"id\": 2, \"name\": \"Item2\" }, { \"id\":[], \"name\": \"Item3\" } ]}"; // build the Object BadList test = null; try { test = mapper.readValue(content, BadList.class); } catch (Exception e) { e.printStackTrace(); } // and now convert it back to a String String data = null; try { data = mapper.writeValueAsString(test); } catch (Exception e) { e.printStackTrace(); } // print the result System.out.println( data ); } } 

将id“[]”更改为Integer值时,显示Item,否则为空。

结果:

 {"items":[{"id":1,"name":"Item1"},{"id":2,"name":"Item2"}]}