2017-07-19 1 views
2

J'ai des applications client et serveur, toutes deux écrites au printemps en Java. J'utilise RestTemplate pour appeler le serveur du client.Spring RestTemplate - Lire un type d'objet différent basé sur le code d'état http?

Le serveur renvoie un objet de réponse différent, en fonction du résultat de l'opération.
Code simplifié:

public ResponseEntity<?> saveSomething (Object something) { 
    boolean saved = save(something); //save logic 
    if(saved) 
     return new ResponseEntity<OKObject>(okObject,HttpStatus.OK); 
    else 
     return new ResponseEntity<ErrorObject>(errorObject,HttpStatus.FAILED); 
} 

Je veux être en mesure de lire les réponses sur le client par le code d'état, mais
RestTemplate ne propose que de lire un type, par exemple <Object_type>.class; et offre le code d'état APRÈS que l'opération .getForEntity(...) a été exécutée - lorsque le type de réponse est déjà retourné.
Ce que je veux dans le code pseudo côté client:

public void saveSomething(Object toSave) { 
    ResTemplate template = new RestTemplate(); 
    ResponseEntity<Object> response = template.getForEntity(url,Object.class); 
    if(response.getStatusCode() == HttpStatus.OK) { 
     OKObject ok = (OKObject) response.getBody(); 
     //some work with ok object 
    } 
    if(response.getStatusCode() == HttpStatus.FAILED) { 
     ErrorObject errorObject = (ErrorObject) response.getBody(); 
     //some work with errorObject 
    } 
} 

Est-ce possible d'une manière non-aki, propre? J'ai lu sur la définition du type de réponse comme String.class et l'analyser ensuite, ou en lisant Object.class (renvoie LinkedHashMap) et l'analyser.
Merci pour vos conseils.

Répondre

2

Je suggère d'introduire une réponse commune qui comprend à la fois ok et l'erreur (l'un d'entre eux est nulle)

publi class CommonResponseObject { 
    private OKObject okObject; 
    private ErrorObject errorObject; 
    public CommonResponseObject(OKObject okObject) { 
     this.okObject=okObject; 
    } 
    public CommonResponseObject(ErrorObject errorObject) { 
     this.errorObject=errorObject; 
    } 
} 

et de l'utiliser

public ResponseEntity<CommonResponseObject > saveSomething (Object something) { 
    boolean saved = save(something); //save logic 
    if(saved) 
     return new ResponseEntity<>(new CommonResponseObject(okObject),HttpStatus.OK); 
    else 
     return new ResponseEntity<>(new CommonResponseObject(errorObject),HttpStatus.FAILED); 
} 

et traiter les résultats

public void saveSomething(Object toSave) { 
    ResTemplate template = new RestTemplate(); 
    ResponseEntity<CommonResponseObject> response = template.getForEntity(url,CommonResponseObject.class); 
    if(response.getStatusCode() == HttpStatus.OK) { 
     OKObject ok = response.getBody().getOkObject(); 
    } 
    if(response.getStatusCode() == HttpStatus.FAILED) { 
     ErrorObject errorObject = response.getBody().getErrorObject(); 
    } 
} 
+0

C'est vraiment mauvais, car avec plus de responseObjects vous transférez plus de données redondantes; et aussi dans le code il y aurait beaucoup de classes de réponse enveloppées dans une juste pour être en mesure d'obtenir une réponse. C'est la manière hacky que je ne veux pas. Mais merci pour la réponse. – milkamar

+2

Juste un peu plus ... l'une des ok/erreur est toujours nulle. Vous pouvez configurer la sérialisation pour ignorer les valeurs NULL. L'info supplémentaire (en cas de json) est juste le nom du champ ok ou erreur. – StanislavL

+1

Vous pouvez également envoyer un String, vérifier l'état et désérialiser la chaîne à Ok ou Error object – StanislavL