2015-06-16 3 views
9

Я использую библиотеку org.json для преобразования формата Object в Json. Просьба проверить приведенный ниже фрагмент кода.Java: преобразовать объект, состоящий из перечисления в объект 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" : {}} 

Это показывает пустое и добавляет фигурные базы. Что это значит? Кто-нибудь прошел через эту проблему?

+0

взглянуть на эту ссылку: http://stackoverflow.com/questions/7766791/serializing -enums-with-jackson –

ответ

10

Прежде всего, я настоятельно рекомендую не использовать эту библиотеку (org.json), это очень старая и неподдерживаемая (как я знаю) библиотека. Я предлагаю Jackson или Gson.

Но если вам действительно нужно JSONObject, вы можете добавить геттер в перечислении:

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

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

результат сериализации:

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

Как я знаю, JSONObject не поддерживают правильную сериализации перечислений, которые не имеют никаких дополнительных данных внутри.

+0

@ Дения: Да, ты прав. org.json слишком стар. Я непременно перейду к Гсону или Джексону. Спасибо за ваши ценные предложения. – Ronnie

-1

У вас должен быть пользовательский сериализатор для Enum. Пожалуйста, проверьте http://www.baeldung.com/jackson-serialize-enums.

+1

Это плохой ответ. Во-первых, вы предлагаете другую библиотеку. Во-вторых, в этой библиотеке вы предлагаете сериализовать enums в порядке, не требуя создания пользовательских сериализаторов. В-третьих, вы предлагаете использовать сериализатор, но не объясняете, как писать одно или что он должен делать. –

0

Кажется JSONObject не поддерживает перечисления. Вы можете изменить свой Job класс, чтобы добавить поглотитель, как это:

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

затем, вызывая new JSONObject(job).toString() производит:

{"id":"12345","status":"INPROGRESS"} 
0
ObjectMapper mapper= new ObjectMapper(); 

new JSONObject(mapper.writeValueAsString(job)); 

будет делать трюк. Теперь Enums и DateTime типы выглядят нормально и правильно преобразуются в объекты json.

Я пришел на эту страницу как человек, ищущий ответ, и мои исследования помогли мне ответить на этот вопрос.

+0

Я пробовал это, но это не сработало, значение для JSON для меня было пустым. Мое перечисление очень упрощено; это имеет значение? 'Общественного перечисления ServiceType { \t \t MULTI_MASTER, \t SINGLE_MASTER }' –

+0

выше метод поможет вам преобразовать объект некоторого типа класса в объект JSON без вмешательства каких-либо типов данных, как мы используем библиотеку ObjectMapper. Поскольку я не знаю, что вы делаете с этим объектом JSON, я могу предложить вам отладить строку по строке в вашей среде IDE и найти, где ваши данные перечисления будут потеряны. Надеюсь, вам может понадобиться проверить код, который управляет созданным объектом JSON. – Hari

0

для меня я создал интерфейс, который shuold будет реализован любым перечислением, которое мне нужно будет использовать в Json, этот интерфейс заставляет перечисление знать собственное перечисление из значения, а также оно должно возвращать значение. так что каждый enum.CONSTANT отображается на значение любого типа (погода число или строка)

поэтому, когда я хочу поместить это перечисление в объект Json, я прошу enum.CONSTANT дать мне это значение , и когда у меня есть это значение (от Json), я могу запросить у перечисления, чтобы дать мне правильное перечисление.КОНСТАНТА, сопоставленные с этим значением

интерфейс выглядит следующим образом (вы можете скопировать его, как он есть):

/** 
* 
* 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», и так далее

Смежные вопросы