@Aspect
作用是把当前类标识为一个切面供容器读取
@Pointcut
定义切入点
@Before 标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterReturning
后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@AfterThrowing
异常抛出增强,相当于ThrowsAdvice
@After
final增强,不管是抛出异常或者正常退出都会执行
@Around
环绕增强,相当于MethodInterceptor
@DeclareParents
引介增强,相当于IntroductionInterceptor
execution函数用于匹配方法执行的连接点,语法为:
execution(方法修饰符(可选) 返回类型 方法名 参数 异常模式(可选))
一、定义切入点
@Pointcut(“execution(public * com.imooc.controller.Seller*.(…))" + "&& !execution(public * com.imooc.controller.SellerUserController.(…))”) public void verify() {} 二、在RequestContextHolder中获取Request
三、在request中读取cookie和redis中的token
package com.imooc.aspect;
import com.imooc.constant.CookieConstant; import com.imooc.constant.RedisConstant; import com.imooc.exception.SellerAuthorizeException; import com.imooc.utils.CookieUtil; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest;
@Aspect @Component @Slf4j public class SellerAuthorizeAspect {
@Autowired private StringRedisTemplate redisTemplate; @Pointcut("execution(public * com.imooc.controller.Seller*.*(..))" + "&& !execution(public * com.imooc.controller.SellerUserController.*(..))") public void verify() {} @Before("verify()") public void doVerify() { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //查询cookie Cookie cookie = CookieUtil.get(request, CookieConstant.TOKEN); if (cookie == null) { log.warn("【登录校验】Cookie中查不到token"); throw new SellerAuthorizeException(); } //去redis里查询 String tokenValue = redisTemplate.opsForValue().get(String.format(RedisConstant.TOKEN_PREFIX, cookie.getValue())); if (StringUtils.isEmpty(tokenValue)) { log.warn("【登录校验】Redis中查不到token"); throw new SellerAuthorizeException(); } }} 四、捕获异常处理
这里写图片描述
在SpringMVC重要注解(一)@ExceptionHandler和@ResponseStatus我们提到,如果单使用@ExceptionHandler,只能在当前Controller中处理异常。但当配合@ControllerAdvice一起使用的时候,就可以摆脱那个限制了。
package com.imooc.handler;
import com.imooc.VO.ResultVO; import com.imooc.config.ProjectUrlConfig; import com.imooc.exception.ResponseBankException; import com.imooc.exception.SellException; import com.imooc.exception.SellerAuthorizeException; import com.imooc.utils.ResultVOUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.servlet.ModelAndView;
@ControllerAdvice public class SellExceptionHandler {
@Autowired private ProjectUrlConfig projectUrlConfig; //拦截登录异常 //http://sell.natapp4.cc/sell/wechat/qrAuthorize?returnUrl=http://sell.natapp4.cc/sell/seller/login @ExceptionHandler(value = SellerAuthorizeException.class) @ResponseStatus(HttpStatus.FORBIDDEN) public ModelAndView handlerAuthorizeException() { return new ModelAndView("redirect:" .concat(projectUrlConfig.getWechatOpenAuthorize()) .concat("/sell/wechat/qrAuthorize") .concat("?returnUrl=") .concat(projectUrlConfig.getSell()) .concat("/sell/seller/login")); } @ExceptionHandler(value = SellException.class) @ResponseBody public ResultVO handlerSellerException(SellException e) { return ResultVOUtil.error(e.getCode(), e.getMessage()); } @ExceptionHandler(value = ResponseBankException.class) @ResponseStatus(HttpStatus.FORBIDDEN) public void handleResponseBankException() { }}