Я должен десериализовать Json для объекта POJO.Я создал пользовательскую десериализацию, но не достаточно универсальный, согласно моему требованию - PullRequest
0 голосов
/ 19 июня 2019

Я должен десериализовать Json для объекта POJO. Я создал пользовательскую десериализацию, которая работает нормально, но я хочу, чтобы мой пользовательский десериализатор был достаточно универсальным, чтобы можно было обрабатывать десериализацию по умолчанию.

Я уже просмотрел много статей, но не смог получить именно то, что хотел.

У меня есть два типа полезной нагрузки Json

{
  "encrypted":{
    "credentials":{
      "accessKey":"AKW2Q",
      "accessSecret":"4esEpRyBeAycy108rpu7A7NAjzJ",
      "bucket":"lohit"
    }
  }
}

{
  "version":"v2",
  "encrypted":{
    "credentials":{
      "accessKeyId":"AKW2Q",
      "accessKeySecret":"4esEpRyBeAycy108rpu7A7NAjzJ",
      "clientBucket":"lohit"
    }
  }
}

Мой класс по учету

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JsonDeserialize(using = CredentialDeserializer.class)
public class Credentials {
    public String accessKeyId;
    public String accessKeySecret;
    public String clientBucket;

    public Credentials() {
    }

    public String getAccessKeyId() {
        return accessKeyId;
    }

    public void setAccessKeyId(String accessKeyId) {
        this.accessKeyId = accessKeyId;
    }

    public String getAccessKeySecret() {
        return accessKeySecret;
    }

    public void setAccessKeySecret(String accessKeySecret) {
        this.accessKeySecret = accessKeySecret;
    }

    public String getClientBucket() {
        return clientBucket;
    }

    public void setClientBucket(String clientBucket) {
        this.clientBucket = clientBucket;
    }
}

Ниже приводится мой пользовательский десериализатор, который я написал

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

import java.io.IOException;

public class CredentialDeserializer extends StdDeserializer<Credentials> {

    ObjectMapper mapper = new ObjectMapper();

    public CredentialDeserializer() {
        this(null);
    }

    public CredentialDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public Credentials deserialize(JsonParser jp, DeserializationContext cntx) throws IOException, JsonProcessingException {

        JsonNode credentialMode = jp.getCodec().readTree(jp);
        Credentials credentials = new Credentials();

        if (credentialMode.has("version")) {
            credentials = new ObjectMapper().treeToValue(credentialMode, Credentials.class);
        } else {
            credentials.setAccessKeyId(credentialMode.get("encrypted").get("credentials").get("accessKey").textValue());
            credentials.setAccessKeySecret(credentialMode.get("encrypted").get("credentials").get("accessSecret").textValue());
            credentials.setClientBucket(credentialMode.get("encrypted").get("credentials").get("bucket").textValue());

        }
        return credentials;

    }

}

Но Json, имеющий значение "version" в качестве "v2", дает StackOverflowError как изнутри deserialize () CustomDeserializer. Я делаю вызов "new ObjectMapper (). TreeToValue (credentialMode, Credentials.class)", который, в свою очередь, снова вызывает десериализатор и входит в рекурсивный цикл.

В некоторых местах было предложено зарегистрировать SimpleModule непосредственно в части реализации, но мое требование состоит в том, чтобы иметь CustomDeserializer, достаточно универсальный для обработки обоих типов Json. ResolvableDeserializer и BeanDeserializerBase и т. Д. Было предложено, но я не знаю, как именно. Любая помощь будет оценена. Спасибо

...