基于AOP做一个拦截并能够返回错误信息到前端的示例程序
最近基于AOP做了一个拦截并能够返回错误信息到前端的示例程序,目标
1.通过自定义注解所带参数,进入切面判断是否合法
2.合法的继续访问
3.不合法的通过自定义异常向前端返回错误信息
我能想到的有三个思路
1.filter实现
2.基于HttpServletResponse,也可以重定向
3.自定义异常+@ControllerAdvice
第一种方法,类似SpringSecurity,我没那么做。
第二种方法,无法在切面里获取HttpServletResponse对象,或是HttpServletResponse为null,所以我放弃了,我尝试了如下方法
ServletWebRequest servletContainer = (ServletWebRequest)RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servletContainer.getResponse();
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); ServletWebRequest servletWebRequest=new ServletWebRequest(request); HttpServletResponse response=servletWebRequest.getResponse();
都不行
第三种方法,调通了,自己还无法评估优劣
源代码地址如下:https://github.com/flyingJiang/InterceptorDemo
接下来我挑主要的说,顺便各位帮忙看看这样做是否有缺陷
首先,是切面。我希望实现,满足条件就禁止用户进入api,如果不满足就继续。这个@Around注解,用Before能实现吗?我没能实现,是不是我太纠结return?
package com.flying.aspect; import com.flying.annotation.Auth; import com.flying.exception.MyException; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Aspect @Component public class AuthInterceptor { private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptor.class); private static final String NO_AUTH = "没有权限哦!这是一个切面!"; @Autowired ControllerExceptionHandler controllerExceptionHandler; @Around("execution(public * com.flying.controller.*.*(..)) && @annotation(auth)") public Object checkAuth(ProceedingJoinPoint pjp, Auth auth) throws Throwable{ MethodSignature signature = (MethodSignature) pjp.getSignature(); String authString = auth.value(); LOGGER.info("checkAuth,method: {}, clientCode={}", signature.getMethod().getName(), authString); // Assume that only yes and no permissions are required for authentication if (authString.equals("yes")){ LOGGER.warn("checkAuth,{}", NO_AUTH); return controllerExceptionHandler.handleNoAuthException(new MyException(NO_AUTH)); }else{ return pjp.proceed(); } } }
再者就是我引入切面异常,这样做是不是不好,还有什么号方法吗?
package com.flying.aspect; import com.flying.constant.HttpCodeEnum; import com.flying.entity.Result; import com.flying.exception.MyException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; @ControllerAdvice public class ControllerExceptionHandler { private static final Logger LOGGER = LoggerFactory.getLogger(ControllerExceptionHandler.class); @ExceptionHandler({ MyException.class }) @ResponseBody public Result handleNoAuthException(MyException e) { LOGGER.error("handle handleNoAuthException, ex={}", e.getMessage(), e); Result result = Result.build(HttpCodeEnum.CODE_401.getValue(),e.getMessage()); return result; } }
结果截图
这是bug吗,这个怎么删除?
梦想还是要有的,万一实现了呢!