问题 Java:将包含枚举的对象转换为Json对象


我使用org.json库将Object转换为Json格式。请检查以下代码段。

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" : {}}

它显示空白并添加Curly基础。这是什么意思?有人经历过这个问题吗?


12556
2018-06-16 14:48


起源

看看这个链接: stackoverflow.com/questions/7766791/... - Arthur Eirich


答案:


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

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

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

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

序列化的结果:

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

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


12
2018-06-16 15:27



@Denya:是的你是对的。 org.json太老了。我一定会搬到Gson或Jackson。感谢您提出宝贵意见。 - Ronnie


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

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

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

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

0
2018-06-16 15:39





ObjectMapper mapper= new ObjectMapper();

new JSONObject(mapper.writeValueAsString(job));

会做的伎俩。现在 Enums 和 DateTime 类型看起来很正常,并在json对象中正确转换。

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


0
2017-10-09 21:27



我尝试了这个,但它没有用,JSON中的值对我来说是空白的。我的枚举很简单;这有什么区别吗? public enum ServiceType { MULTI_MASTER, SINGLE_MASTER } - Mike Stoddart
上面的方法可以帮助您将某些类类型的对象转换为JSON对象,而不会篡改任何数据类型,因为我们使用ObjectMapper库。由于我不知道你在使用那个JSON对象做什么,我建议你在IDE中逐行调试,找到你的枚举数据丢失的地方。我希望您可能需要检查操作创建的JSON对象的代码。 - Hari


对我来说,我创建了一个接口,我将不得不在Json中使用任何枚举,这个接口强制枚举从值中知道正确的枚举本身,并且它应该返回一个值...所以每个枚举.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”,依此类推


0
2018-04-10 15:19





您应该有Enum的自定义序列化程序。请检查 http://www.baeldung.com/jackson-serialize-enums


-1
2018-06-16 14:56



这是一个糟糕的答案。首先,您建议使用不同的库。其次,你建议的那个库序列化枚举很好,而不需要自定义序列化器。第三,你建议使用序列化器,但不解释如何写一个或它应该做什么。 - Sotirios Delimanolis