将JSON对象写入lombok对象

ac1kyiln  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(172)

我有一个问题,将Json对象写入lombok对象。这里是我的Json对象:

```{"id": "1","name":"home","order": "1","isSubMenu": false,"path":"home","subMenu": null},{"id": "2","name":"user","order": "2","isSubMenu": false,"path":"usermanagement" ,"subMenu": [{"id": "21","name":"access","order": "1","isSubMenu": true,"path":"access" ,"subMenu": null},{"id": "22","name":"user","order": "2","isSubMenu": true,"path":"group" ,"subMenu": null},{"id": "23","name":"group","order": "3","isSubMenu": true,"path":"user" ,"subMenu": null}]}}```

我的Lombok岛:

@Value
@JsonDeserialize()
@JsonIgnoreProperties(ignoreUnknown = true)
public class Menu {
    private  String id;
    private  String name;
    private  Integer order;
    private  Boolean isSubMenu;
    private  String path;
    private List<Menu> subMenuList;
}```

and my service:
```ObjectMapper mapper = new ObjectMapper();
            Menu menu = mapper.convertValue(outPutObject, Menu.class);

最后,我的例外:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.barman.framework.model.Menu (no Creators, like default constructor, exist): no String-argument constructor/factory method to deserialize from String value ('')at [Source: UNKNOWN; line: -1, column: -1]

vjhs03f7

vjhs03f71#

当你用lomboks @Value注解你的类时,这意味着你定义你的类是不可变的,这意味着构造函数必须初始化所有成员(lombok会把它们装饰成final)。Jackson默认反序列化器的工作原理是调用一个空构造函数,然后在每个与JSON中的字段匹配的成员上调用setter。如果没有默认的构造函数(你在lomboks @value中不会有这个构造函数),那么它会抛出你看到的错误。
你基本上有两个选择:

1.快速和肮脏:

更换

@Value

@Data
@NoArgConstructor

但是这会破坏类的设计,因为它不再是不可变的(因为@Data添加了setter)。您将需要评估这对于您的设计是否可接受。

2.创建自定义反序列化器:

在菜单类中,将@JsonDeserialize更新为:

@JsonDeserialize(using = MenuDeserializer.class)

然后定义你的Deserializer如下:

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;

import java.io.IOException;
import java.util.List;

public class MenuDeserializer extends JsonDeserializer<Menu> {

    @Override
    public Menu deserialize(JsonParser jp, DeserializationContext deserializationContext) throws IOException, JacksonException {
        JsonNode node = jp.getCodec().readTree(jp);

        ObjectReader reader = new ObjectMapper().readerFor(new TypeReference<List<Menu>>() {        });
        return new Menu(
                node.get("id").asText(),
                node.get("name").asText(),
                node.get("order").asInt(),
                node.get("isSubMenu").asBoolean(),
                node.get("path").asText(),
                reader.readValue(node.get("subMenuList"))
        );
    }
}

这个选项是更多的代码和faff,但你保持不变,这是所有酷孩子做的

相关问题