Spring Boot 使用Jackson反序列化器读取子JSON对象

idfiyjo8  于 2023-04-11  发布在  Spring
关注(0)|答案(1)|浏览(236)

我有一个带有Jackson依赖项的Sping Boot 应用程序,以及一个带有以下代码的Service:

Dto dto = new ObjectMapper().readValue(jsonString, Dto.class);

我有一个类似的JSON:

{
    "meta": {
    ...
    },
    "results": [
        {
            "id": {"raw": "1"},
            "name": {"raw": "Hello World"}
            "number": {"raw": 7.5}
        }
    ]
}

我有一个类似这样的Java类:

public class Dto {
    private AnotherDto meta;
    private List<ResultDto> results;
    // getters/setters
}
public class ResultDto {
    @JsonProperty("id")
    private Wrapper<String> id;

    // More fields and getters/setters
}

然后,我有一个像这样的通用 Package 器类(来自Baeldung的想法:https://www.baeldung.com/jackson-deserialization):

@JsonDeserialize(using = WrapperDeserializer.class)
public class Wrapper<T> {
    T value;
    // getters/setters
}

最后,我有下一个反序列化器:

public class WrapperDeserializer extends JsonDeserializer<Wrapper<?>> implements ContextualDeserializer {
    private JavaType type;

    @Override
    public Wrapper<?> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException {
        Wrapper<?> wrapper = new Wrapper<>();
        wrapper.setValue(deserializationContext.readValue(jsonParser, type));
        return wrapper;
    }

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext deserializationContext, BeanProperty beanProperty) throws JsonMappingException {
        this.type = beanProperty.getType().containedType(0);
        return this;
    }
}

主要的疑问是,我如何才能访问jsonParser对象以获取子JSON信息?在本例中,我想访问{"raw": "1"},这样我就可以将子对象放入 raw key并获取正确的值,因此ID“1”将保存在最终的Java对象中。
我不想像这个例子中那样生成deserializationContext.readValue(jsonParser, type),因为它会抛出这个错误:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
 at [Source:

因为{"raw": "1"}不是一个有效的字符串。我希望只有“1”值。

xu3bshqb

xu3bshqb1#

你真的很接近。主要问题是你使用了字段名value,而它应该是raw。此外,WrapperDeserializer不是必需的。
所有的代码都是你所拥有的,除了以下内容:

Wrapper.java

public class Wrapper<T> {

    T raw;
  
    // getters, setters & toString()
}

主要

public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
    
        ObjectMapper objectMapper = new ObjectMapper();
        
        String json = "{\r\n" + 
                "    \"results\": [\r\n" + 
                "        {\r\n" + 
                "            \"id\": {\"raw\": \"1\"},\r\n" + 
                "            \"name\": {\"raw\": \"Hello World\"},\r\n" + 
                "            \"number\": {\"raw\": 7.5}\r\n" + 
                "        }\r\n" + 
                "    ]\r\n" + 
                "}";
        
        Dto readValue = objectMapper.readValue(json, Dto.class);
        
        System.out.println(readValue);
}

输出

Dto [results=[ResultDto [id=Wrapper [raw=1], name=Wrapper [raw=Hello World], number=Wrapper [raw=7]]]]

相关问题