web-dev-qa-db-fra.com

Que retourner si la méthode du contrôleur Spring MVC ne renvoie pas de valeur?

J'utilise la fonction $.getJSON() de jQuery pour effectuer des appels asynchrones vers mon backend Spring MVC simple. La plupart des méthodes du contrôleur Spring ressemblent à ceci:

@RequestMapping(value = "/someURL", method = RequestMethod.POST)
public @ResponseBody SomePOJO getSomeData(@ModelAttribute Widget widget,
    @RequestParam("type") String type) {
    return someDAO.getSomeData(widget, type);
}   

Les choses sont configurées de telle sorte que chaque contrôleur renvoie le @ResponseBody sous la forme JSON, ce à quoi le client s'attend.

Mais que se passe-t-il lorsqu'une demande n'est pas censée renvoyer de contenu du côté client? Puis-je avoir:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public @ResponseBody void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Si non, quelle est la syntaxe appropriée à utiliser ici? Merci d'avance!

110
IAmYourFaja

vous pouvez retourner void, alors vous devez marquer la méthode avec @ResponseStatus (valeur = HttpStatus.OK) vous n'avez pas besoin de @ResponseBody

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}

Seules les méthodes get renvoient une implicité de code d'état 200, toutes les autres que vous avez effectuent l'une des trois opérations suivantes: 

  • Retourne null et marque la méthode avec @ResponseStatus(value = HttpStatus.OK)
  • Renvoyer un objet et le marquer avec @ResponseBody 
  • Renvoyer une instance HttpEntity 
216
ams

Vous pouvez simplement renvoyer un ResponseEntity avec l'en-tête approprié:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
public ResponseEntity updateDataThatDoesntRequireClientToBeNotified(...){
....
return new ResponseEntity(HttpStatus.OK)
}
40
Biju Kunjummen

Vous pouvez renvoyer l'objet "ResponseEntity" . L'utilisation de l'objet "ResponseEntity" est très pratique à la fois au moment de la construction de l'objet réponse (qui contient le corps de la réponse et du code d'état HTTP) et au moment de l'extraction d'informations .

Des méthodes telles que getHeaders (), getBody (), getContentType (), getStatusCode (), etc., facilitent grandement la lecture de l'objet ResponseEntity.

Vous devez utiliser l'objet ResponseEntity avec un code de statut HTTP de 204 (pas de contenu), qui spécifie spécifiquement que la demande a été traitée correctement et que le corps de la réponse est délibérément vide. Utilisez des codes de statut appropriés pour transmettre les informations appropriées. est très important, surtout si vous créez une API qui sera utilisée par plusieurs applications client.

7
Harley

Oui, vous pouvez utiliser @ResponseBody avec le type de retour void:

@RequestMapping(value = "/updateSomeData" method = RequestMethod.POST)
@ResponseBody
public void updateDataThatDoesntRequireClientToBeNotified(...) {
    ...
}
3
user1338062

Il n'y a rien de mal à renvoyer un @ResponseBody vide et vous devriez le faire pour les demandes POST.

Utilisez des codes d’état HTTP pour définir les erreurs dans les routines du gestionnaire d’exceptions, car d’autres mentionnent l’état de réussite. Une méthode normale, telle que vous la retournerez, renverra un code de réponse de 200 (ce que vous voudrez, tout gestionnaire d’exceptions pourra alors renvoyer un objet d’erreur et un code différent (à savoir 500).

2
Brett Ryan

Mais au fur et à mesure que votre système grandit en taille et en fonctionnalité ... je pense que renvoyer toujours un JSON n'est pas une mauvaise idée du tout. Est-ce plus une question d'architecture/"design à grande échelle".

Vous pouvez penser à toujours conserver un JSON avec deux champs connus: le code et les données. Où code est un code numérique spécifiant le succès de l'opération à effectuer et les données sont des données supplémentaires associées à l'opération/service demandé. 

Allez, quand on utilise un fournisseur de services backend, tout service peut être vérifié pour voir s'il a bien fonctionné.

Donc, je m'en tiens à ne pas laisser spring gérer cela, en exposant les opérations de retour hybrides (certaines données ne renvoient rien d'autre ...) .. instaed Assurez-vous que votre serveur expose une interface plus homogène. Est plus simple à la fin de la journée.

1
Victor

Voici un exemple de code que j'ai fait pour une méthode asynchrone

@RequestMapping(value = "/import", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
public void importDataFromFile(@RequestParam("file") MultipartFile file) 
{
    accountingSystemHandler.importData(file, assignChargeCodes);
}

Vous n'avez pas besoin de renvoyer quoi que ce soit de votre méthode, vous avez uniquement besoin de cette annotation pour que votre méthode retourne OK dans tous les cas

@ResponseStatus(value = HttpStatus.OK)
0
AbdusSalam