【问题标题】:Java : Convert Object consisting enum to Json ObjectJava:将包含枚举的对象转换为 Json 对象
【发布时间】:2015-09-01 11:22:54
【问题描述】:

我正在使用 org.json 库将 Object 转换为 Json 格式。请检查以下代码 sn-p。

public enum JobStatus implements Serializable{
     INCOMPLETE,
     INPROGRESS,
     ABORTED,
     COMPLETED
}

public class Job implements Serializable {
    private string id;
    private JobStatus status;
    ...
}

...

// Create Job Object
Job job = new Job("12345", JobStatus.INPROGRESS);

// Convert and print in JSON format
System.out.println(new JSONObject(job).toString());

它显示这样的输出:

 {"id":"12345", "status" : {}}

它显示空白并添加卷曲碱基。这是什么意思?有人遇到过这个问题吗?

【问题讨论】:

标签: java json enums


【解决方案1】:

首先,我强烈建议不要使用这个库(org.json),这是一个非常古老且不受支持(据我所知)的库。我建议JacksonGson

但是如果你真的需要JSONObject,你可以在枚举中添加getter:

 public enum JobStatus implements Serializable{
    INCOMPLETE,
    INPROGRESS,
    ABORTED,
    COMPLETED;

    public String getStatus() {
        return this.name();
    }
}

序列化结果:

{"id":"12345","status":{"status":"INPROGRESS"}}

据我所知,JSONObject 不支持对内部没有任何附加数据的枚举进行正确序列化。

【讨论】:

  • @Denya:是的,你是对的。 org.json 太旧了。我肯定会搬到 Gson 或 Jackson。感谢您提出宝贵的建议。
  • 不需要实现Serializable,因为每个枚举默认都是Serializable。
【解决方案2】:
ObjectMapper mapper= new ObjectMapper();

new JSONObject(mapper.writeValueAsString(job));

会成功的。现在 EnumsDateTime 类型看起来很正常,并且在 json 对象中正确转换。

我作为一个寻求答案的人来到这个页面,我的研究帮助我回答了这个问题。

【讨论】:

  • 我试过了,但没用,我的 JSON 中的值是空白的。不过,我的枚举非常简单;这有什么区别吗? public enum ServiceType { MULTI_MASTER, SINGLE_MASTER }
  • 上述方法可以帮助您将某个类类型的对象转换为 JSON 对象,而不会篡改任何数据类型,因为我们使用 ObjectMapper 库。因为我不知道你在用那个 JSON 对象做什么,我可以建议你在你的 IDE 中逐行调试代码并找到你的枚举数据丢失的地方。我希望您可能需要检查操作创建的 JSON 对象的代码。
【解决方案3】:

JSONObject 似乎不支持枚举。你可以改变你的Job 类来添加一个像这样的getter:

public String getStatus() {
    return status.name();
}

然后,调用 new JSONObject(job).toString() 会产生:

{"id":"12345","status":"INPROGRESS"}

【讨论】:

    【解决方案4】:

    对我来说,我创建了一个接口,该接口应该由我必须在 Json 中使用的任何枚举实现,这个接口强制枚举从一个值中知道正确的枚举本身,并且它应该返回一个值......所以每个 enum.CONSTANT 都映射到任何类型的值(无论是数字还是字符串)

    所以当我想把这个枚举放在一个 Json 对象中时,我要求 enum.CONSTANT 给我它的值,当我有这个值(来自 Json)时,我可以请求枚举给我正确的enum.CONSTANT 映射到这个值

    界面如下(可以照原样复制):

    /**
     * 
     * this interface is intended for {@code enums} (or similar classes that needs
     * to be identified by a value) who are based on a value for each constant,
     * where it has the utility methods to identify the type ({@code enum} constant)
     * based on the value passed, and can declare it's value in the interface as
     * well
     * 
     * @param <T>
     *            the type of the constants (pass the {@code enum} as a type)
     * @param <V>
     *            the type of the value which identifies this constant
     */
    public interface Valueable<T extends Valueable<T, V>, V> {
    
        /**
         * get the Type based on the passed value
         * 
         * @param value
         *            the value that identifies the Type
         * @return the Type
         */
        T getType(V value);
    
        /**
         * get the value that identifies this type
         * 
         * @return a value that can be used later in {@link #getType(Object)}
         */
        V getValue();
    }
    

    现在这里是一个实现此接口的小型枚举示例:

    public enum AreaType implements Valueable<AreaType, Integer> {
        NONE(0),
        AREA(1),
        NEIGHBORHOOD(2);
    
        private int value;
    
        AreaType(int value) {
            this.value = value;
        }
    
        @Override
        public AreaType getType(Integer value) {
    
            if(value == null){
                // assume this is the default
                return NONE;
            }
    
            for(AreaType a : values()){
                if(a.value == value){ // or you can use value.equals(a.value)
                    return a;
                }
            }
            // assume this is the default
            return NONE;
        }
    
        @Override
        public Integer getValue() {
            return value;
        }
    
    }
    

    将此枚举保存在 Json 中:

    AreaType areaType = ...;
    jsonObject.put(TAG,areaType.getValue());
    

    现在从 Json 对象中获取您的价值:

    int areaValue = jsonObject.optInt(TAG,-1);
    AreaType areaType = AreaType.NONE.getType(areaValue);
    

    例如,如果 areaValue 为 1,AreaType 将为“Area”,以此类推

    【讨论】:

      【解决方案5】:

      类似于@Denys Denysiuk 的回答。 但是如果你想返回任何值而不是String我们可以这样使用。在下面的示例中,我想返回值 1 或 15 而不是 String

      @Getter
      public enum PaymentCollectionDay {
      
          FIRST_OF_MONTH(1), FIFTEENTH_OF_MONTH(15);
          PaymentCollectionDay(int day) {
              this.day = day;
          }
      
          @JsonValue
          final int day;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-12
        • 2016-12-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        • 1970-01-01
        相关资源
        最近更新 更多