web-dev-qa-db-fra.com

Java: Convertir un objet composé en un objet Json

J'utilise la bibliothèque org.json pour convertir Object au format Json. Veuillez vérifier l'extrait de code ci-dessous.

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());

Il montre la sortie comme ceci:

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

Il montre vide et ajoute des bases bouclés. Qu'est-ce que ça veut dire? Est-ce que quelqu'un a traversé ce problème?

13
Ronnie

Tout d’abord, je recommande fortement de ne pas utiliser cette bibliothèque (org.json), c’est une bibliothèque très ancienne et non prise en charge (à ma connaissance). Je suggère Jackson ou Gson .

Mais si vous avez vraiment besoin de JSONObject, vous pouvez ajouter un getter à l’énumération:

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

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

résultat de la sérialisation:

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

Comme je le sais, JSONObject ne prend pas en charge la sérialisation correcte des énumérations qui ne contiennent aucune donnée supplémentaire.

13
Denys Denysiuk

Il semble que JSONObject ne supporte pas les énumérations. Vous pouvez modifier votre classe Job pour ajouter un getter comme celui-ci:

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

alors, invoquer new JSONObject(job).toString() produit:

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

pour moi, j’ai fait une interface qui devrait être implémentée par toute énumération que j’aurai à utiliser dans Json, cette interface force l’énum à connaître la bonne enum à partir d’une valeur, et elle doit aussi renvoyer une valeur ... donc chaque énumère .CONSTANT est associé à une valeur de n'importe quel type (météo un nombre ou une chaîne)

donc quand je veux mettre cette énumération dans un objet Json, je demande à l'énum.CONSTANT de me donner sa valeur, et quand j'ai cette valeur (de Json), je peux demander à l'énum de me donner l'énum correct. mappé à cette valeur

l'interface est la suivante (vous pouvez la copier telle quelle):

/**
 * 
 * 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();
}

voici maintenant un exemple pour une petite énumération implémentant cette interface:

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;
    }

}

enregistrer cette énumération dans un Json:

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

maintenant pour obtenir votre valeur d'un objet Json:

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

ainsi, si la valeur zoneValue est 1 par exemple, le type AreaType sera "Area", etc.

0
Ahmed Adel Ismail
ObjectMapper mapper= new ObjectMapper();

new JSONObject(mapper.writeValueAsString(job));

ferait l'affaire. Maintenant, les types Enums et DateTime semblent normaux et sont convertis correctement dans les objets json. 

Je suis venu sur cette page en tant que personne cherchant une réponse et mes recherches m'ont aidé à répondre à cette question.

0
Hari