一、maven相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
二、响应码枚举类 StatusCode
package com.lgq.demo.common.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 状态码
*
* @Author: guanqin_li
* @Date: 2020-08-06 10:23
*/
@Getter
@AllArgsConstructor
public enum StatusCode {
/**
* 成功
*/
SUCCESS(200, "SUCCESS"),
/**
* 系统繁忙,请稍后重试
*/
SYS_ERROR(-1, "系统繁忙,请稍后重试"),
/**
* 参数错误
*/
PARAM_ERROR(101, "参数错误"),
/**
* 缺少必填参数
*/
PARAM_MISSING(102, "缺少必填参数"),
/**
* 操作失败
*/
OPERATE_FAILED(302, "操作失败");
private final int code;
private final String desc;
}
三、统一响应实体类 Response
package com.lgq.demo.common.pojo;
import com.lgq.demo.common.constant.StatusCode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 响应结果
*
* @Author: guanqin_li
* @Date: 2020-08-06 10:21
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Response {
/**
* 响应码
*/
private int code;
/**
* 响应信息
*/
private String message;
/**
* 响应数据
*/
private Object data;
public Response setCode(int code) {
this.code = code;
return this;
}
public Response setMessage(String message) {
this.message = message;
return this;
}
public Response setData(Object data) {
this.data = data;
return this;
}
public static Response warn(int code, String message, Object data) {
return Response.builder().code(code).message(message).data(data).build();
}
public static Response warn(StatusCode statusCode, Object data) {
return Response.builder().code(statusCode.getCode()).message(statusCode.getDesc()).data(data).build();
}
public static Response warn(int code, String message) {
return Response.builder().code(code).message(message).build();
}
public static Response warn(StatusCode statusCode) {
return Response.builder().code(statusCode.getCode()).message(statusCode.getDesc()).build();
}
public static Response success() {
return warn(StatusCode.SUCCESS);
}
public static Response success(Object data) {
return warn(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getDesc(), data);
}
/**
* 系统繁忙,请稍后重试
*/
public static Response error() {
return warn(StatusCode.SYS_ERROR);
}
/**
* 系统繁忙,请稍后重试
*/
public static Response error(Object data) {
return warn(StatusCode.SYS_ERROR, data);
}
}
四、Http响应结果封装类 HttpResult 和 HttpClientUtil
HttpResult 和 HttpClientUtil 请参考 HttpClient工具类
五、异常处理
- 业务异常类
package com.lgq.demo.common.exception;
import com.lgq.demo.common.constant.StatusCode;
import lombok.Data;
/**
* 业务异常
*
* @Author: guanqin_li
* @Date: 2020-09-28 15:30
*/
@Data
public class BizException extends RuntimeException {
/**
* 返回给用户的错误码
*/
private int code;
/**
* 返回给用户的错误信息
*/
private String message;
/**
* 日志记录的具体异常信息
*/
private String error;
public BizException(StatusCode statusCode) {
super();
this.code = statusCode.getCode();
this.message = statusCode.getDesc();
this.error = statusCode.getDesc();
}
public BizException(StatusCode statusCode, String message) {
super();
this.code = statusCode.getCode();
this.message = message;
this.error = message;
}
public BizException(StatusCode statusCode, String message, String error) {
super();
this.code = statusCode.getCode();
this.message = message;
this.error = error;
}
}
- 全局统一异常处理
package com.lgq.demo.common.exception;
import com.lgq.demo.common.constant.StatusCode;
import com.lgq.demo.common.pojo.Response;
import com.lgq.demo.common.util.HttpClientUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import javax.validation.Path;
import java.util.stream.Collectors;
/**
* 全局异常处理
*
* @Author: guanqin_li
* @Date: 2020-04-09 9:59
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 校验字段失败的处理
*/
@ExceptionHandler(BindException.class)
public Response bindExceptionHandler(HttpServletRequest request, BindException e) {
FieldError fieldError = e.getBindingResult().getFieldError();
if (null != fieldError) {
String message = String.format("[%s]%s", fieldError.getField(), fieldError.getDefaultMessage());
log.warn("CHECK_PARAM|{}|BindException|{}|{}", null != request ? request.getRequestURI() : "", message, null != request ? HttpClientUtil.getIpAddress(request) : "");
return Response.warn(StatusCode.PARAM_ERROR).setMessage(message);
}
log.warn("CHECK_PARAM|{}|BindException|{}", null != request ? request.getRequestURI() : "", null != request ? HttpClientUtil.getIpAddress(request) : "");
return Response.warn(StatusCode.PARAM_ERROR);
}
/**
* 校验对象字段失败
*/
@ExceptionHandler(ConstraintViolationException.class)
public Response constraintViolationExceptionHandler(HttpServletRequest request, ConstraintViolationException e) {
String message = e.getConstraintViolations().stream().map(constraintViolation -> {
Path path = constraintViolation.getPropertyPath();
String fieldName = null;
for (Path.Node node : path) {
fieldName = node.getName();
}
if (StringUtils.isNotBlank(fieldName)) {
return String.format("[%s]%s", fieldName, constraintViolation.getMessage());
} else {
return null;
}
}).collect(Collectors.joining());
if (StringUtils.isNotBlank(message)) {
log.warn("CHECK_PARAM|{}|ConstraintViolationException|{}|{}", null != request ? request.getRequestURI() : "", message, null != request ? HttpClientUtil.getIpAddress(request) : "");
return Response.warn(StatusCode.PARAM_ERROR).setMessage(message);
}
log.warn("CHECK_PARAM|{}|ConstraintViolationException|{}", null != request ? request.getRequestURI() : "", null != request ? HttpClientUtil.getIpAddress(request) : "");
return Response.warn(StatusCode.PARAM_ERROR);
}
/**
* 请求字段参数缺失的处理
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
public Response constraintViolationExceptionHandler(HttpServletRequest request, MissingServletRequestParameterException e) {
String message = String.format("[%s]%s", e.getParameterName(), StatusCode.PARAM_MISSING.getDesc());
log.warn("CHECK_PARAM|{}|MissingServletRequestParameterException|{}{}", null != request ? request.getRequestURI() : "", message, null != request ? HttpClientUtil.getIpAddress(request) : "");
return Response.warn(StatusCode.PARAM_MISSING).setMessage(message);
}
/**
* json 字段校验失败
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Response methodArgumentNotValidExceptionHandler(HttpServletRequest request, MethodArgumentNotValidException e) {
FieldError fieldError = e.getBindingResult().getFieldError();
if (null != fieldError) {
String message = String.format("[%s]%s", fieldError.getField(), fieldError.getDefaultMessage());
log.warn("CHECK_PARAM|{}|MethodArgumentNotValidException|{}|{}", null != request ? request.getRequestURI() : "", message, null != request ? HttpClientUtil.getIpAddress(request) : "");
return Response.warn(StatusCode.PARAM_ERROR).setMessage(message);
}
log.warn("CHECK_PARAM|{}|MethodArgumentNotValidException|{}|{}", null != request ? request.getRequestURI() : "", e.getMessage(), null != request ? HttpClientUtil.getIpAddress(request) : "");
return Response.warn(StatusCode.PARAM_ERROR);
}
/**
* 业务异常处理
*/
@ExceptionHandler(BizException.class)
public Response exceptionHandler(HttpServletRequest request, BizException e) {
log.error("BUSINESS_ERROR|{}|{}|{}|{}", null != request ? request.getRequestURI() : "", e.getMessage(), e.getError(), null != request ? HttpClientUtil.getIpAddress(request) : "", e);
return Response.warn(e.getCode(), e.getMessage());
}
/**
* 异常处理
*/
@ExceptionHandler(Exception.class)
public Response exceptionHandler(HttpServletRequest request, Exception e) {
log.error("SYS_ERROR|{}|{}: {}|{}", null != request ? request.getRequestURI() : "", e.getClass().getSimpleName(), e.getMessage(), null != request ? HttpClientUtil.getIpAddress(request) : "", e);
return Response.warn(StatusCode.SYS_ERROR);
}
}