1、使用@AfterThrowing异常通知:
注:使用异常通知,不会完全处理异常,异常会向上继续传递给调用者。
1.1自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ProcessException {
Class<? extends Throwable>[] value() default {};
}
1.2编写切面
@Component
@Aspect
public class UserAspect {
@Pointcut("@within(org.springframework.stereotype.Controller)")
private void exceptionProcesser() {}
@AfterThrowing(value = "exceptionProcesser()", throwing = "e")
public void afterThrowingMethod(JoinPoint point, Throwable e) {
Class<?> clazz = point.getTarget().getClass();
Method[] methods = clazz.getMethods();
for (Method m : methods) {
ProcessException anno = m.getAnnotation(ProcessException.class);
if (anno != null) {
Class<? extends Throwable>[] exArr = anno.value();
if (exArr.length == 0) {
if (e instanceof RuntimeException) {
try {
m.invoke(clazz.newInstance(), e);
} catch(Exception ex) {
e.printStackTrace();
}
}
} else {
for (Class<? extends Throwable> exClass : exArr) {
if (exClass.isInstance(e)) {
try {
m.invoke(clazz.newInstance(), e);
} catch(Exception ex) {
e.printStackTrace();
}
}
}
}
break;
}
}
}
}
1.3写全局异常处理方法:
public abstract class BaseController {
@ProcessException(ServiceException.class)
public ResponseResult<Void> handleException(Throwable e) {
System.out.println(e.getMessage());
ResponseResult<Void> result = new ResponseResult<>();
result.setMessage(e.getMessage());
if (e instanceof UsernameDuplicateKeyException) {
result.setState(4001);
} else if (e instanceof InsertException) {
result.setState(4002);
} else if (e instanceof UserNotFoundException) {
result.setState(4003);
} else if (e instanceof PasswordNotMatchException) {
result.setState(4004);
} else if (e instanceof UpdateException) {
result.setState(4005);
}
return result;
}
}
@Controller
@RequestMapping("/users")
public class UserController extends BaseController {
@Autowired
private IUserService userService;
@PostMapping("/login")
@ResponseBody
public ResponseResult<Void> login(String username, String password, HttpSession session) {
User user = userService.login(username, password);
session.setAttribute("uid", user.getUid());
session.setAttribute("username", user.getUsername());
return new ResponseResult<>(SUCCESS);
}
}
@Data
public class ResponseResult<T> implements Serializable {
private static final long serialVersionUID = 8011176026667744133L;
private Integer state;
private String message;
private T data;
public ResponseResult() {
}
public ResponseResult(Integer state) {
this.state = state;
}
public ResponseResult(Integer state, T data) {
this.state = state;
this.data = data;
}
}
2、使用Around环绕通知:
1.1自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ProcessException {
Class<? extends Throwable>[] value() default {};
}
1.2编写切面
@Component
@Aspect
public class UserAspect {
@Pointcut("@within(org.springframework.stereotype.Controller)")
private void exceptionProcesser() {}
@Around(value="exceptionProcesser()")
public Object around(ProceedingJoinPoint jp) throws Throwable {
try {
return jp.proceed();
} catch (Throwable e) {
try {
Class<?> clazz = jp.getTarget().getClass();
Method[] methods = clazz.getMethods();
for (Method m : methods) {
ProcessException anno = m.getAnnotation(ProcessException.class);
if (anno != null) {
Class<? extends Throwable>[] exArr = anno.value();
if (exArr.length == 0) {
if (e instanceof RuntimeException) {
return m.invoke(clazz.newInstance(), e);
}
} else {
for (Class<? extends Throwable> exClass : exArr) {
if (exClass.isInstance(e)) {
return m.invoke(clazz.newInstance(), e);
}
}
}
}
}
throw e;
} catch (Exception ex) {
throw ex;
}
}
}
}
1.3写全局异常处理方法:
public abstract class BaseController {
@ProcessException(ServiceException.class)
public ResponseResult<Void> handleException(Throwable e) {
System.out.println(e.getMessage());
ResponseResult<Void> result = new ResponseResult<>();
result.setMessage(e.getMessage());
if (e instanceof UsernameDuplicateKeyException) {
result.setState(4001);
} else if (e instanceof InsertException) {
result.setState(4002);
} else if (e instanceof UserNotFoundException) {
result.setState(4003);
} else if (e instanceof PasswordNotMatchException) {
result.setState(4004);
} else if (e instanceof UpdateException) {
result.setState(4005);
}
return result;
}
}
@Controller
@RequestMapping("/users")
public class UserController extends BaseController {
@Autowired
private IUserService userService;
@PostMapping("/login")
@ResponseBody
public ResponseResult<Void> login(String username, String password, HttpSession session) {
User user = userService.login(username, password);
session.setAttribute("uid", user.getUid());
session.setAttribute("username", user.getUsername());
return new ResponseResult<>(SUCCESS);
}
}
@Data
public class ResponseResult<T> implements Serializable {
private static final long serialVersionUID = 8011176026667744133L;
private Integer state;
private String message;
private T data;
public ResponseResult() {
}
public ResponseResult(Integer state) {
this.state = state;
}
public ResponseResult(Integer state, T data) {
this.state = state;
this.data = data;
}
}