Comment retourner différents types de ResponseEntity dans le MVC ou le Spring-Boot
j'ai écrit l'application de repos simple en utilisant le ressort MVC 4 (ou le ressort-Boot). Dans le controller j'ai return ResponseEntity
. Mais dans certains cas je veux donner le succès JSON et s'il y a une erreur de validation je veux donner l'erreur JSON. Actuellement, le succès et les réponses d'erreur sont totalement différents, donc j'ai créé 2 classes pour l'erreur et le succès. Dans le contrôleur, je veux retourner ResponseEntity<Success>
, si la logique interne est d'accord. Sinon, je veux retourner ResponseEntity<Error>
. Est-il possible de le faire il.
Success
et Error
sont les 2 classes que j'utilise pour représenter le succès et la réponse d'erreur.
8 réponses
vous pouvez implémenter comme ci-dessous pour retourner Success
et Error
sur une même demande de la méthode de mapping
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
}
je vous recommande d'utiliser le Printemps @ControllerAdvice
pour traiter les erreurs de validation. Lire ce guide pour une bonne introduction, en commençant par la section intitulée "Gestion des erreurs de démarrage à ressort". Pour une discussion en profondeur, il y a un article au printemps.io blog qui a été mis à jour le avril 2018.
Un bref résumé sur la façon dont cela fonctionne:
- votre méthode de controller ne doit retourner que
ResponseEntity<Success>
. Il ne sera pas responsable du retour de l'erreur ou réponses d'exception. - vous allez implémenter une classe qui gère les exceptions pour tous les controllers. Cette classe sera annotée de
@ControllerAdvice
- cette classe de conseils de contrôleur contiendra des méthodes annotées avec
@ExceptionHandler
- Chaque gestionnaire d'exception méthode sera configuré 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 le class) une méthode de handler d'exception pour l'erreur de validation. Le type de retour serait
ResponseEntity<Error>
avec cette approche, vous n'avez qu'à implémenter la gestion des exceptions de votre controller en un seul endroit pour tous les endpoints de votre API. Il est également facile pour votre API d'avoir une structure de réponse d'exception uniforme pour tous les endpoints. Cela simplifie la gestion des exceptions pour vos clients.
il est possible de revenir ResponseEntity
sans l'utilisation 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);
}
}
je ne suis pas sûr, mais, je pense que vous pouvez utiliser @ResponseEntity
et @ResponseBody
et envoyer 2 est un Succès et le deuxième est le 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, se référer à ce: http://www.concretepage.com/spring-4/spring-4-mvc-jsonp-example-with-rest-responsebody-responseentity
Voici un moyen que je voudrais 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);
}
j'ai l'habitude d'utiliser une classe comme ça. statusCode est défini lorsqu'il y a une erreur avec le message d'erreur message. Les données sont stockées soit dans la carte, soit 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;
}
}
Espérons que cette aide.
Vous pouvez aussi implémenter comme ceci pour retourner le succès et L'erreur sur une même méthode de mappage des requêtes, utiliser la classe objet (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
}
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);
}
}