首先,返回有两个状态,status和code
status标识response的状态,有2个值:0成功,-1服务错误。
code跟业务有关,可以有各种数值,99999服务未知异常,10000参数异常,100001创建订单失败等等。这两个状态用枚举类表示。
ResponseStatus
/**
* @Author: ivan
* @Description: 服务状态代码
* @Date: 18/11/26
* @Modified By;
*/
public enum ResponseStatus {
OK(0, "成功"),
ERROR(-1, "服务错误");
private int value;
private String message;
ResponseStatus(int value, String message){
this.value = value;
this.message = message;
}
public int getValue() {
return value;
}
public String getMessage() {
return message;
}
}
ResponseCode
/**
* @Author: ivan
* @Description: 业务状态代码
* @Date: 18/11/26
* @Modified By;
*/
public enum ResponseCode {
FORMAL(0, "业务正常"),
INVALID_PARAM(100000, "参数错误"),
UNKNOWN_FAILED(999999, "服务器未知错误"),
SAVE_FAILED(888888, "保存失败"),
UPDATE_FAILED(777777, "保存失败"),
DELTE_FAILED(666666, "删除失败"),
SEARCH_FLOW_FAILED(555555, "查询任务流的执行详情失败!");
private int value;
private String message;
ResponseCode(int value, String message){
this.value = value;
this.message = message;
}
public int getValue() {
return value;
}
public String getMessage() {
return message;
}
}
然后,是Response类,简单工厂模式,提供build方法,创建正常返回和错误返回Response。
Response
/**
* @Author: ivan
* @Description: 返回值封装
* @Date: Created in 17:26 18/11/26
* @Modified By:
*/
public class Response<T> implements Serializable {
private int status;
private int code;
private String message;
private Object data;
public Response(ResponseStatus status, ResponseCode code, String message, T data) {
this.setStatus(status);
this.setCode(code);
this.setMessage(message);
this.setData(data);
}
public static <T> Response<T> buildSuccessResponse(T data) {
return new Response<T>(ResponseStatus.OK, ResponseCode.FORMAL, null, data);
}
public static <T> Response<T> buildFailResponse(ResponseStatus responseStatus, ResponseCode responseCode,
String message, T data) {
return new Response<T>(responseStatus, responseCode, message, data);
}
public int getStatus() {
return status;
}
public void setStatus(ResponseStatus status) {
this.status = status.getValue();
}
public int getCode() {
return code;
}
public void setCode(ResponseCode code) {
this.code = code.getValue();
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
如果不想在controller里try-catch一般的异常,并且在一定的条件下通过throw控制代码逻辑,我们需要建立ControllerAdvice。
我这个advice会捕捉ApiException(自定义),一般用业务Code码里的错误码和信息,这时候我们可以返回提示性异常。然后就是Exception普通异常,一般提示服务器未知错误。
我这里还处理了一个参数校验异常
/**
* @Author: ivan
* @Description: 全局异常处理advice
* @Date: Created in 20:21 18/11/26
* @Modified By:
*/
@ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 处理全局异常handler, ApiException为业务异常, 其他为服务器未知异常
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public Response<String> handle(Exception e) {
Response<String> response;
if (e instanceof ApiException) {
ApiException error = (ApiException) e;
response = Response.buildFailResponse(ResponseStatus.ERROR, error.getResponseCode(),
error.getResponseCode().getMessage(), null);
} else {
response = Response.buildFailResponse(ResponseStatus.ERROR, ResponseCode.UNKNOWN_FAILED,
ResponseCode.UNKNOWN_FAILED.getMessage(), null);
}
logger.error("[Exception] message={}", e);
return response;
}
/**
* 处理参数校验异常handler
*/
@ExceptionHandler(ValidationException.class)
@ResponseBody
public Response<String> handle(ValidationException e) {
StringBuilder sb = new StringBuilder();
if(e instanceof ConstraintViolationException){
ConstraintViolationException error = (ConstraintViolationException) e;
Set<ConstraintViolation<?>> violations = error.getConstraintViolations();
for (ConstraintViolation<?> item : violations) {
sb.append(item.getMessage());
}
}
logger.error("[Validation] message={}", sb.toString(), e);
return Response.buildFailResponse(ResponseStatus.ERROR, ResponseCode.INVALID_PARAM, sb.toString(), null);
}
}
|