Java 在 Spring MVC 或 Spring-Boot 中返回不同类型的 ResponseEntity 的最佳方法是什么
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38117717/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to return different types of ResponseEntity in Spring MVC or Spring-Boot
提问by Saveendra Ekanayake
I have written simple rest application using Spring MVC 4 (or Spring-Boot). Within the controller I have return ResponseEntity
. But in some cases I want to give success JSON and if there is validation error I want to give error JSON. Currently success and error responses are totally different, So I have created 2 classes for error and success. Within the controller I want to return ResponseEntity<Success>
, if the internal logic is okay. Otherwise I want to return ResponseEntity<Error>
. Is there any way to do it.
我已经使用 Spring MVC 4(或 Spring-Boot)编写了简单的休息应用程序。在控制器中,我有 return ResponseEntity
。但在某些情况下,我想给出成功的 JSON,如果有验证错误,我想给出错误的 JSON。目前成功和错误响应完全不同,所以我为错误和成功创建了 2 个类。ResponseEntity<Success>
如果内部逻辑没问题,我想在控制器内返回。否则我想退货ResponseEntity<Error>
。有什么办法可以做到。
Success
and Error
are the 2 classes that i use to represent success and error response.
Success
并且Error
是我用来表示成功和错误响应的 2 个类。
采纳答案by Mark Norman
I recommend using Spring's @ControllerAdvice
to handle validation errors. Read this guidefor a good introduction, starting at the section named "Spring Boot Error Handling". For an in-depth discussion, there's an articlein the Spring.io blog that was updated on April, 2018.
我建议使用 Spring@ControllerAdvice
来处理验证错误。阅读本指南以获得很好的介绍,从名为“Spring Boot 错误处理”的部分开始。如需深入讨论,请参阅 Spring.io 博客中的一篇文章,该文章于 2018 年 4 月更新。
A brief summary on how this works:
关于其工作原理的简要总结:
- Your controller method should only return
ResponseEntity<Success>
. It will not be responsible for returning error or exception responses. - You will implement a class that handles exceptions for all controllers. This class will be annotated with
@ControllerAdvice
- This controller advice class will contain methods annotated with
@ExceptionHandler
- Each exception handler method will be configured to handle one or more exception types. These methods are where you specify the response type for errors
- For your example, you would declare (in the controller advice class) an exception handler method for the validation error. The return type would be
ResponseEntity<Error>
- 您的控制器方法应该只返回
ResponseEntity<Success>
. 它不负责返回错误或异常响应。 - 您将实现一个处理所有控制器异常的类。这个类将被注释
@ControllerAdvice
- 这个控制器通知类将包含用注释的方法
@ExceptionHandler
- 每个异常处理程序方法都将被配置为处理一种或多种异常类型。这些方法是您指定错误响应类型的地方
- 对于您的示例,您将(在控制器通知类中)声明验证错误的异常处理程序方法。返回类型将是
ResponseEntity<Error>
With this approach, you only need to implement your controller exception handling in one place for all endpoints in your API. It also makes it easy for your API to have a uniform exception response structure across all endpoints. This simplifies exception handling for your clients.
使用这种方法,您只需在一个地方为 API 中的所有端点实现控制器异常处理。它还使您的 API 在所有端点上拥有统一的异常响应结构变得容易。这简化了客户端的异常处理。
回答by shazinltc
I used to use a class like this. The statusCodeis set when there is an error with the error message set in message. Data is stored either in the Map or in a List as and when appropriate.
我曾经使用过这样的类。所述的StatusCode当存在与在错误消息中设置一个错误被设定消息。数据在适当的时候存储在 Map 或 List 中。
/**
*
*/
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;
}
}
}
Hope this helps.
希望这可以帮助。
回答by Maulik Patel
i am not sure but, I think you can use @ResponseEntity
and @ResponseBody
and send 2 different one is Success and second is error message like :
我不知道,但是,我想你可以使用@ResponseEntity
和@ResponseBody
发送2不同的是成功和第二就像是错误信息:
@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);
}
For more detail refer to this: http://www.concretepage.com/spring-4/spring-4-mvc-jsonp-example-with-rest-responsebody-responseentity
有关更多详细信息,请参阅:http: //www.concretepage.com/spring-4/spring-4-mvc-jsonp-example-with-rest-responsebody-responseentity
回答by Saravana
You can return generic wildcard <?>
to return Success
and Error
on a same request mapping method
您可以返回通用通配符<?>
以返回Success
并Error
使用相同的请求映射方法
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
}
@Mark Norman answer is the correct approach
@Mark Norman 答案是正确的方法
回答by Saveendra Ekanayake
Its possible to return ResponseEntity
without using generics, such as follows,
可以在ResponseEntity
不使用泛型的情况下返回,如下所示,
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);
}
}
回答by sharath
Here is a way that I would do it:
这是我会做的一种方式:
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);
}
回答by NeeruKSingh
You can also implement like this to return Success and Error on a same request mapping method,use Object class(Parent class of every class in java) :-
您也可以像这样实现以在相同的请求映射方法上返回成功和错误,使用对象类(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
}
回答by Ridha10
You can use a map with your object or string like bellow :
您可以将地图与您的对象或字符串一起使用,如下所示:
@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);
}
}