使用JDK动态代理在controller捕捉service主动抛出的异常
程序员文章站
2022-04-12 22:45:22
需求: 在service层处理业务的时候,总归会有一些校验异常的情况,此时,我们可以在service主动抛出对应的异常(XxxException extends RuntimeException),然后在controller层进行捕捉,进行相应的处理,再返回。弊端: 这将导致,在controller每次调用service方法时,都要进行一次捕捉,以及捕捉后的处理,导致大量重复的代码。处理方式: 通过动态代理,在controller生成service的......
需求:
在service层处理业务的时候,总归会有一些校验异常的情况,此时,我们可以在service主动抛出对应的异常(XxxException extends RuntimeException),然后在controller层进行捕捉,进行相应的处理,再返回。
弊端:
这将导致,在controller每次调用service方法时,都要进行一次捕捉,以及捕捉后的处理,导致大量重复的代码。
处理方式:
通过动态代理,在controller生成service的代理类,再代理中进行try catch,和处理异常。
下面直接上代码:
校验使用的工具类
public class CheckUtil {
public static void checkMobile(String mobile) {
if(!Pattern.matches("^1[3456789]\d{9}$", mobile)) {
throw new XxxException(XxxExceptionEnum.MOBILE_ERROR);
}
}
}
service层
public interface MemberService {
Result login(String mobile, String password);
}
@Service
public class MemberServiceImpl implements MemberService {
@Override
Result login(String mobile, String password) {
// 校验手机号,不匹配会抛出自定义异常
CheckUtil.checkMobile(mobile);
}
}
代理类
public class ServiceProxy<T> implements InvocationHandler {
private final Logger LOG = LoggerFactory.getLogger(ServiceProxy.class);
private T service;
public ServiceProxy(T service) {
this.service = service;
}
// 获取代理service
public Object getService(Class c) {
return Proxy.newProxyInstance(c.getClassLoader(), new Class<?>[]{c}, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String errorMsg;
String code;
try {
Object invoke = method.invoke(service, args);
if(null == invoke) {
return Result.success();
} else {
return invoke;
}
} catch (Exception e){
// 你自己抛出的异常,在这里
if(Objects.equals(e.getCause().getClass(), XxxException.class)) {
LOG.error("执行失败", e);
errorMsg = e.getCause().getMessage();
code = ((XxxException)e.getCause()).getCode();
} else { // 系统抛出的异常在这里
LOG.error("执行异常", e);
errorMsg = e.getMessage();
code = "999999";
}
}
return Result.fault(code, message);
}
}
controller使用
@RestController
@RequestMapping("/member")
public class MemberController {
@Autowired
private MemberService memberService;
private MemberService memberServiceProxy;
@PostConstruct
public void getService() {
memberServiceProxy = (MemberService) new ServiceProxy(memberService).getService(MemberService.class);
}
@RequestMapping("/login")
public ResponsePayload login(
@RequestParam("mobile") String mobile,
@RequestParam("password") String password
) {
return memberServiceProxy.login(mobile, password);
}
}
本文地址:https://blog.csdn.net/sdchencc/article/details/109616957
下一篇: Vue.js2+ArcGIS3四、热力图