英文:
Use Jackson deserializer to read child JSON object
问题
I have a Spring Boot application with Jackson dependency, and a Service with this code:
Dto dto = new ObjectMapper().readValue(jsonString, Dto.class);
I have a JSON similar to this one:
{
"meta": {
...
},
"results": [
{
"id": {"raw": "1"},
"name": {"raw": "Hello World"}
"number": {"raw": 7.5}
}
]
}
And I have a Java class like this one:
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
}
Then, I have a generic Wrapper class like this one (idea from Baeldung: https://www.baeldung.com/jackson-deserialization ):
@JsonDeserialize(using = WrapperDeserializer.class)
public class Wrapper<T> {
T value;
// getters/setters
}
Lastly, I have the next deserializer:
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;
}
}
The main doubt is, how I can access to jsonParser object in order to get the child JSON information? In this case, I would like to access {"raw": "1"}
, so I could get the child into "raw" key and get the proper value, so ID "1" would be saved in final Java object.
I wouldn't want to make deserializationContext.readValue(jsonParser, type)
as in this example, because it would throw this error:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
at [Source:
Because {"raw": "1"}
is not a valid String. I would want to have only the "1" value.
英文:
I have a Spring Boot application with Jackson dependency, and a Service with this code:
Dto dto = new ObjectMapper().readValue(jsonString, Dto.class);
I have a JSON similar to this one:
{
"meta": {
...
},
"results": [
{
"id": {"raw": "1"},
"name": {"raw": "Hello World"}
"number": {"raw": 7.5}
}
]
}
And I have a Java class like this one:
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
}
Then, I have a generic Wrapper class like this one (idea from Baeldung: https://www.baeldung.com/jackson-deserialization ):
@JsonDeserialize(using = WrapperDeserializer.class)
public class Wrapper<T> {
T value;
// getters/setters
}
Lastly, I have the next deserializer:
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;
}
}
The main doubt is, how I can access to jsonParser object in order to get the child JSON information? In this case, I would like to access {"raw": "1"}
, so I could get the child into raw key and get the proper value, so ID "1" would be saved in final Java object.
I wouldn't want to make deserializationContext.readValue(jsonParser, type)
as in this example, because it would throw this error:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)
at [Source:
Because {"raw": "1"}
is not a valid String. I would want to have only the "1" value.
答案1
得分: 1
你已经非常接近了。主要问题是你在字段名称 value
处使用了,实际应该是 raw
。另外,WrapperDeserializer
不是必要的。
所有代码都按你的要求,除了以下部分:
Wrapper.java
public class Wrapper<T> {
T raw;
// getters, setters & toString()
}
main
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
String json = "{
"results": [
{
"id": {"raw": "1"},
"name": {"raw": "Hello World"},
"number": {"raw": 7.5}
}
]
}";
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.5]]]]
英文:
You are really close. The main issue is that you used the field name value
where it should be raw
. Also, the WrapperDeserializer
is not required.
All the code is as you have it besides the following:
Wrapper.java
public class Wrapper<T> {
T raw;
// getters, setters & toString()
}
main
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);
}
Output
Dto [results=[ResultDto [id=Wrapper [raw=1], name=Wrapper [raw=Hello World], number=Wrapper [raw=7]]]]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论