1.新建异常类MyException,注意必须继承RuntimeException
public class MyException extends RuntimeException{
/** serialVersionUID*/
private static final long serialVersionUID = -5212079010855161498L;
public MyException(String message){
super(message);
this.message = message;
}
//异常信息
private String message;
public void setMessage(String message) {
this.message = message;
}
}
2. 在代码中抛出异常
@Component
@Aspect
public class Interceptor {
private static final Log LOGGER = LogFactory.getLog(Interceptor.class);
@Autowired
private LogService logService;
private static final String NAMESPACE = "API/";
/**
* 调用接口前拦截
* @param MyInteceptor
*/
@Before("@annotation(importOperate)")
@Around("execution(* com.cmbchina.ccd.oa.socialsecurity.controller.*Controller.*(..))")
private void pointcut(MyInteceptor myInteceptor) {
String operateName = myInteceptor.operateName();
if(StringUtils.isBlank(operateName) || "before".equals(operateName)){
throw new MyException("我的异常");
}
}
/**
* 记录日志
*
* @param joinPoint 切面连接点
* 整个表达式可以分为五个部分:
* 1、execution(): 表达式主体。
* 2、第一个*号:表示返回类型,*号表示所有的类型。
* 3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.cmbchina.ccd.oa.hrtransfer.controller包、子孙包下所有类的方法。
* 4、第二个*号:表示类名,*号表示所有的类。
* 5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
* @return 统一返回报文
* @throws Throwable
*/
@Around("execution(* com.cmbchina.ccd.oa.socialsecurity.controller.*Controller.*(..))")
public Object logInfo(ProceedingJoinPoint joinPoint) {
//拦截的实体类
Object target = joinPoint.getTarget();
//拦截的方法名称
String methodName = joinPoint.getSignature().getName();
//拦截的方法参数
Object[] args = joinPoint.getArgs();
Class clazz = target.getClass();
//判断是否存在requestMapping注释
String path = getNameSpace(clazz);
//添加日志
StopWatch stopWatch = new StopWatch();
stopWatch.start();
AccessLog accessLog = new AccessLog();
//只记录对外暴露的接口日志
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
accessLog.setCreateTime(new Date());
accessLog.setAccessUrl(methodName);
if ("get".equalsIgnoreCase(request.getMethod())) {
accessLog.setParameter(request.getQueryString());
} else {
if (args != null && args.length > 0) {
accessLog.setParameter(JSON.toJSONString(args[0]));
}
}
try {
Object result = joinPoint.proceed();
if (path != null || result != null) {
accessLog.setReturnMsg(JSON.toJSONString(result));
stopWatch.stop();
accessLog.setAccessDuration(stopWatch.getTime());
accessLog.setType(Constant.LogType.LOCAL_SYSTEM);
//获取登录人不需要记录日志
List<String> noLogRecord = Arrays.asList("Employee");
if(!noLogRecord.contains(path)){
logService.createLog(accessLog);
}
}
return result;
} catch (Throwable exp) {
//异常日志
StringBuffer sb = new StringBuffer();
StackTraceElement[] stackArray = exp.getStackTrace();
for (int i = 0; i < stackArray.length; i++) {
StackTraceElement element = stackArray[i];
sb.append(element.toString() + "\n");
}
accessLog.setType(Constant.LogType.LOCAL_SYSTEM_EXCEPTION);
accessLog.setReturnMsg(sb.toString());
logService.createLog(accessLog);
LOGGER.error(sb.toString());
exp.printStackTrace();
throw new MyException(exp.getMessage());
//return null;
}
}
/**
* 调用接口后拦截
* @param myInteceptor
*/
@AfterReturning(returning="result", pointcut="@annotation(myInteceptor)")
public void after(Object result, MyInteceptor myInteceptor){
Response response = (Response) result;
String operateName = myInteceptor.operateName();
if(StringUtils.isBlank(operateName) || "after".equals(operateName)){
if(response != null){
}
}
}
/**
* 获取拦截类的命名空间
*
* @param clazz
* @return
*/
private String getNameSpace(Class clazz) {
String path = null;
boolean present = clazz.isAnnotationPresent(RequestMapping.class);
if (present) {
//得到requestMapping注释
RequestMapping annotation = (RequestMapping) clazz.getAnnotation(RequestMapping.class);
//得到value数组
String[] pathArr = annotation.value();
for (String str : pathArr) {
if (path == null) {
path = str;
} else {
path += str;
}
}
}
return path;
}
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyInteceptor {
String operateName() default "";
}
4.全局捕获异常
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = RuntimeException.class)
@ResponseBody
public Object defaultErrorHandler(Exception e){
e.printStackTrace();
return e.getMessage();
}
// 处理方法参数的异常类型
@ExceptionHandler()
public Object exceptionHandle(Exception e){
e.printStackTrace();
return e.getMessage();
}
}