注:使用lombok
ResponseResult.java ----- 通用返回体
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/*************************************************************
* 类:json串响应体
* @author Jabwin
*************************************************************
*/
@Data
@Accessors(chain = true)
public class ResponseResult implements Serializable
{
private String resultCode;
private String msg;
private transient T data;
public ResponseResult(String resultCode, String msg)
{
this.resultCode = resultCode;
this.msg = msg;
}
public ResponseResult(String resultCode, String msg, T data)
{
this.resultCode = resultCode;
this.msg = msg;
this.data = data;
}
public static ResponseResult build(String code, String msg, T data)
{
return new ResponseResult<>(code, msg,data);
}
public static ResponseResult build(String code, String msg)
{
return new ResponseResult<>(code, msg);
}
public static ResponseResult build()
{
return new ResponseResult<>(null, null);
}
}
BaseController.java ----- Controller基类
/*************************************************************
* 控制器基类:
* @author Jabwin
*************************************************************
*/
public abstract class BaseController
{
/** 此次请求响应成功 */
protected ResponseResult success(T data)
{
return new ResponseResult("200", "操作成功", data);
}
/** 此次请求响应成功 */
protected ResponseResult success()
{
return ResponseResult.build("200", "操作成功");
}
}
GlobalExceptionHandler.java ----- 全局异常处理
import com.xwj.ssp.templet.exception.ServiceException;
import com.xwj.ssp.templet.ResponseResult;
import feign.FeignException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.QueryTimeoutException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.validation.ConstraintViolationException;
import java.util.List;
/*************************************************************
* 全局异常处理类
* @author Jabwin
*************************************************************
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler
{
/** 返回码:参数错误 */
public static final String RETURN_CODE_ARGUMENT_NOT_VALID = "40500";
/** 返回码:请求方式错误 */
public static final String RETURN_CODE_REQUEST_METHOD_FAIL = "40100";
/** 返回码:远程调用失败 */
public static final String RETURN_CODE_FEIGN_FAIL = "50100";
/** 总异常处理 */
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult handleException(Exception e)
{
log.error(e.getMessage());
ResponseResult result = new ResponseResult<>("90000", "未知错误");
log.info("\r\n==== 未处理异常 ==== 响应参数:{}", result);
return result;
}
/** 请求方式异常处理 */
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseBody
public ResponseResult handleException(HttpRequestMethodNotSupportedException e)
{
log.error(e.getMessage());
ResponseResult result = new ResponseResult<>(RETURN_CODE_REQUEST_METHOD_FAIL, "请求方式错误");
log.info("\r\n==== 请求方式异常 ==== 响应参数:{}", result);
return result;
}
/** mybatis异常处理 */
@ExceptionHandler(DataAccessException.class)
@ResponseBody
public ResponseResult handleDataAccessException(DataAccessException e)
{
log.error(e.getMessage());
ResponseResult result = new ResponseResult<>("50000", "数据库访问错误");
log.info("\r\n==== mybatis异常 ==== 响应参数:{}", result);
return result;
}
/** mybatis异常处理,数据重复插入 */
@ExceptionHandler(DuplicateKeyException.class)
@ResponseBody
public ResponseResult handleDataAccessException(DuplicateKeyException e)
{
log.error(e.getMessage());
ResponseResult result = new ResponseResult<>("50000", "数据重复");
log.info("\r\n==== mybatis异常 ==== 响应参数:{}", result);
return result;
}
/** mybatis异常处理,数据库连接超时 */
@ExceptionHandler(QueryTimeoutException.class)
@ResponseBody
public ResponseResult handleDataAccessException(QueryTimeoutException e)
{
log.error(e.getMessage());
ResponseResult result = new ResponseResult<>("50000", "数据连接超时");
log.info("\r\n==== mybatis异常 ==== 响应参数:{}", result);
return result;
}
//*****************************************************************************************************
/** Validated异常处理,对象 */
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ResponseResult handleException(MethodArgumentNotValidException e)
{
log.error(e.getMessage());
BindingResult result = e.getBindingResult();
final List fieldErrors = result.getFieldErrors();
StringBuilder builder = new StringBuilder();
for(FieldError error : fieldErrors)
{
builder.append(error.getDefaultMessage() + "; ");
}
ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, builder.toString());
log.info("\r\n==== violation异常 ==== 响应参数:{}", reResult);
return reResult;
}
/** validated异常处理,单个参数 */
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResponseResult handleException(ConstraintViolationException e)
{
log.error(e.getMessage());
ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, e.getMessage().replaceAll("^.*:\\s",""));
log.info("\r\n==== violation异常 ==== 响应参数:{}", reResult);
return reResult;
}
//*****************************************************************************************************
/** requestParam异常处理,单个参数 */
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
public ResponseResult handleException(MissingServletRequestParameterException e)
{
log.error(e.getMessage());
ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, "缺少必须的请求参数");
log.info("\r\n==== requestParam异常 ==== 响应参数:{}", reResult);
return reResult;
}
/** requestParam异常处理,单个参数类型错误 */
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
@ResponseBody
public ResponseResult handleException(MethodArgumentTypeMismatchException e)
{
log.error(e.getMessage());
ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, "请求失败,请检查请求参数");
log.info("\r\n==== requestParam异常 ==== 响应参数:{}", reResult);
return reResult;
}
/** Bind异常处理,参数绑定错误 */
@ExceptionHandler(BindException.class)
@ResponseBody
public ResponseResult handleException(BindException e)
{
log.error(e.getMessage());
BindingResult result = e.getBindingResult();
final List fieldErrors = result.getFieldErrors();
StringBuilder builder = new StringBuilder();
for(FieldError error : fieldErrors)
{
builder.append(error.getDefaultMessage() + "; ");
}
ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, builder.toString());
log.info("\r\n==== 请求参数数据绑定异常 ==== 响应参数:{}", reResult);
return reResult;
}
/** Bind异常处理,单个参数类型错误 */
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody
public ResponseResult handleException(HttpMessageNotReadableException e)
{
log.error(e.getMessage());
ResponseResult reResult = new ResponseResult<>(RETURN_CODE_ARGUMENT_NOT_VALID, "请求失败,传入格式无法解析");
log.info("\r\n==== 请求参数数据绑定异常 ==== 响应参数:{}", reResult);
return reResult;
}
//****************************************************************************************************
/** Feign异常处理,调用失败 */
@ExceptionHandler(FeignException.class)
@ResponseBody
public ResponseResult handleException(FeignException e)
{
log.error(e.getMessage());
ResponseResult reResult = new ResponseResult<>(RETURN_CODE_FEIGN_FAIL, "服务访问失败。");
log.info("\r\n==== feign异常 ==== 响应参数:{}", reResult);
return reResult;
}
//****************************************************************************************************
/** service异常处理 */
@ExceptionHandler(ServiceException.class)
@ResponseBody
public ResponseResult handleServiceException(ServiceException e)
{
ResponseResult result = new ResponseResult<>(e.getResultCode(), e.getMsg());
log.info("\r\n==== " + e.getMethod() + " ==== 响应参数:{}", result);
return result;
}
}
ServiceException.java -----通用异常类
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/*************************************************************
* 异常类:服务
* @author Jabwin
*************************************************************
*/
@Data
@Accessors(chain = true)
public class ServiceException extends RuntimeException implements Serializable
{
private String resultCode;
private String msg;
private String method;
public ServiceException(String resultCode, String msg)
{
this.resultCode = resultCode;
this.msg = msg;
}
/** 简单服务异常 */
public static ServiceException simpleThrow(String message)
{
return new ServiceException("500", message);
}
}
LogAspect.java ----- 切面打印日志
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
/*************************************************************
* 切面:为controller层整体出参入参打印日志
* @author Jabwin
*************************************************************
*/
@Aspect
@Component
public class LogAspect
{
@Autowired
private ObjectMapper objectMapper;
private static final String ENTER = "\r\n";
@Around("execution(public * *..controller.*Controller.*(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable
{
Long startTime = System.currentTimeMillis();
Class targetClass = joinPoint.getTarget().getClass();//获取目标类
Signature method = joinPoint.getSignature();//目标方法
String methodName = method.getName();//获取目标类方法名称
Object[] args = joinPoint.getArgs();//参数列表
Field field = targetClass.getDeclaredField("log");
if (field == null || !field.getType().equals(Logger.class)) return joinPoint.proceed();
field.setAccessible(true);
Logger logger = (Logger)field.get(Logger.class);
try
{
StringBuilder argStr = new StringBuilder();
for(Object o : args)
{
if (!argStr.toString().isEmpty()) argStr.append("; ");
argStr.append(objectMapper.writeValueAsString(o));
}
logger.info(ENTER + "==== {} ==== 接入参数:{}", methodName, argStr);
Object returnObj = joinPoint.proceed();
Long exeTime = System.currentTimeMillis() - startTime;//执行时间
logger.info(ENTER + "==== {} ==== 响应时间:{}ms,响应参数:{}" ,methodName, exeTime, objectMapper.writeValueAsString(returnObj));
return returnObj;
}
catch (Exception e)
{
if (logger != null) logger.info(ENTER + "XXXX {} XXXX 抛出异常:【{}】",methodName , e.getClass().getName());
throw e;
}
}
}