Java 如何使用Jackson将字符串反序列化为自定义对象?
我有一个要解析的JSON:Java 如何使用Jackson将字符串反序列化为自定义对象?,java,json,jackson,jackson-databind,Java,Json,Jackson,Jackson Databind,我有一个要解析的JSON: { "name": "john", } 我必须使用以下层次结构。这些类是不可变的,我必须通过静态工厂方法访问它们(这是必需的,因此建议对Name或Person进行修改是没有意义的) 为此,我想用Jackson反序列化一个人,所以我写了以下内容: public class NameJsonDeserializer extends JsonDeserializer<Name> { @Override public
{
"name": "john",
}
我必须使用以下层次结构。这些类是不可变的,我必须通过静态工厂方法访问它们(这是必需的,因此建议对Name
或Person
进行修改是没有意义的)
为此,我想用Jackson反序列化一个人
,所以我写了以下内容:
public class NameJsonDeserializer extends JsonDeserializer<Name> {
@Override public Name deserialize(JsonParser parser, DeserializationContext context) {
var tree = parser.getCodec().readTree(parser);
var name = tree.asToken().asString();
return Name.valueOf(name);
}
}
public class PersonJsonDeserializer extends JsonDeserializer<Person> {
@Override public Person deserialize(JsonParser parser, DeserializationContext context) {
var tree = parser.getCodec().readTree(parser);
var name = (ObjectNode) tree.get("name");
return Person.create(name);
}
}
如何在不借助中间POJO的情况下进行反序列化?如果可以修改Person,可以使用@JsonCreator:
@JsonCreator
public static Person create(@JsonProperty("name") String name) {
Name nameInstance = Name.valueOf(name);
return new Person(nameInstance);
}
这将正确地使用JSON,将“name”属性映射到方法的第一个参数
如果无法修改该类,则可以使用mixin方法,创建mixin:
interface PersonMixin {
@JsonCreator
public static Person create(@JsonProperty("name") Name name) {return null;}
}
并在映射器中注册它:
mapper.addMixIn(Person.class, PersonMixin.class);
如果可以修改Person,可以使用@JsonCreator:
@JsonCreator
public static Person create(@JsonProperty("name") String name) {
Name nameInstance = Name.valueOf(name);
return new Person(nameInstance);
}
这将正确地使用JSON,将“name”属性映射到方法的第一个参数
如果无法修改该类,则可以使用mixin方法,创建mixin:
interface PersonMixin {
@JsonCreator
public static Person create(@JsonProperty("name") Name name) {return null;}
}
并在映射器中注册它:
mapper.addMixIn(Person.class, PersonMixin.class);
对于
NameDeserializer
我必须使用parser.getValueAsString()
,对于personderializer
我必须使用codec.treeToValue()
:
公共类名称JsonDeserializer扩展JsonDeserializer{
@重写公共名称反序列化(JsonParser解析器,反序列化上下文){
var name=parser.getValueAsString();
返回名称。valueOf(名称);
}
}
公共类PersonJsonDeserializer扩展JsonDeserializer{
@重写公共人物反序列化(JsonParser解析器,反序列化上下文){
var codec=parser.getCodec();
var-tree=codec.readTree(解析器);
var name=codec.treeToValue(tree.get(“name”)、name.class);
返回人。创建(名称);
}
}
我必须为名称反序列化程序使用解析器.getValueAsString()
,为PersonDeserializer
使用编解码器.treeToValue()
:
公共类名称JsonDeserializer扩展JsonDeserializer{
@重写公共名称反序列化(JsonParser解析器,反序列化上下文){
var name=parser.getValueAsString();
返回名称。valueOf(名称);
}
}
公共类PersonJsonDeserializer扩展JsonDeserializer{
@重写公共人物反序列化(JsonParser解析器,反序列化上下文){
var codec=parser.getCodec();
var-tree=codec.readTree(解析器);
var name=codec.treeToValue(tree.get(“name”)、name.class);
返回人。创建(名称);
}
}
不,这些类是不可变的,我不能修改它们。这就是为什么我说我必须通过静态工厂方法访问它们。此外,这也不能满足在不修改所有内容的情况下一致地反序列化Name
的需要。不可变和不能修改java类文件是完全不同的事情。我将添加一个mixin示例,以防您发现它有价值。的确,但我说过“我必须通过静态工厂方法访问它们”。因此,我认为mixin是一个比前一个更好的解决方案,但它仍然不能解决名称部分的任何问题。不,类是不可变的,我不能修改它们。这就是为什么我说我必须通过静态工厂方法访问它们。此外,这也不能满足在不修改所有内容的情况下一致地反序列化Name
的需要。不可变和不能修改java类文件是完全不同的事情。我将添加一个mixin示例,以防您发现它有价值。的确,但我说过“我必须通过静态工厂方法访问它们”。因此,我猜想mixin是一个比前一个更好的解决方案,但它仍然不能回答名称
部分的任何问题。