diff --git a/src/main/java/com/aiprose/mbp/conf/ControllerExceptionHandler.java b/src/main/java/com/aiprose/mbp/conf/ControllerExceptionHandler.java new file mode 100644 index 0000000..4cf7d48 --- /dev/null +++ b/src/main/java/com/aiprose/mbp/conf/ControllerExceptionHandler.java @@ -0,0 +1,90 @@ +package com.aiprose.mbp.conf; + +import com.aiprose.mbp.util.Response; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.annotation.Resource; +import java.net.BindException; + + +/** + * @author nelson + * @desc 统一异常处理 + */ +@Slf4j +@RestControllerAdvice +public class ControllerExceptionHandler { + + @Resource + private Response response; + + /** + * 400 - Bad Request 参数绑定出错 + */ + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(BindException.class) + public Response handleBindException(BindException e) { + log.error("绑定参数出错", e); + return response.failure(HttpStatus.BAD_REQUEST,"绑定参数出错"); + } + + /** + * 400 - Bad Request + */ + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(HttpMessageNotReadableException.class) + public Response handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { + log.error("请求参数读取错误", e); + return response.failure(HttpStatus.BAD_REQUEST,"请求参数错误"); + } + + /** + * 400 - Bad Request + */ + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler({MethodArgumentNotValidException.class}) + public Response handleValidationException(MethodArgumentNotValidException e) { + log.error("请求参数验证失败", e); + return response.failure(HttpStatus.BAD_REQUEST,"请求参数验证失败"); + } + + /** + * 405 - Method Not Allowed。HttpRequestMethodNotSupportedException + * 是ServletException的子类,需要Servlet API支持 + */ +// @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED) +// @ExceptionHandler(HttpRequestMethodNotSupportedException.class) +// public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) { +// log.error("请求方法不支持", e); +// return response.failure(HttpStatus.METHOD_NOT_ALLOWED,"请求方法不支持"); +// } + + /** + * 415 - Unsupported Media Type。HttpMediaTypeNotSupportedException + * 是ServletException的子类,需要Servlet API支持 + */ +// @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE) +// @ExceptionHandler({HttpMediaTypeNotSupportedException.class}) +// public Response handleHttpMediaTypeNotSupportedException(Exception e) { +// log.error("content-type类型不支持", e); +// return response.failure(HttpStatus.UNSUPPORTED_MEDIA_TYPE,"content-type类型不支持"); +// } + + + /** + * 500 - Internal Server Error + */ + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + @ExceptionHandler(Exception.class) + public Response handleException(Exception e) { + log.error("服务器内部错误", e); + return response.failure(HttpStatus.INTERNAL_SERVER_ERROR,"服务器内部错误"); + } + +} \ No newline at end of file diff --git a/src/main/java/com/aiprose/mbp/controller/UserController.java b/src/main/java/com/aiprose/mbp/controller/UserController.java index 2a2828d..551cc61 100644 --- a/src/main/java/com/aiprose/mbp/controller/UserController.java +++ b/src/main/java/com/aiprose/mbp/controller/UserController.java @@ -3,6 +3,7 @@ package com.aiprose.mbp.controller; import com.aiprose.mbp.annotation.OperLog; import com.aiprose.mbp.entity.User; import com.aiprose.mbp.service.UserService; +import com.aiprose.mbp.util.Response; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -20,27 +21,31 @@ public class UserController { @Autowired private UserService userService; + @Autowired + private Response response; + @GetMapping("save") - public void save() { + public Response save() { User user = new User(); user.setName("nelson"); - System.out.println(userService.save(user)); + return response.success(userService.save(user)); } @GetMapping("find/name") - public List save(String name) { - return userService.fingByName(name,11); + public Response save(String name) { + return response.success(userService.fingByName(name,11)); } @GetMapping("list") - public List user() { - return userService.list(); + public Response user() { + return response.success(userService.list()); } @ApiOperation(value = "分页") @GetMapping("page") @OperLog(operModul = "用户列表分页",operType = "分页") - public Page page(@RequestParam Integer pageNum,@RequestParam Integer pageSize) { - return userService.page(pageNum,pageSize); + public Response page(@RequestParam Integer pageNum,@RequestParam Integer pageSize) { + Page page = userService.page(pageNum, pageSize); + return response.page(page.getRecords(), page.getTotal()); } } diff --git a/src/main/java/com/aiprose/mbp/util/Response.java b/src/main/java/com/aiprose/mbp/util/Response.java new file mode 100644 index 0000000..eab321a --- /dev/null +++ b/src/main/java/com/aiprose/mbp/util/Response.java @@ -0,0 +1,233 @@ +package com.aiprose.mbp.util; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import org.springframework.context.annotation.Scope; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; + +/** + * 响应对象。包含处理结果(Meta)和返回数据(Data)两部分,在 Controller 处理完请求后将此对象转换成 json 返回给前台。注意: + *
    + *
  • 处理成功一般返回处理结果和返回数据,失败只返回处理结果。具体返回什么需看接口文档。
  • + *
  • 处理成功结果码一般是200,失败码具体看出了什么错,对照 HTTP 响应码填。
  • + *
  • 默认处理方法慎用,前台最想要拿到的还是具体的结果码和信息。
  • + *
+ *

+ * @author :nelson
+ * 修改人:
+ * 修改时间:
+ * 修改备注:
+ *

+ */ +@Component +@Scope("prototype") +@SuppressWarnings(value = "all") +public class Response { + /** + * 默认成功响应码 + */ + private static final Integer DEAFAULT_SUCCESS_CODE = HttpStatus.OK.value(); + /** + * 默认成功响应信息 + */ + private static final String DEAFAULT_SUCCESS_MSG = "请求/处理成功!"; + /** + * 默认失败响应码 + */ + private static final Integer DEAFAULT_FAILURE_CODE = HttpStatus.INTERNAL_SERVER_ERROR.value(); + /** + * 默认失败响应信息 + */ + private static final String DEAFAULT_FAILURE_MSG = "请求/处理失败!"; + + @Getter + private Meta meta; + + @Getter + private Object data; + + @Getter + private Long total =0l; + + + /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓成功↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ + + public Response success() { + this.meta = new Meta(DEAFAULT_SUCCESS_CODE, DEAFAULT_SUCCESS_MSG); + this.data = null; + return this; + } + + + /** + * 处理成功响应,返回自定义响应码、信息和数据。 + * + * @param msg 处理结果信息 + * @return 响应对象 + */ + public Response success(String msg) { + this.meta = new Meta(DEAFAULT_SUCCESS_CODE, msg); + this.data = null; + return this; + } + + /** + * 处理成功响应,返回自定义响应码、信息和数据。 + * + * @param data 返回数据 + * @return 响应对象 + */ + public Response success(Object data) { + this.meta = new Meta(DEAFAULT_SUCCESS_CODE, DEAFAULT_SUCCESS_MSG); + this.data = data; + this.total = 0l; + return this; + } + + /** + * 处理成功响应,返回自定义响应码、信息和数据。 + * + * @param msg 处理结果信息 + * @param data 返回数据 + * @return 响应对象 + */ + public Response success(String msg, Object data) { + this.meta = new Meta(DEAFAULT_SUCCESS_CODE, msg); + this.data = data; + return this; + } + + /** + * 分页数据为空 + * @return + */ + public Response page() { + this.meta = new Meta(DEAFAULT_SUCCESS_CODE, DEAFAULT_SUCCESS_MSG); + this.data = new ArrayList<>(); + this.total = 0l; + return this; + } + + /** + * 分页数据和总数量 + * @return + */ + public Response page(Object data,Long total) { + this.meta = new Meta(DEAFAULT_SUCCESS_CODE, DEAFAULT_SUCCESS_MSG); + this.data = data; + this.total = total; + return this; + } + + /** + * 处理成功响应,返回自定义响应码、信息和数据。 + * + * @param httpStatus HTTP 响应码 + * @param msg 处理结果信息 + * @param data 返回数据 + * @return 响应对象 + */ + public Response success(HttpStatus httpStatus, String msg, Object data) { + this.meta = new Meta(httpStatus.value(), msg); + this.data = data; + return this; + } + + + /*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓失败↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/ + + /** + * 处理失败响应,返回自定义响应码、信息和数据。 + * + * @param msg 处理结果信息 + * @return 响应对象 + */ + public Response failure(String msg) { + this.meta = new Meta(DEAFAULT_FAILURE_CODE, msg); + this.data = null; + return this; + } + + public Response failure(Integer status) { + String msg = "请求异常"; + switch (status){ + case 401: + msg = "请先登录"; + break; + case 404: + msg = "资源找不到"; + break; + case 500: + msg = "服务器异常"; + break; + } + + this.meta = new Meta(status, msg); + this.data = null; + return this; + } + /** + * 处理失败响应,返回自定义响应码、信息和数据。 + * + * @param data 返回数据 + * @return 响应对象 + */ + public Response failure(Object data) { + this.meta = new Meta(DEAFAULT_FAILURE_CODE, DEAFAULT_FAILURE_MSG); + this.data = data; + return this; + } + + /** + * 处理失败响应,返回自定义响应码、信息和数据。 + * + * @param msg 处理结果信息 + * @param data 返回数据 + * @return 响应对象 + */ + public Response failure(String msg, Object data) { + this.meta = new Meta(DEAFAULT_FAILURE_CODE, msg); + this.data = data; + return this; + } + + /** + * 处理失败响应,返回自定义响应码、信息和数据。 + * + * @param httpStatus HTTP 响应码 + * @param msg 处理结果信息 + * @param data 返回数据 + * @return 响应对象 + */ + public Response failure(HttpStatus httpStatus, String msg, Object data) { + this.meta = new Meta(httpStatus.value(), msg); + this.data = data; + return this; + } + + public Response failure(HttpStatus httpStatus, String msg) { + this.meta = new Meta(httpStatus.value(), msg); + this.data = null; + return this; + } + + @Data + @AllArgsConstructor + private class Meta { + + /** + * 处理结果代码,与 HTTP 状态响应码对应 + */ + private Integer code; + + /** + * 处理结果信息 + */ + private String msg; + } +}