web-dev-qa-db-fra.com

Quel est le meilleur moyen de renvoyer différents types de ResponseEntity dans Spring MVC ou Spring-Boot

J'ai écrit une application de repos simple en utilisant Spring MVC 4 (ou Spring-Boot). Dans le contrôleur, j'ai return ResponseEntity. Mais dans certains cas, je veux donner du succès au JSON et s’il ya une erreur de validation, je veux donner l’erreur au JSON. Actuellement, le succès et les réponses d'erreur sont totalement différents. J'ai donc créé 2 classes d'erreur et de succès. Dans le contrôleur, je veux renvoyer ResponseEntity<Success>, si la logique interne est correcte. Sinon, je veux renvoyer ResponseEntity<Error>. Y a-t-il un moyen de le faire.

Success et Error sont les 2 classes que j'utilise pour représenter le succès et la réponse d'erreur.

21

Vous pouvez implémenter comme ci-dessous pour renvoyer Success et Error sur une même méthode de mappage de demandes

public ResponseEntity<?> method() {
    boolean b = // some logic
    if (b)
        return new ResponseEntity<Success>(HttpStatus.OK);
    else
        return new ResponseEntity<Error>(HttpStatus.CONFLICT); //appropriate error code
}
27
Saravana

Je recommande d'utiliser le @ControllerAdvice de Spring pour traiter les erreurs de validation. Lisez ce guide pour une bonne introduction, en commençant par la section intitulée "Traitement des erreurs de démarrage du printemps". Pour une discussion approfondie, il y a un article dans le blog de Spring.io mis à jour en avril 2018.

Un bref résumé sur la façon dont cela fonctionne:

  • Votre méthode de contrôleur ne devrait renvoyer que ResponseEntity<Success>. Il ne sera pas responsable du renvoi des réponses d'erreur ou d'exception.
  • Vous allez implémenter une classe qui gère les exceptions pour tous les contrôleurs. Cette classe sera annotée avec @ControllerAdvice
  • Cette classe d'avis de contrôleur contiendra des méthodes annotées avec @ExceptionHandler
  • Chaque méthode de gestionnaire d'exceptions sera configurée pour gérer un ou plusieurs types d'exceptions. Ces méthodes sont où vous spécifiez le type de réponse pour les erreurs
  • Pour votre exemple, vous déclareriez (dans la classe de conseil du contrôleur) une méthode de gestionnaire d'exceptions pour l'erreur de validation. Le type de retour serait ResponseEntity<Error>

Avec cette approche, il vous suffit d'implémenter la gestion des exceptions de votre contrôleur à un emplacement unique pour tous les ordinateurs d'extrémité de votre API. Il est également facile pour votre API d’avoir une structure de réponse aux exceptions uniforme sur tous les points de terminaison. Cela simplifie la gestion des exceptions pour vos clients.

23
Mark Norman

je ne suis pas sûr mais, je pense que vous pouvez utiliser @ResponseEntity et @ResponseBody et envoyer 2 noms différents, Success et second, un message d'erreur du type:

@RequestMapping(value ="/book2", produces =MediaType.APPLICATION_JSON_VALUE )
@ResponseBody
Book bookInfo2() {
    Book book = new Book();
    book.setBookName("Ramcharitmanas");
    book.setWriter("TulasiDas");
    return book;
}

@RequestMapping(value ="/book3", produces =MediaType.APPLICATION_JSON_VALUE )
public ResponseEntity<Book> bookInfo3() {
    Book book = new Book();
    book.setBookName("Ramayan");
    book.setWriter("Valmiki");
    return ResponseEntity.accepted().body(book);
}

Pour plus de détails, reportez-vous à ceci: http://www.concretepage.com/spring-4/spring-4-mvc-jsonp-example-with-rest-responsebody-responseentity

4
km8295

Il est possible de retourner ResponseEntity sans utiliser de génériques, comme suit,

public ResponseEntity method() {
    boolean isValid = // some logic
    if (isValid){
        return new ResponseEntity(new Success(), HttpStatus.OK);
    }
    else{
        return new ResponseEntity(new Error(), HttpStatus.BAD_REQUEST);
    }
}
3
Saveendra Ekanayake

Voici une façon de le faire:

