J'utilise Spring MVC pour une API JSON simple, avec @ResponseBody
une approche basée comme celle-ci. (J'ai déjà une couche de service qui produit directement JSON.)
@RequestMapping(value = "/matches/{matchId}", produces = "application/json")
@ResponseBody
public String match(@PathVariable String matchId) {
String json = matchService.getMatchJson(matchId);
if (json == null) {
// TODO: how to respond with e.g. 400 "bad request"?
}
return json;
}
La question est, dans le scénario donné, quelle est la façon la plus simple et la plus propre de répondre avec une erreur HTTP 400 ?
J'ai rencontré des approches comme:
return new ResponseEntity(HttpStatus.BAD_REQUEST);
... mais je ne peux pas l'utiliser ici car le type de retour de ma méthode est String, pas ResponseEntity.
java
spring
spring-mvc
http-error
Jonik
la source
la source
ResponseEntity
comme ça aussi. Cela fonctionne bien et n'est qu'une simple modification du code d'origine - merci!Quelque chose comme ça devrait fonctionner, je ne sais pas s'il existe ou non un moyen plus simple:
la source
body
etrequest
params.)Pas nécessairement la façon la plus compacte de faire cela, mais l'OMI assez propre
Modifier, vous pouvez utiliser @ResponseBody dans la méthode du gestionnaire d'exceptions si vous utilisez Spring 3.1+, sinon utilisez un
ModelAndView
ou quelque chose.https://jira.springsource.org/browse/SPR-6902
la source
ERROR org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: public controller.TestController$MyError controller.TestController.handleException(controller.TestController$BadThingException) org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
manque-t-il quelque chose dans la réponse?javax.validation.ValidationException
place. (Printemps 3.1.4)Je changerais légèrement la mise en œuvre:
Tout d'abord, je crée un
UnknownMatchException
:Notez l'utilisation de @ResponseStatus , qui sera reconnu par Spring's
ResponseStatusExceptionResolver
. Si l'exception est levée, elle créera une réponse avec l'état de réponse correspondant. (J'ai également pris la liberté de changer le code d'état404 - Not Found
auquel je trouve plus approprié pour ce cas d'utilisation, mais vous pouvez vous y tenirHttpStatus.BAD_REQUEST
si vous le souhaitez.)Ensuite, je changerais le
MatchService
pour avoir la signature suivante:Enfin, je voudrais mettre à jour le contrôleur et déléguer à Spring
MappingJackson2HttpMessageConverter
pour gérer automatiquement la sérialisation JSON (il est ajouté par défaut si vous ajoutez Jackson au chemin de classe et ajoutez soit@EnableWebMvc
ou<mvc:annotation-driven />
à votre configuration, voir les documents de référence ):Remarque, il est très courant de séparer les objets de domaine des objets de vue ou des objets DTO. Cela peut facilement être réalisé en ajoutant une petite fabrique DTO qui renvoie l'objet JSON sérialisable:
la source
Match
et un autre objet.Voici une approche différente. Créez une
Exception
annotation personnalisée avec@ResponseStatus
, comme la suivante.Et jetez-le en cas de besoin.
Consultez la documentation Spring ici: http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#mvc-ann-annotated-exceptions .
la source
Comme mentionné dans certaines réponses, il est possible de créer une classe d'exception pour chaque statut HTTP que vous souhaitez renvoyer. Je n'aime pas l'idée de devoir créer une classe par statut pour chaque projet. Voici ce que j'ai trouvé à la place.
Passons au code
Ensuite, je crée une classe de conseils de contrôleur
Pour l'utiliser
http://javaninja.net/2016/06/throwing-exceptions-messages-spring-mvc-controller/
la source
J'utilise ceci dans mon application Spring Boot
la source
Le moyen le plus simple est de lancer un
ResponseStatusException
la source
Avec Spring Boot, je ne sais pas vraiment pourquoi cela était nécessaire (j'ai eu le
/error
repli même si cela a@ResponseBody
été défini sur un@ExceptionHandler
), mais ce qui suit en soi n'a pas fonctionné:Il a toujours levé une exception, apparemment parce qu'aucun type de média productible n'a été défini comme attribut de demande:
Je les ai donc ajoutés.
Et cela m'a permis d'avoir un "type de support compatible pris en charge", mais cela n'a toujours pas fonctionné, car mon
ErrorMessage
était défectueux:JacksonMapper ne l'a pas traité comme "convertible", j'ai donc dû ajouter des getters / setters, et j'ai également ajouté des
@JsonProperty
annotationsEnsuite, j'ai reçu mon message comme prévu
la source
Vous pouvez également
throw new HttpMessageNotReadableException("error description")
profiter de la gestion des erreurs par défaut de Spring .Cependant, comme c'est le cas avec ces erreurs par défaut, aucun corps de réponse ne sera défini.
Je les trouve utiles lorsque je rejette des demandes qui ne pouvaient raisonnablement avoir été fabriquées qu'à la main, indiquant potentiellement une intention malveillante, car elles masquent le fait que la demande a été rejetée sur la base d'une validation personnalisée plus approfondie et de ses critères.
Hth, dtk
la source
HttpMessageNotReadableException("error description")
est obsolète.Une autre approche consiste à utiliser
@ExceptionHandler
avec@ControllerAdvice
pour centraliser tous vos gestionnaires dans la même classe, sinon vous devez placer les méthodes de gestionnaire dans chaque contrôleur avec lequel vous souhaitez gérer une exception.Votre classe de gestionnaire:
Votre exception personnalisée:
Vous pouvez maintenant lever des exceptions à partir de n'importe lequel de vos contrôleurs, et vous pouvez définir d'autres gestionnaires dans votre classe de conseils.
la source
Je pense que ce fil a en fait la solution la plus simple et la plus propre, qui ne sacrifie pas les outils de martialisation JSON fournis par Spring:
https://stackoverflow.com/a/16986372/1278921
la source