0

我有一个由 Elixir 类创建的 JSON,它有一个可以是字符串或数组的字段:

field :logs, {:array, :string}

如果有人不明白这一点,那就是

{"logs" : "some log 1"}

或者

{
"logs": ["some log 1", "some log 2"]
}

我为此映射了一个 Java 字段:

@JsonProperty("logs")
private String logs;

此映射仅在logs作为 a 出现时才有效String,但如果logs出现array错误并指出它无法转换START_ARRAYstring.

如果字段以数组形式出现,如何序列化字段并将其存储为逗号分隔的字符串?

4

1 回答 1

0

我在标签中看到您使用 Jackson 进行解析。这意味着您需要为您的logs领域编写自定义反序列化器并向 Jackson 注册。

这种解决方案的一个例子:

package tmp;

import java.io.IOException;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ValueNode;

public class JacksonDemo {

    public static class LogHolder {
        @JsonProperty("logs")
        @JsonDeserialize(using = ArrayOrStringJsonDeserializer.class)
        private String logs;

        @Override
        public String toString() {
            return "LogHolder(logs=" + logs + ")";
        }
    }

    public static class ArrayOrStringJsonDeserializer extends JsonDeserializer<String> {

        @Override
        public String deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            JsonNode node = (JsonNode) jsonParser.readValueAsTree();
            if (node.isValueNode()) {
                ValueNode valueNode = (ValueNode) node;
                if (valueNode.isTextual()) {
                    return valueNode.textValue();
                }
            } else if (node.isArray()) {
                ArrayNode arrayNode = (ArrayNode) node;
                return StreamSupport.stream(Spliterators.spliteratorUnknownSize(arrayNode.iterator(), Spliterator.ORDERED), false)
                        .map(JsonNode::textValue)
                        .collect(Collectors.joining(", "));
            }
            throw MismatchedInputException.from(jsonParser, String.class,
                    "Expected node to be of type String or array, but got " + node.getNodeType().toString());
        }

    }

    public static void main(String args[]) throws Exception {
        String[] docs = { "{\"logs\" : \"some log 1\"}", "{\"logs\": [\"some log 1\", \"some log 2\"]}" };

        ObjectMapper om = new ObjectMapper();
        for (String doc : docs) {
            System.out.println(om.readValue(doc, LogHolder.class));
        }
    }
}

执行此代码的结果:

LogHolder(logs=some log 1)
LogHolder(logs=some log 1, some log 2)
于 2021-09-28T18:39:35.203 回答