如何反序列化json对象数组为json字符串数组? [英] How deserialize json object array as array of json strings?
问题描述
考虑json输入:
{
companies: [
{
"id": 1,
"name": "name1"
},
{
"id": 1,
"name": "name1"
}
],
nextPage: 2
}
如何将其反序列化为类:
How deserialize this into class:
public class MyClass {
List<String> companies;
Integer nextPage;
}
List<String> companies;
由字符串组成:
{"id": 1,"name": "name1"}
{"id": 1,"name": "name1"}
@JsonRawValue
不适用于List<String> companies;
是否可以配置 Jackson 序列化,以使公司仅使用带有注释的原始json字符串进行排列? (例如,无需编写自定义反序列化器)
Is there a way to configure Jackson serialization to keep companies array with raw json string with annotations only? (E.g. without writing custom deserializator)
推荐答案
没有针对您问题的仅注释解决方案.您必须以某种方式将JSON Object
转换为java.lang.String
,并且需要指定该转换.
There is no annotation-only solution for your problem. Somehow you have to convert JSON Object
to java.lang.String
and you need to specify that conversion.
您可以:
- 编写自定义反序列化器,这可能是最明显的解决方案,但被禁止使用.
- 注册自定义
com.fasterxml.jackson.databind.deser.DeserializationProblemHandler
并以更复杂的方式处理com.fasterxml.jackson.databind.exc.MismatchedInputException
情况. - 实现
com.fasterxml.jackson.databind.util.Converter
接口并将JsonNode
转换为String
.这是解决问题的半注释方式,但我们不会执行最糟糕的部分-反序列化.
- Write custom deserializer which is probably most obvious solution but forbidden in question.
- Register custom
com.fasterxml.jackson.databind.deser.DeserializationProblemHandler
and handlecom.fasterxml.jackson.databind.exc.MismatchedInputException
situation in more sophisticated way. - Implement
com.fasterxml.jackson.databind.util.Converter
interface and convertJsonNode
toString
. It is semi-annotational way to solve a problem but we do not implement the worst part - deserialisation.
让我们马上转到第2点.
Let's go to point 2. right away.
解决方案非常简单:
ObjectMapper mapper = new ObjectMapper();
mapper.addHandler(new DeserializationProblemHandler() {
@Override
public Object handleUnexpectedToken(DeserializationContext ctxt, JavaType targetType, JsonToken t, JsonParser p, String failureMsg) throws IOException {
if (targetType.getRawClass() == String.class) {
// read as tree and convert to String
return p.readValueAsTree().toString();
}
return super.handleUnexpectedToken(ctxt, targetType, t, p, failureMsg);
}
});
将整个JSON
读取为TreeNode
,然后使用toString
方法将其转换为String
.有用的是,toString
会生成有效的JSON
.缺点是,此解决方案具有给定ObjectMapper
实例的全局范围.
Read a whole piece of JSON
as TreeNode
and convert it to String
using toString
method. Helpfully, toString
generates valid JSON
. Downside, this solution has a global scope for given ObjectMapper
instance.
此解决方案需要实现com.fasterxml.jackson.databind.util.Converter
接口,该接口将com.fasterxml.jackson.databind.JsonNode
转换为String
:
This solution requires to implement com.fasterxml.jackson.databind.util.Converter
interface which converts com.fasterxml.jackson.databind.JsonNode
to String
:
class JsonNode2StringConverter implements Converter<JsonNode, String> {
@Override
public String convert(JsonNode value) {
return value.toString();
}
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return typeFactory.constructType(new TypeReference<JsonNode>() {
});
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return typeFactory.constructType(new TypeReference<String>() {
});
}
}
现在,您可以使用如下注释:
and now, you can use annotation like below:
@JsonDeserialize(contentConverter = JsonNode2StringConverter.class)
private List<String> companies;
解决方案2和3.几乎以相同的方式解决此问题-读取节点并将其转换回JSON
,但是使用不同的方法.
Solutions 2. and 3. solve this problem almost in the same way - read node and convert it back to JSON
, but uses different approaches.
如果要避免反序列化和序列化过程,可以看一下本文提供的解决方案:
If, you want to avoid deserialising and serialising process you can take a look on solution provided in this article: Deserializing JSON property as String with Jackson and take a look at:
- How to serialize JSON with array field to object with String field?
- How to get a part of JSON as a plain text using Jackson
- How to extract part of the original text from JSON with Jackson?
这篇关于如何反序列化json对象数组为json字符串数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!