我有一个像
这样的JSON对象{
"id" : "1",
"children" : ["2","3"]
}
我有一个Java对象(省略了构造函数,getter和setter):
public class Entity {
public String id;
public String children;
}
我希望使用Jackson代码将此JSON反序列化为我的Java对象:
Entity entity = mapper.readValue(json, Entity.class);
但是得到以下错误:
Can not deserialize instance of java.lang.String out of START_ARRAY token
如何在不更改children
字段类型的情况下解决问题?
children
字段应具有以下值:["2","3"]
。
答案 0 :(得分:2)
创建自定义反序列化器以获取原始JSON值。您可以根据需要选择以下实现之一:
public class RawJsonDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
long begin = jp.getCurrentLocation().getCharOffset();
jp.skipChildren();
long end = jp.getCurrentLocation().getCharOffset();
String json = jp.getCurrentLocation().getSourceRef().toString();
return json.substring((int) begin - 1, (int) end);
}
}
public class RawJsonDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
ObjectMapper mapper = (ObjectMapper) jp.getCodec();
return mapper.writeValueAsString(node);
}
}
通过引用Entity
属性并使用children
引用上面定义的反序列化器来更改@JsonDeserialize
类:
public class Entity {
public String id;
@JsonDeserialize(using = RawJsonDeserializer.class)
public String children;
}
然后使用ObjectMapper
解析JSON,Jackson将使用您的自定义反序列化器:
String json = "{\"id\":\"1\",\"children\":[\"2\",\"3\"]}";
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper.readValue(json, Entity.class);
children
属性的值为["2","3"]
。
有关详细信息,请查看此question。
答案 1 :(得分:1)
将您的对象转换为JSON格式。
然后从JSON文件解组
public interface MarshallingSupport {
public String marshal(Object object);
public <T> T unmarshal(String s, Class<T> t);
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class JacksonJSONMarshallingSupport implements MarshallingSupport {
private final ObjectMapper mapper;
public JacksonJSONMarshallingSupport(ObjectMapper mapper) {
this.mapper = mapper;
this.mapper.getFactory().configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
}
@Override
public String marshal(Object object) {
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException ex) {
throw new RuntimeException(ex);
}
}
@Override
public <T> T unmarshal(String s, Class<T> t) {
try {
T newObj = mapper.readValue(s, t);
return newObj;
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
答案 2 :(得分:1)
接受@ Cassio的回答,如果你不想或你不能注释你的实体类,只需添加一些配置。
首先创建一个抽象类[for method annotation purpose you can create an interface, but in this case we will annotate a bean property so we create an abstract class, and if you also want to annotate a method in this abstract class you have to declare that method as abstract
],就像Jackson配置的mime bean一样:
public abstract class EntityMixIn {
@JsonDeserialize(using = RawJsonDeserializer.class)
public String children;
}
现在,你必须告诉你的mapper采用这个mixin类,并且只是为了这个配置目的而像原始的Entity类一样:
mapper.addMixIn(Entity.class, EntityMixIn.class);