springmvc后台拦截form表单重复提交;form提交多个附件

思路:要提交的form中用隐藏域存放一个token,此token伴随form提交,若token和session中一样,则成功,并且将session中token换一个值,若重复提交,token就会不相同

  1. controller

@Controller
@RequestMapping("wechat")
public class WeChatController {
    Logger log = Logger.getLogger(WeChatController.class);//记录log日志

    @RequestMapping("/toadd")
    public String toadd(Model model,HttpServletRequest request){
        String token1 = TokenProccessor.getInstance().makeToken();//创建令牌
        //System.out.println("在Servlet中生成的token:"+token1);
        request.getSession().setAttribute("token", token1);  //在服务器使用session保存token(令牌)
        model.addAttribute("token", token1);
        return "wenjuan";
    }

    @RequestMapping("/addinfo")
    public String addinfo(MdgcContact mdgcContact,MdgcConveyor mc,MdgcCustomer mct,MdgcShip ms,String token,
            @RequestParam(value = "contactBusinessCardPhoto", required = false) MultipartFile contactBusinessCardPhoto,
            @RequestParam(value = "plantPhoto", required = false) MultipartFile plantPhoto,
            @RequestParam(value = "spentBladePhoto", required = false) MultipartFile spentBladePhoto,
            @RequestParam(value = "photo", required = false) MultipartFile photo,
            HttpSession session,HttpServletRequest request,HttpServletResponse response) throws ServletException{
            boolean b = isRepeatSubmit(request,token);//判断用户是否是重复提交(按钮连续快速点击两次)

            //System.out.println("处理用户提交请求!!");
            response.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8"); 
            PrintWriter out = null;
            try {
                out = response.getWriter();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } 
            try {  
                if(b==true){
                    out.println("<script language='javascript'>");   
                    out.println("alert('请勿重复提交');");  
                    out.print("</script>");
                    return null;
                }
                request.getSession().removeAttribute("token");//移除session中的token

                String token1 = TokenProccessor.getInstance().makeToken();//创建令牌
                //System.out.println("在Servlet中生成的token:"+token1);
                request.getSession().setAttribute("token", token1);  //在服务器使用session保存token(令牌)
                if (null != contactBusinessCardPhoto) {
                    String nameString = contactBusinessCardPhoto.getOriginalFilename();
                    System.out.println("======nameString=============="+nameString);
                    System.out.println("======nameString=============="+nameString);
                    System.out.println("======nameString=============="+nameString);
                    System.out.println("======nameString=============="+nameString);
                }

                out.println("<script language='javascript'>");   
                out.println("alert('保存成功');");  
                //out.println("history.back();");   
                out.print("</script>");
            } catch (Exception e) {  
                e.printStackTrace();  
                out.println("<script language='javascript'>");   
                out.println("alert('保存失败');");  
                out.print("</script>");
            }  
            //response.setContentType("text/html; charset=gbk");  

            return null;
    }





    /**
     * 判断客户端提交上来的令牌和服务器端生成的令牌是否一致
     * @param request
     * @return 
     *         true 用户重复提交了表单 
     *         false 用户没有重复提交表单
     */
    private boolean isRepeatSubmit(HttpServletRequest request,String client_token) {
        //1、如果用户提交的表单数据中没有token,则用户是重复提交了表单
        if(client_token==null){
            return true;
        }
        //取出存储在Session中的token
        String server_token = (String) request.getSession().getAttribute("token");
        //2、如果当前用户的Session中不存在Token(令牌),则用户是重复提交了表单
        if(server_token==null){
            return true;
        }
        //3、存储在Session中的Token(令牌)与表单提交的Token(令牌)不同,则用户是重复提交了表单
        if(!client_token.equals(server_token)){
            return true;
        }

        return false;
    }
}

  1. token类(单列模式)

public class TokenProccessor {
    /*
     *单例设计模式(保证类的对象在内存中只有一个)
     *1、把类的构造函数私有
     *2、自己创建一个类的对象
     *3、对外提供一个公共的方法,返回类的对象
     */
    private TokenProccessor(){}

    private static final TokenProccessor instance = new TokenProccessor();

    /**
     * 返回类的对象
     * @return
     */
    public static TokenProccessor getInstance(){
        return instance;
    }

