[Java] Deserialization JSON et typage

Deserialization JSON et typage [Java] - Java - Programmation

Marsh Posté le 10-03-2020 à 13:19:07    

Bonjour  :hello: ,
 
Je développe habituellement en Node et pour des raisons de contraintes techniques j'ai besoin d'écrire du Java et je galère avec une problématique qui parait toute bête qui est de la déserialization JSON sur un langage typé.
 
Le problème est simple. Je vais recevoir via un système de queuing des messages contenant du JSON, donc j'ai en entrée une variable de type String. Ces messages JSON sont de différents types, par exemple "DispatchTask" et "SendEvent". Ils contiennent certaines propriétés qui sont bien définies (par exemple "name", dont la valeur est toujours String), et d'autres qui le sont moins comme par exemple "input" qui est un array qui peut contenir un nombre indéfini de valeurs, et de n'importe quelle type JSON valide. Donc voici différents exemples de ces messages:
 


{"type": "DispatchTask", "name": "TaskA", inputs: []}
 
{"type": "DispatchTask", "name": "TaskB", inputs: [1, 2, 3]}
 
{"type": "DispatchTask", "name": "TaskC", inputs: ["2020-03-10"]}
 
{"type": "SendEvent", "workflow_id": "456", "name": "UserRegistered", inputs: [{"id": "123", "name": "John Doe", "registered_at": "2020-03-10"}]}
 
{"type": "SendEvent", "workflow_id": "456", "name": "UserAddedItemToShoppingCart", inputs: ["abcdef", 2]}


 
Les exemples sont simplifiés et il y a beaucoup plus de type de messages différents qui ont parfois des "schema" complètement différents, pas la peine de jouer sur des trucs qu'ils pourraient avoir en commun pour essayer de trouver une solution.
 
Ce que j'ai, c'est une classe qui doit implémenter une interface avec une méthode bien précise:
 


public class MyMessageProcessor implements MessageProcessor {
    public void process(String s) {
        // need to decode the String to be able to read the "type" property.
 
        // use the type property to get an object of the right type.
    }
}


 
Et j'ai différentes classes pour représenter les différents types de messages:
 


public class DispatchTaskMessage {
    private String id;
    private String name;
    private Object[] inputs;
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Object[] getInputs() {
        return inputs;
    }
 
    public void setInputs(Object[] inputs) {
        this.inputs = inputs;
    }
}
 
public class SendEventMessage {
    private String workflowId;
    private String name;
    private Object[] inputs;
 
    public String getId() {
        return id;
    }
 
    public void setId(String id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public Object[] getInputs() {
        return inputs;
    }
 
    public void setInputs(Object[] inputs) {
        this.inputs = inputs;
    }
}
 


 
J'ai mis dans les inputs un typage en Object[] car ne connaissant pas ce qui va être fournit, et sachant que ça peut en plus être de différent type, je ne connais pas d'autre moyen de représenter cette situation, si quelqu'un à mieux à suggérer, n'hésitez pas.
 
Et donc j'aimerais bien dans MyMessageProcessor décoder du JSON et me retrouver avec un objet du bon type qui représente mon message.
Mais comme le type dont je vais avoir besoin dépend du contenu du JSON, je bloque complètement. Je ne sais pas du tout comment m'y prendre. Je ne sais pas si l'usage des génériques pourrait m'aider à résoudre cette problématique puisque beaucoup va se passer au runtime. Si quelqu'un a des idées ou des livres / articles bien faits qui parlent de comment gérer ce genre de cas

Reply

Marsh Posté le 10-03-2020 à 13:19:07   

Reply

Marsh Posté le 10-03-2020 à 17:28:46    

Le plus simple c'est d'utiliser le composant Gson
 
https://github.com/google/gson/blob/master/UserGuide.md

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed