使用基於servlet的攔截器實現訂單提交控制Demo-SpringAOP

首先提交訂單前需要進行庫存校驗等一系列的準備操作流程,故可以在提交訂單流程的基礎上進行攔截器的預提交操作。

具體Demo如下:

首先編輯攔截器:

package com.sanbang.interceptors;

import org.apache.log4j.Logger;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class putOrderFromsInterceptor implements HandlerInterceptor {

    private static Logger log = Logger.getLogger(putOrderFromsInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //在此可以添加庫存校驗等預提交代碼的部分
        System.out.println("putOrderFromsInterceptor-----------preHandle" );
        log.info("putOrderFromsInterceptor-----------preHandle");
        response.sendRedirect("/front/app/goods/trytest.htm?mess='jhgjh'");
        
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("putOrderFromsInterceptor-----------postHandle" );
        log.info("putOrderFromsInterceptor-----------postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("putOrderFromsInterceptor-----------afterCompletion" );
        log.info("putOrderFromsInterceptor-----------afterCompletion");
    }
}

配置攔截器:

<mvc:interceptors>
		<!--下單攔截 校驗-->
		 <mvc:interceptor>
             <!--下單接口的URL-->
			 <mvc:mapping path="/app/goods/dealImmediatelyBuyGood.htm"/>
			 <bean class="com.sanbang.interceptors.putOrderFromsInterceptor" />
		 </mvc:interceptor>
		
</mvc:interceptors>

具體下單操作方法如下:

@RequestMapping(value = "/dealImmediatelyBuyGood")
	@ResponseBody
	@Transactional(rollbackFor=Exception.class,propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT,timeout=5000)
	public synchronized Object dealImmediatelyBuyGood(HttpServletRequest request, HttpServletResponse response,
			Long WeAddressId, Long goodsId, Double count) {
		Map<String, Object> mmp = null;
		Result rs = Result.failure();
		try {
			ezs_user user = RedisUserSession.getUserInfoByKeyForApp(request);
			if (user == null) {
				rs = Result.failure();
				rs.setErrorcode(DictionaryCode.ERROR_WEB_SESSION_ERROR);
				rs.setMsg("用戶未登錄");
				return rs;
			} else {
				Long auditingusertype_id = user.getEzs_store().getAuditingusertype_id();
				ezs_dict dictCode = dictService.getDictByThisId(auditingusertype_id);
				if (dictCode.getSequence() <= 3) {
					if (user.getEzs_store().getStatus() != 2) {
						rs = Result.failure();
						rs.setErrorcode(DictionaryCode.ERROR_WEB_PARAM_ERROR);
						rs.setMsg("您還未完成實名認證,請去個人中心完成實名認證!");
						return rs;
					}
				}
			}
			ezs_orderform orderForm = new ezs_orderform();
			ezs_goods buyGoods = null;
			// 修改訂單號生成規則
			try{
				buyGoods = this.ezs_goodsMapper.selectByPrimaryKey(goodsId);
				orderForm.setOrder_no(createOrderNo(buyGoods));
			}catch(Exception e){
				e.printStackTrace();
				log.info("訂單號生成失敗");
			}
			boolean isour=this.childCompanyGoodsService.isChildCompanyGood(buyGoods);
			if(isour){
				mmp = this.childCompanyGoodsService.immediateAddOrderFormFunc(orderForm, user, "GOODS", WeAddressId, buyGoods, count);
			}else{
				mmp = this.goodsService.immediateAddOrderFormFunc(orderForm, user, "GOODS", WeAddressId, buyGoods, count);
			}
			Integer ErrorCode = (Integer) mmp.get("ErrorCode");
			if (ErrorCode != null && ErrorCode.equals(DictionaryCode.ERROR_WEB_REQ_SUCCESS)) {
				rs = Result.success();
				rs.setMsg(mmp.get("Msg").toString());
			} else {
				rs = Result.failure();
				rs.setMsg(mmp.get("Msg").toString());
			}
			//判斷是否爲子公司
			/*if(isour&&rs.getSuccess()) {
				rs=CheckOrderService.signContentProcess(rs, orderForm.getOrder_no());
				if(!rs.getSuccess()) {
					throw new Exception("立即下單:簽章錯誤orderno="+orderForm.getOrder_no()+"錯誤信息爲:"+rs.toString());
				}
			}*/
		} catch (Exception e) {
			e.printStackTrace();
			rs.setSuccess(false);
			rs.setMsg("提交訂單失敗");
		}
		
		return rs;
	}

如此即可實現對下單的攔截。

 

亦可使用基於AOP的方式實現下單操作前校驗,如下:基於註解的aspect

首先是execution()函數 用來匹配執行方法的連接點

語法結構:   execution(   方法修飾符  方法返回值  方法所屬類 匹配方法名 (  方法中的形參表 )  方法申明拋出的異常  )

其中(方法返回值、匹配方法名 (  方法中的形參表 ))不能省略的,各部分都支持通配符 “*” 來匹配全部。

比較特殊的爲形參表部分,其支持兩種通配符

  •   "*":代表一個任意類型的參數;
  •   “..”:代表零個或多個任意類型的參數。

例如:

    ()匹配一個無參方法

    (..)匹配一個可接受任意數量參數和類型的方法

    (*)匹配一個接受一個任意類型參數的方法

    (*,Integer)匹配一個接受兩個參數的方法,第一個可以爲任意類型,第二個必須爲Integer。

 代碼實例如下:

首先添加啓用aop配置:

<aop:aspectj-autoproxy proxy-target-class="true" />
package com.sanbang.Aspects;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Aspect
@Component
public class putOrderFormAspect {

    private static Logger log = Logger.getLogger(putOrderFormAspect.class);
    /**
     * 定義一個方法,用於聲明切入點表達式,方法中一般不需要添加其他代碼
     * 使用@Pointcut聲明切入點表達式
     * 後面的通知直接使用方法名來引用當前的切點表達式;如果是其他類使用,加上包名即可
     */
    @Pointcut("execution(public * com.sanbang.app.controller.AppGoodsController.dealImmediatelyBuyGood(..))")
    public void declearJoinPointExpression(){}

    /**
     * 前置通知
     * @param joinPoint
     */
    @Before("declearJoinPointExpression()") //該標籤聲明次方法是一個前置通知:在目標方法開始之前執行
    public void beforMethod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
//獲取目標方法的傳入參數,可按照索引進行獲取        
for (int i=0;i<args.length;i++){
            System.out.println("參數"+i+":"+args[i].toString());
        }
        System.out.println("this method "+methodName+" begin. param<"+ args+">");
        log.info("beforMethod  開始執行。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。");

    }
    /**
     * 後置通知(無論方法是否發生異常都會執行,所以訪問不到方法的返回值)
     * @param joinPoint
     */
    @After("declearJoinPointExpression()")
    public void afterMethod(JoinPoint joinPoint){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("this method "+methodName+" end.");
    }
    /**
     * 返回通知(在方法正常結束執行的代碼)
     * 返回通知可以訪問到方法的返回值!
     * @param joinPoint
     */
    @AfterReturning(value="declearJoinPointExpression()",returning="result")
    public void afterReturnMethod(JoinPoint joinPoint,Object result){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("this method "+methodName+" end.result<"+result+">");
    }
    /**
     * 異常通知(方法發生異常執行的代碼)
     * 可以訪問到異常對象;且可以指定在出現特定異常時執行的代碼
     * @param joinPoint
     * @param ex
     */
    @AfterThrowing(value="declearJoinPointExpression()",throwing="ex")
    public void afterThrowingMethod(JoinPoint joinPoint,Exception ex){
        String methodName = joinPoint.getSignature().getName();
        System.out.println("this method "+methodName+" end.ex message<"+ex+">");
    }
    /**
     * 環繞通知(需要攜帶類型爲ProceedingJoinPoint類型的參數)
     * 環繞通知包含前置、後置、返回、異常通知;ProceedingJoinPoin 類型的參數可以決定是否執行目標方法
     * 且環繞通知必須有返回值,返回值即目標方法的返回值
     * @param point
     */
    @Around(value="declearJoinPointExpression()")
    public Object aroundMethod(ProceedingJoinPoint point){

        Object result = null;
        String methodName = point.getSignature().getName();
        try {
            //前置通知
            System.out.println("The method "+ methodName+" start. param<"+ Arrays.asList(point.getArgs())+">");
            //執行目標方法
            result = point.proceed();
            //返回通知
            System.out.println("The method "+ methodName+" end. result<"+ result+">");
        } catch (Throwable e) {
            //異常通知
            System.out.println("this method "+methodName+" end.ex message<"+e+">");
            throw new RuntimeException(e);
        }
        //後置通知
        System.out.println("The method "+ methodName+" end.");
        return result;
    }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章