    /**
     * 生成Token
     * Token:Nv6RRuGEVvmGjB+jimI/gw==
     * @return
     */
    public String makeToken(){  //checkException
        //  7346734837483  834u938493493849384  43434384
        String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
        //数据指纹   128位长   16个字节  md5
        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            byte md5[] =  md.digest(token.getBytes());
            //base64编码--任意二进制编码明文字符   adfsdfsdfsf
            BASE64Encoder encoder = new BASE64Encoder();
            return encoder.encode(md5);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}
  1. 页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + path + "/";
%>
<!DOCTYPE html>
<html class="pixel-ratio-2 retina">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>jQuery WeUI</title>

<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
    content="width=device-width, initial-scale=1, user-scalable=no">

<meta name="description"
    content="Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description.
">
<title>html5问卷调查表</title>
<link rel="stylesheet" type="text/css"
    href="<%=basePath%>static/jQuery WeUI_files/weui.min.css" />
<link rel="stylesheet" type="text/css"
    href="<%=basePath%>static/jQuery WeUI_files/jquery-weui.css" />
<link rel="stylesheet" type="text/css"
    href="<%=basePath%>static/jQuery WeUI_files/demos.css" />

<script type="text/javascript"
    src="<%=basePath%>static/jQuery WeUI_files/jquery-2.1.4.js"></script>
<script type="text/javascript"
    src="<%=basePath%>static/jQuery WeUI_files/fastclick.js"></script>
<style type="text/css">
/*文字靠右样式*/
select {
    direction: rtl;
}

select option {
    direction: ltr;
}
</style>
</head>
<body ontouchstart="">
<!-- enctype="multipart/form-data" -->

    <header class="demos-header">
        <h1 class="demos-title">表单</h1>
    </header>
    <iframe name="formsubmit" style="display:none;"> </iframe>  
    <form id="myform" action="<%=basePath%>wechat/addinfo" method="post" enctype="multipart/form-data" onsubmit="return checked()" target="formsubmit">
        <div id="d1" class="ceshi weui-cells weui-cells_form">

            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label">联系人名片照片</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="file" id="contactBusinessCardPhoto"
                        placeholder="联系人名片照片" name="contactBusinessCardPhoto">
                </div>
            </div>
            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label">工厂备注</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="text" placeholder="工厂备注"
                        name="plantNotes">
                </div>
            </div>
            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label">工厂照片</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="file" id="plantPhoto"
                        placeholder="工厂照片" name="plantPhoto">
                </div>
            </div>
            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label">扫码序列号</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="text" placeholder="扫码序列号"
                        name="assemblySerialNumber">
                </div>
            </div>

            <div class="weui-btn-area">
                <a class="weui-btn weui-btn_primary" href="javascript:"
                    onclick="showdiv('#d2','#d1')">下一页</a>
            </div>
        </div>



        <div id="d2" class="ceshi weui-cells weui-cells_form">

            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label"><span style="color:red">*</span>皮带机运行情况:小时/天</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="text" placeholder="皮带机运行情况:小时/天"
                        name="operationScheduleHours" required="required">
                </div>
            </div>

            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label"><span style="color:red">*</span>每次检修天数</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="number" pattern="[0-9]*"
                        placeholder="每次检修天数" name="averageOutageDuration"
                        required="required">
                </div>
            </div>
            <div class="weui-cell"></div>
            <div class="weui-cells__title">
                <label class="weui-label"><span style="color:red">*</span>清扫器有无张紧</label>
            </div>
            <div class="weui-cells weui-cells_radio">
                <label class="weui-cell weui-check__label" for="e11">
                    <div class="weui-cell__bd">
                        <p></p>
                    </div>
                    <div class="weui-cell__ft">
                        <input type="radio" class="weui-check" name="tensionnedCleaner"
                            value="0" id="e11"> <span class="weui-icon-checked"></span>
                    </div>
                </label> <label class="weui-cell weui-check__label" for="e12">

                    <div class="weui-cell__bd">
                        <p></p>
                    </div>
                    <div class="weui-cell__ft">
                        <input type="radio" name="tensionnedCleaner" class="weui-check"
                            id="e12" value="1" checked="checked"> <span
                            class="weui-icon-checked"></span>
                    </div>
                </label>
            </div>




            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label">清扫器品牌</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="text" placeholder="清扫器品牌"
                        name="assemblyManufacturer">
                </div>
            </div>

            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label">其他清扫器厂家</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="text" placeholder="其他清扫器厂家"
                        name="assemblyManufacturerOther">
                </div>
            </div>
            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label"><span style="color:red">*</span>清扫器/刀片物料号</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="text" placeholder="清扫器/刀片物料号"
                        name="assemblyDescriptionPartNumber" required="required">
                </div>
            </div>


            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label class="weui-label"><span style="color:red">*</span>已安装的刀片类型</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="text" placeholder="已安装的刀片类型" required="required"
                        name="bladeProductLineInstalled">
                </div>
            </div>



