有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

带JsonDeserializer的java Lombok

我有一个JSON字符串,我想反序列化到一个类中。JSON看起来是这样的:

{ "data": { "name": "Box 1", "size": "10x20" } }

我可以将其反序列化为以下类:

@Builder
@Value
@JsonDeserialize(builder = Box1.Box1Builder.class)
public class Box1 {

    @JsonProperty("data")
    Box1Data data;

    public static Box1 of(String json) throws IOException {
        return new ObjectMapper().readValue(json, Box1.class);
    }

    @Builder
    @Value
    @JsonDeserialize(builder = Box1Data.Box1DataBuilder.class)
    static class Box1Data {

        @JsonProperty("name")
        String name;

        @JsonProperty("size")
        String size;

    }

}

上面的类看起来很笨拙,因为它有一个无用的data层次结构。我可以这样摆脱它:

@Builder
@Value
@JsonDeserialize(using = Box2Deserializer.class)
public class Box2 {

    @JsonProperty("name")
    String name;

    @JsonProperty("size")
    String size;

    public static Box2 of(String json) throws IOException {
        return new ObjectMapper().readValue(json, Box2.class);
    }

    static class Box2Deserializer extends JsonDeserializer<Box2> {

        @Override
        public Box2 deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            var node = jsonParser.getCodec().readTree(jsonParser);
            var dataNode = node.get("data");
            return Box2.builder()
                    .name(dataNode.get("name").toString())
                    .size(dataNode.get("size").toString())
                    .build();
        }
    }

}

但在这里,我遇到了死胡同。我希望将size字段解析为Dimension实例。我可以为size编写一个自定义的反序列化程序,它解析一个String并返回一个正确的Dimension,但我不能通过字段注释(@JsonDeserialize(using = SizeDeserializer.class))使用它,因为JsonDeserialize类注释的存在迫使Box1忽略它,而Box2则忽略它,因为我正在手动构建框

有没有一个优雅的解决方案?我想要的是将给定的JSON读入如下类:

@Builder
@Value
public class Box3 {

    @JsonProperty("name")
    String name;

    @JsonProperty("size")
    Dimension size;

    public static Box3 of(String json) {
        ...
    }

}

谢谢

阿西姆


共 (1) 个答案

  1. # 1 楼答案

    实际上,您不需要自定义反序列化程序和@JsonDeserialize注释。ObjectMapper提供了一种配置,可以使用包装器对象类上的@JsonRootName注释来包装/展开根值

    @Builder
    @Value
    @JsonRootName("data")
    public class Box {
    
        @JsonProperty("name")
        String name;
    
        @JsonProperty("size")
        String size;
    
        public static Box of(String json) throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
            return mapper.readValue(json, Box.class);
        }
    }
    

    PS:完全错过了问题中的Dimension部分,因此,您可以使用其他答案中提到的自定义反序列化程序