【问题标题】:Enum Keys are discarded on Deserialization枚举键在反序列化时被丢弃
【发布时间】:2020-05-05 12:15:12
【问题描述】:

我正在尝试将以下 json 结构反序列化为对象。

"policyDetail": {
"policies": {
    "API_KEY": {
        "isEnabled": "Yes",
        "policyEnabled": true
    },
    "BASIC_AUTH": {
        "username": "username",
        "password": "password",
        "policyEnabled": true
    }
}

}

在这个结构中,API_KEY 和 BASIC_AUTH 是 java Enum 类型。我正在尝试像这样反序列化。

在服务类中

ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

SimpleModule module = new SimpleModule();
module.addDeserializer(Policy.class, new PolicyDeserializer());
mapper.registerModule(module);

PolicyDeserializer.java

公共类 PolicyDeserializer 扩展了 StdDeserializer{

public PolicyDeserializer() {
    super(Policy.class);
}
protected PolicyDeserializer(Class<?> vc) {
    super(vc);
}

@Override
public Policy deserialize(JsonParser jp, DeserializationContext ctxt) 
        throws IOException, JsonProcessingException {

    ObjectMapper mapper = new ObjectMapper();
    JsonNode node = jp.readValueAsTree();

 // Here I am only getting values under API_KEY not the entire API_KEY and underneath structure.

    JsonNode customField = node.findValue("API_KEY");

    Policy result = null;

    if(customField != null && !customField.isNull()) {

        ApiKeyPolicy apiKeyPolicy = new ApiKeyPolicy();
        apiKeyPolicy = mapper.readValue(customField.toString(), ApiKeyPolicy.class);
        result = apiKeyPolicy;

        return result;
    }
    return result;
}

}

Policy.java

package model.policy;

import enums.PolicyType;

public abstract class Policy {

    private PolicyType policyType;
    private boolean isPolicyEnabled;

    public Policy(PolicyType policyType) {
        this.policyType = policyType;
    }

    /**
     * @return the isPolicyEnabled
     */
    public boolean isPolicyEnabled() {
        return isPolicyEnabled;
    }

    /**
     * @param isPolicyEnabled
     *            the isPolicyEnabled to set
     */
    public void setPolicyEnabled(boolean isPolicyEnabled) {
        this.isPolicyEnabled = isPolicyEnabled;
    }

}

ApiKeyPolicy.java

import enums.PolicyType;
import model.Policy;

public class ApiKeyPolicy extends Policy {

    private String isEnabled;

    public ApiKeyPolicy() {
        super(PolicyType.API_KEY);
    }

    /**
     * @return the isEnabled
     */
    public String getIsEnabled() {
        return isEnabled;
    }

    /**
     * @param isEnabled the isEnabled to set
     */
    public void setIsEnabled(String isEnabled) {
        this.isEnabled = isEnabled;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "ApiKeyPolicy [isEnabled=" + isEnabled + "]";
    }


}

PolicyDetail.java

import java.util.EnumMap;
import java.util.Map;

import enums.PolicyType;

public class PolicyDetail {

    EnumMap<PolicyType, Policy> policyMap = null;

    public PolicyDetail() {
        if(policyMap == null) {
            policyMap = new EnumMap<PolicyType,Policy>(PolicyType.class);
        }
    }

    public void addPolicy(PolicyType policyType, Policy policy, boolean isEnabled) {
        if(null != policy) {
            policy.setPolicyEnabled(isEnabled);
            this.policyMap.put(policyType, policy);
        }
    }

    public Map<PolicyType, Policy> getPolicies(){
        return this.policyMap;
    }

    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "PolicyDetail [policyMap=" + policyMap + "]";
    }

}

因为这就是第 3 方 Json 的结构。因此,我无法更改现有结构。你能建议我在哪里失踪吗?

提前谢谢..!

【问题讨论】:

  • 你能展示你的JavaPOJO模型吗?
  • 感谢您的关注。请查看更新后的内容,如果您需要更多信息,请告诉我

标签: jackson


【解决方案1】:

经过太多的研究和反复试验。我发现父抽象类 Policy.java 应该有以下条目,如

@JsonTypeInfo(
          use = JsonTypeInfo.Id.NAME, 
          include = JsonTypeInfo.As.PROPERTY, 
          property = "type",
          visible = true
          )
        @JsonSubTypes({ 
          @JsonSubTypes.Type(value = APIKeyPolicy.class, name = "API_KEY"), 
          @Type(value = BasicAuth.class, name = "BASIC_AUTH")})

      public abstract class Policy {
        //with all methods
      }

所以,现在当我尝试将其反序列化为对象时,我应该得到关注

"API_KEY": {
            "type": "API_KEY",
            "isEnabled": "Yes",
            "policyEnabled": true
        },
        "BASIC_AUTH": {
            "type": "BASIC_AUTH",
            "username": "username",
            "password": "password",
            "policyEnabled": true
        }

但它带有一个额外的属性作为类型,目前还可以。因为我对具有相应属性的策略名称 ENUM 更感兴趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-31
    • 2015-07-26
    • 1970-01-01
    • 2021-11-30
    • 2017-07-24
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    相关资源
    最近更新 更多