建站學(xué)堂

網(wǎng)站建設(shè)|使用aop加解密http接口

建站學(xué)堂

2813

字體:

背景

最近,我正在編寫小程序接口,因?yàn)樗陌踩院芨?有必要對(duì)請(qǐng)求參數(shù)和響應(yīng)進(jìn)行加密。如果您對(duì)每種方法進(jìn)行加密和解密,代碼都會(huì)過(guò)于繁瑣,工作量也會(huì)增加。因此,我們將進(jìn)行統(tǒng)一的加密和解密處理,更傳統(tǒng)的方法是通過(guò)攔截器攔截。在這里,我們選擇使用Spring的AOP來(lái)實(shí)現(xiàn)它。

處理方案

1.比較了Spring的五種通知之后,不難發(fā)現(xiàn)環(huán)繞式通知可以解決我們的問(wèn)題。環(huán)繞式通知的特點(diǎn)是什么?

環(huán)繞式通知是所有通知類型中最強(qiáng)大的,可以全方位地控制連接點(diǎn)。您甚至可以控制連接點(diǎn)是否被執(zhí)行。

對(duì)于環(huán)繞聲通知,連接點(diǎn)的參數(shù)類型必須是ProcedingJoinPoint。它是JoinPoint的一個(gè)子接口,允許控制何時(shí)執(zhí)行以及是否執(zhí)行連接點(diǎn)。

需要在環(huán)繞聲通知中顯式調(diào)用Process()方法來(lái)執(zhí)行代理方法。如果您忘記這樣做,通知將被執(zhí)行,但目標(biāo)方法不會(huì)被執(zhí)行。

圍繞通知的方法需要在執(zhí)行目標(biāo)方法后返回結(jié)果,即調(diào)用jointPoint.try()的返回值;否則將出現(xiàn)空指針異常

 

import com.legendnet.elecmeter.utils.EncryptUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
 import org.aspectj.lang.ProceedingJoinPoint;
 import org.aspectj.lang.annotation.Around;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Pointcut;
 import org.springframework.stereotype.Component;
 import org.springframework.web.context.request.RequestContextHolder;
 import org.springframework.web.context.request.ServletRequestAttributes;
 import javax.servlet.http.HttpServletRequest;
 /**
  * @Author 情系IT
  * @Description
  * @Date 2019-12-04 14:55
  */
 @Aspect
 @Slf4j
 @Component
 public class HttpAspect {
     // 定義切點(diǎn)controller包及子包下面的所有方法
    @Pointcut("execution(public * com.legendnet.elecmeter.controller..*.*(..))")
     public void httpRequest(){}
     @Around("httpRequest()")
     public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Exception {
         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
         HttpServletRequest request = attributes.getRequest();
         // target 判斷來(lái)源然后根據(jù)不同的解密算法解密
        String target = request.getParameter("target");
         String paramCode = request.getParameter("param_code");
         paramCode = paramCode.replaceAll(" ", "+");
         if(StringUtils.isNotBlank(paramCode)){
             if("miniProgram".equals(target)){
                 paramCode = EncryptUtils.aesDecrypt(paramCode);
             }
             log.info("請(qǐng)求參數(shù)為:【{}】",paramCode);
         }
         Object proceed = "";
         try {
             proceed = proceedingJoinPoint.proceed();
             if("miniProgram".equals(target)){
                 proceed = EncryptUtils.aesEncrypt(proceed.toString());
             }
         } catch (Throwable throwable) {
             throwable.printStackTrace();
         }
         return proceed;
     }
 }
 controller類
import com.alibaba.fastjson.JSON;
 import com.legendnet.elecmeter.common.ResultBean;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 /**
  * @Author 情系IT
  * @Description
  * @Date 2019-12-04 15:23
  */
 @RestController
 @Slf4j
 public class TestController {
     @RequestMapping("test")
     public String test(@RequestParam("param_code") String paramCode){
         log.info("我已接收到參數(shù),參數(shù)為:【{}】",paramCode);
         ResultBean resultBean = new ResultBean();
         resultBean.fillData("這就是我的響應(yīng)");
         return JSON.toJSONString(resultBean);
     }
 }

[聲明]原創(chuàng)不易,請(qǐng)轉(zhuǎn)發(fā)者備注下文章來(lái)源(hbsjsd.cn)【速建時(shí)代】。