Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用Jackson将字符串反序列化为自定义对象?_Java_Json_Jackson_Jackson Databind - Fatal编程技术网

Java 如何使用Jackson将字符串反序列化为自定义对象?

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

我有一个要解析的JSON:

{
 "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是一个比前一个更好的解决方案,但它仍然不能回答
名称
部分的任何问题。