使用基于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;
    }
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值