自定义注解

首先定义注解类:

import java.lang.annotation.*; @Documented @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Token {
    boolean save() default  false;
    boolean remove() default false ;

}

该注解类定义了两个方法,save与remove,其作用在后面的示例中可以看到。下面是该注解应用的拦截器:

import com.jd.fastjson.JSON;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class TokenInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            Token annotation = method.getAnnotation(Token.class);
            if (annotation != null) {
                boolean needSaveSession = annotation.save();
                if (needSaveSession) {
                    request.getSession(false).setAttribute("token", UUID.randomUUID().toString());
                }
                boolean needRemoveSession = annotation.remove();
                if (needRemoveSession) {
                    if (isRepeatSubmit(request)) {
                        Map map = new HashMap();
                        map.put("message","请勿频繁提交!");
                        map.put("error","2");
                        try {
                            PrintWriter printWriter = response.getWriter();
                            printWriter.println(JSON.toJSONString(map));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return false;
                    }
                    request.getSession(false).removeAttribute("token");
                }
            }
            return true;
        } else {
            try {
                return super.preHandle(request, response, handler);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    private boolean isRepeatSubmit(HttpServletRequest request) {
        String serverToken = (String) request.getSession(false).getAttribute("token");
        if (serverToken == null) {
            return true;
        }
        String clinetToken = "";
        if (request.getMethod().equals("GET")) {
            clinetToken = request.getParameter("token");
        } else if (request.getMethod().equals("POST")) {
            clinetToken = request.getParameter("token");
        }
        if (clinetToken == null) {
            return true;
        }
        if (!serverToken.equals(clinetToken)) {
            return true;
        }
        return false;
    }
}

上面的拦截器是实现拦截所有请求,如果请求的方法上面有Token的注解,则判断是否是save,如果是save,则在session中存入一个token值并传值给页面,这是一个特殊值,用于标示是否是首次请求。如果是remove,则判断页面传回来的token值是否与session中的值相同。首次请求肯定是相同的,首次请求过后会执行session对token属性的删除,这样第二次请求时,页面有token值,而session没有,二者对比不相等,就能判断出这是重复的请求,会传给页面一个提示。

页面的ajax请求的提示如下:

$.ajax({
                url: "/xxxxxController/xxxxxMethod?token="+$("input[name=token]").val(),
                type: 'post',
                data: JSON.stringify({"param":param}),
                cache: true,
                contentType: "application/json; charset=utf-8",
                dataType: 'json',
                success: function (data) {
                    if (data.error == 0) {
                        window.location.href = "/xxxxxxController/xxxxxMethod";
                    }else if(data.error ==2){
                        alert(data.message);
                    } else {
                        alert(data.errMsg);
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert("操作异常");
                    window.location.href = "/xxxxxxController/xxxxxMethod";
                }
            });

注解在应用中的代码如下:
第一段代码(访问页面):

@RequestMapping(value = "audit", method = RequestMethod.POST)
    @Token(save = true)
    public String toStrategyAudit(Model model, @RequestParam String param) {
        JSONObject params = JSONObject.parseObject(param);
        String detailId = params.getString("param");
            ························省略······················································································
         model.addAttribute("detailId", detailId);
         return "page/xxxxJsp";
        }

第二段代码(页面提交请求):

@RequestMapping(value = "addTable", method = RequestMethod.POST)
    @ResponseBody
    @Token(remove = true)
    public JSONObject saveTableStructure(@RequestBody String body) {
    try{
        JSONObject result = new JSONObject();
        JSONObject bodyJson = JSONObject.parseObject(body);
        String paramS = bodyJson.getString("tableStructures");
        ········································省略···························································
        tableMapper.addTable(list);
       result.put("error", "0");
       }catch(Exception e) {
            e.printStackTrace();
            result.put("errMsg", "error");
            result.put("error", 1);
        }
        return result;
        }

整个拦截器类是为了防止用户点击提交太频繁,导致后台提交的代码执行多次,会产生很严重的错误。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值