欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用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