            <div class="weui-btn-area">
                <a class="weui-btn weui-btn_primary" href="javascript:"
                    onclick="showdiv('#d1','#d2')">上一页</a>
            </div>

            <div class="weui-btn-area">
                <a class="weui-btn weui-btn_primary" href="javascript:"
                    onclick="showdiv('#d3','#d2')">下一页</a>
            </div>
        </div> 
        <div id="d3" class="ceshi weui-cells weui-cells_form">

            <div class="weui-cell weui-cell_select weui-cell_select-after">
                <div class="weui-cell__hd">
                    <label for="" class="weui-label"><span style="color:red">*</span>清扫器使用状态</label>
                </div>
                <div class="weui-cell__bd">
                    <select class="weui-select" name="assemblyCondition">
                        <option value="1">新的</option>
                        <option value="2">正常磨损</option>
                        <option value="3">需要修理</option>
                        <option value="4">需要更换</option>
                    </select>
                </div>
            </div>

            <div class="weui-cell weui-cell_select weui-cell_select-after">
                <div class="weui-cell__hd">
                    <label for="" class="weui-label"><span style="color:red">*</span>刀片磨损情况</label>
                </div>
                <div class="weui-cell__bd">
                    <select class="weui-select" name="bladeCondition">
                        <option value="1">剩余75%-100%磨损周期</option>
                        <option value="2">剩余50%-75%磨损周期</option>
                        <option value="3">剩余25%-50%磨损周期</option>
                        <option value="4">剩余25%以下磨损周期</option>
                        <option value="5">丢失或损坏</option>
                    </select>
                </div>
            </div>

            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label for="" class="weui-label"><span style="color:red">*</span>下次替换所需的时间(月数)</label>
                </div>
                <div class="weui-cell__bd">
                <input class="weui-input" type="text" placeholder="已安装的刀片类型" required="required"
                        name="monthsUntilReplacementNeeded">

                </div>
            </div>


            <div class="weui-cell">
                <div class="weui-cell__hd">
                    <label for="" class="weui-label"><span style="color:red">*</span>皮带宽度(mm)</label>
                </div>
                <div class="weui-cell__bd">
                    <input class="weui-input" type="number" value="" name="beltWidth"
                        required="required">
                </div>
            </div>



            <div class="weui-btn-area">
                <a class="weui-btn weui-btn_primary" href="javascript:"
                    onclick="showdiv('#d2','#d3')">上一页</a>
            </div>
            <div class="weui-btn-area">
                <input type="submit" class="weui-btn weui-btn_primary" value="提交" />
            </div>
        </div>
    </form>





    <script>
        $(function() {
            FastClick.attach(document.body);
        });
    </script>
    <script src="<%=basePath%>static/jQuery WeUI_files/jquery-weui.js"></script>


    <script>
        $("#showTooltips").click(function() {
            var tel = $('#tel').val();
            var code = $('#code').val();
            if (!tel || !/1[3|4|5|7|8]\d{9}/.test(tel)) $.toptip('请输入手机号');
            else if (!code || !/\d{6}/.test(code)) $.toptip('请输入六位手机验证码');
            else $.toptip('提交成功', 'success');
        });

        $(function() {
            $("#d2").hide();
            $("#d3").hide();
        });

        function checked(){
            var flag1 = true;
            $("input[required='required']").each(function() {
                if (null == $(this).val() || isNull($(this).val())) {
                    flag1 = false;
                    return;
                }
            });
            if (!flag1) {
                $.toptip('请输入必填项');
                return flag1;
            }
            return flag1;
        }

        function showdiv(id, nowid) {
            var flag = false;
            $(nowid).find("input[required='required']").each(function() {
                if (null == $(this).val() || isNull($(this).val())) {
                    flag = true;
                    return;
                }
            })
            if (flag) {
                $.toptip('请输入必填项');
                return;
            }
            $(".ceshi").hide();
            $(id).show();
        }
        //判断是否为空或者都是空格
        function isNull(str) {
            if (str == "") return true;
            var regu = "^[ ]+$";
            var re = new RegExp(regu);
            return re.test(str);
        }

    </script>


</body>
</html>

猜你喜欢

转载自blog.csdn.net/sdzhangshulong/article/details/79928991