本文共 7300 字,大约阅读时间需要 24 分钟。
org.springframework.boot spring-boot-starter-validation org.springframework.boot spring-boot-starter-web org.projectlombok lombok true
1.1 统一响应体定义
package com.suruomo.unified.result;import lombok.Getter;import lombok.Setter;/** * @author suruomo * @date 2020/8/7 15:36 * @description: 自定义统一响应体 * VO( View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。 */@Getter@Setterpublic class ResultVO{ /** * 状态码,比如1000代表响应成功 */ private int code; /** * 响应信息,用来说明响应情况 */ private String msg; /** * 响应的具体数据 */ private T data; public ResultVO(T data) { this(ResultCode.SUCCESS, data); } public ResultVO(ResultCode resultCode, T data) { this.code = resultCode.getCode(); this.msg = resultCode.getMsg(); this.data = data; }}
1.2 枚举状态码定义
package com.suruomo.unified.result;import lombok.Getter;/** * @author suruomo * @date 2020/8/7 16:10 * @description: 响应码枚举 */@Getterpublic enum ResultCode { //1000系列通用错误 SUCCESS(1000, "操作成功"), FAILED(1001, "接口错误"), VALIDATE_FAILED(1002, "参数校验失败"), ERROR(1003, "未知错误"), //2000系列用户错误 USER_NOT_EXIST(2000,"用户不存在"), USER_LOGIN_FAIL(2001,"用户名或密码错误"), USER_NOT_LOGIN(2002,"用户还未登录,请先登录"), NO_PERMISSION(2003,"权限不足,请联系管理员"); private int code; private String msg; ResultCode(int code, String msg) { this.code = code; this.msg = msg; }}
package com.suruomo.unified.pojo;import lombok.Getter;import lombok.NoArgsConstructor;import lombok.Setter;import javax.validation.constraints.Email;import javax.validation.constraints.NotNull;import javax.validation.constraints.Size;/** * @author suruomo * @date 2020/8/7 15:41 * @description: 实体类 */@Getter@Setter@NoArgsConstructorpublic class User { @NotNull(message = "用户id不能为空") private Long id; @NotNull(message = "用户账号不能为空") @Size(min = 6, max = 11, message = "账号长度必须是6-11个字符") private String account; @NotNull(message = "用户密码不能为空") @Size(min = 6, max = 11, message = "密码长度必须是6-16个字符") private String password; @NotNull(message = "用户邮箱不能为空") @Email(message = "邮箱格式不正确") private String email;}
3.1 自定义异常APIException
package com.suruomo.unified.exception;import com.suruomo.unified.result.ResultCode;import lombok.Getter;/** * @author suruomo * @date 2020/8/7 16:43 * @description: 自定义异常 */@Getterpublic class APIException extends RuntimeException { private int code; private String msg; public APIException() { this(ResultCode.FAILED); } public APIException(ResultCode failed) { this.code=failed.getCode(); this.msg=failed.getMsg(); }}
2.全局异常统一处理
package com.suruomo.unified.exception;import com.suruomo.unified.result.ResultCode;import com.suruomo.unified.result.ResultVO;import lombok.extern.slf4j.Slf4j;import org.springframework.http.HttpStatus;import org.springframework.validation.ObjectError;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 java.util.ArrayList;import java.util.List;/** * @author suruomo * @date 2020/8/7 15:39 * @description: 全局异常处理类 */@RestControllerAdvice@Slf4jpublic class GlobalExceptionHandler { /** * 自定义异常APIException */ @ExceptionHandler(APIException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ResultVO
实现ResponseBodyAdvice接口重写supports和beforeBodyWrite方法避免Controller里返回数据每次都要用响应体来包装package com.suruomo.unified.controller;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import com.suruomo.unified.exception.APIException;import com.suruomo.unified.result.ResultVO;import org.springframework.core.MethodParameter;import org.springframework.http.MediaType;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.bind.annotation.RestControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;/** * @author suruomo * @date 2020/8/7 16:38 * @description: 全局处理增强版Controller,避免Controller里返回数据每次都要用响应体来包装 */@RestControllerAdvice(basePackages = {"com.suruomo.unified.controller"}) // 注意哦,这里要加上需要扫描的包public class ResponseControllerAdvice implements ResponseBodyAdvice{ @Override public boolean supports(MethodParameter returnType, Class > aClass) { // 如果接口返回的类型本身就是ResultVO那就没有必要进行额外的操作,返回false return !returnType.getGenericParameterType().equals(ResultVO.class); } @Override public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType, Class > aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { // String类型不能直接包装,所以要进行些特别的处理 if (returnType.getGenericParameterType().equals(String.class)) { ObjectMapper objectMapper = new ObjectMapper(); try { // 将数据包装在ResultVO里后,再转换为json字符串响应给前端 return objectMapper.writeValueAsString(new ResultVO<>(data)); } catch (JsonProcessingException e) { throw new APIException(); } } // 将原本的数据包装在ResultVO里 return new ResultVO<>(data); }}
注意直接返回String数据不能直接包装,所以需要额外处理
package com.suruomo.unified.controller;import com.suruomo.unified.pojo.User;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;/** * @author suruomo * @date 2020/8/7 15:45 * @description: */@RestControllerpublic class TestController { @GetMapping("/getUser") public User getUser() { User user = new User(); user.setId(1L); user.setAccount("12345678"); user.setPassword("12345678"); user.setEmail("123@qq.com"); return user; } @PostMapping("/addUser") public void addUser(@Valid @RequestBody User user){ }}
1.POST测试
使用postman测试 请求: 返回结果: 2.GET测试 请求: 返回结果:转载地址:http://pkqub.baihongyu.com/