public ResponseEntity < ? extends BaseResponse > message(@PathVariable String player) { //REST Endpoint.

 try {
  Integer.parseInt(player);
  return new ResponseEntity < ErrorResponse > (new ErrorResponse("111", "player is not found"), HttpStatus.BAD_REQUEST);
 } catch (Exception e) {


 }
 Message msg = new Message(player, "Hello " + player);
 return new ResponseEntity < Message > (msg, HttpStatus.OK);

}

@RequestMapping(value = "/getAll/{player}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity < List < ? extends BaseResponse >> messageAll(@PathVariable String player) { //REST Endpoint.

 try {
  Integer.parseInt(player);
  List < ErrorResponse > errs = new ArrayList < ErrorResponse > ();
  errs.add(new ErrorResponse("111", "player is not found"));
  return new ResponseEntity < List < ? extends BaseResponse >> (errs, HttpStatus.BAD_REQUEST);
 } catch (Exception e) {


 }
 Message msg = new Message(player, "Hello " + player);
 List < Message > msgList = new ArrayList < Message > ();
 msgList.add(msg);
 return new ResponseEntity < List < ? extends BaseResponse >> (msgList, HttpStatus.OK);

}
2
sharath

Vous pouvez également implémenter comme ceci pour renvoyer Success et Error sur une même méthode de mappage de requête, utilisez Object class (Classe parent de chaque classe en Java): - 

public ResponseEntity< Object> method() {                                                                                                                                                                                                                                                                                                                                                                                  
    boolean b = //  logic  here   
      if (b)  
        return new ResponseEntity< Object>(HttpStatus.OK);      
    else      
        return new ResponseEntity< Object>(HttpStatus.CONFLICT); //appropriate error code   
}
1
NeeruSingh

J'avais l'habitude d'utiliser une classe comme celle-ci. Le statusCode est défini en cas d'erreur avec le message d'erreur défini dans message . Les données sont stockées dans la carte ou dans une liste selon les besoins.

/**
* 
*/
package com.test.presentation.response;

import Java.util.Collection;
import Java.util.Map;

/**
 * A simple POJO to send JSON response to ajax requests. This POJO enables  us to
 * send messages and error codes with the actual objects in the application.
 * 
 * 
 */
@SuppressWarnings("rawtypes")
public class GenericResponse {

/**
 * An array that contains the actual objects
 */
private Collection rows;

/**
 * An Map that contains the actual objects
 */
private Map mapData;

/**
 * A String containing error code. Set to 1 if there is an error
 */
private int statusCode = 0;

/**
 * A String containing error message.
 */
private String message;

/**
 * An array that contains the actual objects
 * 
 * @return the rows
 */
public Collection getRows() {
    return rows;
}

/**
 * An array that contains the actual objects
 * 
 * @param rows
 *            the rows to set
 */
public void setRows(Collection rows) {
    this.rows = rows;
}

/**
 * An Map that contains the actual objects
 * 
 * @return the mapData
 */
public Map getMapData() {
    return mapData;
}

/**
 * An Map that contains the actual objects
 * 
 * @param mapData
 *            the mapData to set
 */
public void setMapData(Map mapData) {
    this.mapData = mapData;
}

/**
 * A String containing error code.
 * 
 * @return the errorCode
 */
public int getStatusCode() {
    return statusCode;
}

/**
 * A String containing error code.
 * 
 * @param errorCode
 *            the errorCode to set
 */
public void setStatusCode(int errorCode) {
    this.statusCode = errorCode;
}

/**
 * A String containing error message.
 * 
 * @return the errorMessage
 */
public String getMessage() {
    return message;
}

/**
 * A String containing error message.
 * 
 * @param errorMessage
 *            the errorMessage to set
 */
public void setMessage(String errorMessage) {
    this.message = errorMessage;
}

}

J'espère que cela t'aides.

0
shazinltc

Vous pouvez utiliser une carte avec votre objet ou une chaîne comme ci-dessous:

@RequestMapping(value = "/path", 
        method = RequestMethod.GET, 
        produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<Map<String,String>> getData(){

    Map<String,String> response = new HashMap<String, String>();

    boolean isValid = // some logic
    if (isValid){
        response.put("ok", "success saving data");
        return ResponseEntity.accepted().body(response);
    }
    else{
        response.put("error", "an error expected on processing file");
        return ResponseEntity.badRequest().body(response);
    }

}
0
Ridha10