SSM尚硅谷 --雷丰阳

第22-31集

第22集 实现点击实现点击模态框的保存按钮,实现将数据提交给服务器保存

  • 1,实现点击模态框的保存按钮,实现将数据提交给服务器保存

  • 2,发送ajax请求保存员工

  • URI:的定义

    • /emp/{id} GET 查询员工
    • /emp POST 保存员工
    • /emp/{id} PUT 修改员工
    • /emp/{id} DELETE 删除员工
  • //点击模态框的保存按钮实现
                    $("#save_add_btn").click(function () {
                        // 1,实现点击模态框的保存按钮,实现将表单中的数据提交给服务器保存
                        //2,发送ajax请求保存员工
                    // alert($("#empAddBtnModal form").serialize());
                    $.ajax({
                            url:"${APP_PATH}/emp",
                            type:"POST",
                            data:$("#empAddBtnModal form").serialize(),
                            success:function (result) {
                                // alert(result.msg);
                                //保存员工成功,但是遗留两个问题
                                //1,关闭模态框
                                $('#empAddBtnModal').modal('hide');
                                //2,来到最后一页,显示刚才保存的数据
                                //发送ajax来到最后一页即可,两种方式:1,赋予一个较大的数,2,赋予它总记录数
                                to_page(totalRecord);
    //totalRecord: 定义的全局变量,用来记录总记录数
                            }
                        });
                    });
    

第23集 表单信息的校验

  • 使用正则表达式对表单数据进行验证

  • //表单校验
                    function validata_add_form(){
                    //要拿到表单数据要使用正则表达式
                        var empName = $("#input_add_empName").val();
                        var regName = 	/(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
                        if(!regName.test(empName)){
                            alert("用户名可以是2-5位汉字或者6-16位字母和数字")
                        }
                        //校验邮箱
                        var email = $("#input_add_email").val();
                        var regEmail = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
                        if (!regEmail.test(email)){
                            alert("邮箱格式不正确!")
                        }
                        return false;
                    }
    
  • 剩余问题:提示信息是弹窗格式,不太美观

第24集 校验信息的显示优化

  • 使用bootstrap 的css 来优化

  • Bootstrap 对表单控件的校验状态,如 error、warning 和 success 状态,都定义了样式。使用时,添加 .has-warning.has-error.has-success 类到这些控件的父元素即可。任何包含在此元素之内的 .control-label.form-control.help-block 元素都将接受这些校验状态的样式。

  • //表单校验
                    function validata_add_form(){
                    //要拿到表单数据要使用正则表达式
                        var empName = $("#input_add_empName").val();
                        var regName = 	/(^[a-zA-Z0-9_-]{6,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
                        if(!regName.test(empName)){
                            //如果第一次是输入的信息是错误的话,第二次再输入正确格式会显示两个class并存,所以每次校验之前先清除固有的class
    
                            //错误信息的弹窗
                            // alert("用户名可以是2-5位汉字或者6-16位字母和数字的组合");
                            // $("#input_add_empName").parent().addClass("has-success");
                            // $("#input_add_empName").next("span").text("用户名可以是2-5位汉字或者6-16位字母和数字的组合");
                            show_validata_msg("#input_add_empName","error","用户名可以是2-5位汉字或者6-16位字母和数字的组合");
                            return false;
                        }else {
                            show_validata_msg("#input_add_empName","success","");
                        }
    
                        //校验邮箱
                        var email = $("#input_add_email").val();
                        var regEmail = /^[a-z\d]+(\.[a-z\d]+)*@([\da-z](-[\da-z])?)+(\.{1,2}[a-z]+)+$/;
                        if (!regEmail.test(email)){
                            // alert("邮箱格式不正确!");
                            show_validata_msg("#input_add_email","error","邮箱格式不正确");
                            return false;
                        }else{
                            show_validata_msg("#input_add_email","success","");
                        }
                        return true;
                    }
    
                    //校验状态
                    //ele,status,msg: 分别是参数,状态,和提示信息
                    function show_validata_msg(ele,status,msg) {
                        //如果第一次是输入的信息是错误的话,第二次再输入正确格式会显示两个class并存,所以每次校验之前先清除固有的class
                        //清除当前元素的校验状态
                        $(ele).parent().removeClass("has-success has-error");
                        $(ele).next("span").text("");
                        if("success" == status){
                            $(ele).parent().addClass("has-success");
                            $(ele).next("span").text(msg);
                        }else if ("error" == status) {
                            $(ele).parent().addClass("has-error");
                            $(ele).next("span").text(msg);
                        }
                    }
    
    • 注意点就是,当条件不满足时返回false,当两个条件同时满足时才返回true

第25集 ajax 校验用户名是否重复

  • 首先是校验用户名是否重复的验证

    • 1,新增一个方法(function)
    • 2,在Controller中写一个请求
    • 3,在实现类中实现
  • 实现表单数据的清除,即表单重置,避免数据重复保存钻跳过验证的漏洞

  • //新增一个ajax校验用户名是否重复
                    $("#input_add_empName").change(function () {
                        //发送ajax请求校验是否可用
                        var empName = this.value;
                        //这里的value :代表的就是 input_add_empName 这个输入框的值
                        $.ajax({
                            url:"${APP_PATH}/checkUser",
                            data:"empName="+empName,
                            type:"POST",
                            success:function (result) {
                                if(result.code==100){
                                    show_validata_msg("#input_add_empName","success","用户名可用");
                                    //attr("ajax-va","success"): 给保存按钮自定义一个属性
                                    $("#save_add_btn").attr("ajax-va","success");
                                }else{
                                    show_validata_msg("#input_add_empName","error","用户名不可用");
                                    $("#save_add_btn").attr("ajax-va","error");
                                }
                            }
                        })
                    });
    
                    //点击模态框的保存按钮实现,点击保存,实现保存
                    $("#save_add_btn").click(function () {
                        // 1,实现点击模态框的保存按钮,实现将表单中的数据提交给服务器保存
                        //1.1 增加表单信息校验
                        if(!validata_add_form()) {
                            return false;
                        }
                        //1.2 判断之前的ajax用户名验证是否成功
                        if($(this).attr("ajax-va")=="error"){
                            return false;
                        }
                        //2,发送ajax请求保存员工
                    // alert($("#empAddBtnModal form").serialize());
                    $.ajax({
                            url:"${APP_PATH}/emp",
                            type:"POST",
                            data:$("#empAddBtnModal form").serialize(),
                        //serialize: 序列化表格中的内容为字符串
                            success:function (result) {
                                // alert(result.msg);
                                //保存员工成功,但是遗留两个问题
                                //1,关闭模态框
                                $('#empAddBtnModal').modal('hide');
                                //2,来到最后一页,显示刚才保存的数据
                                //发送ajax来到最后一页即可,两种方式:1,赋予一个较大的数,2,赋予它总记录数
                                to_page(totalRecord);
                                //totalRecord: 定义的全局变量,用来记录总记录数
                            }
                        });
                    });
    

第26集 ajax用户名重复校验优化

  • 1,是前端验证和后台验证的冲突

    • 解决:在后台验证中,在数据库验证之前加入与前端逻辑相同的验证

    • @RequestMapping("/checkUser")
          @ResponseBody
          public Msg checkUser(@RequestParam("empName") String empName){
              
              
              //先判断用户名是否合法的表达式
              String regex = "(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5})";
              if(!empName.matches(regex)){
              
              
                  return Msg.fail().add("va_value","用户名可以是6-16位字母和数字的组合或者2-5位汉字!!!");
              }
              //数据库验证
              Boolean b = employeeServiceImpl.checkUser(empName);
              if (b){
              
              
                  return Msg.success();
              }else{
              
              
                  return Msg.fail().add("va_value","用户名可以是6-16位字母和数字的组合或者2-5位汉字!!!");
              }
          }
      
  • 2,是表单样式的残留

    • 解决:使用removeClass

    • 或者使用 find

    • //表单样式及其内容的清除
                      function remove_form(ele){
                          $(ele)[0].reset();
                          //清空表单样式  find("*")清除所有的 ;find(".help-block") :清除提示信息span
                          $(ele).find("*").removeClass("has-error has-success");
                          $(ele).find(".help-block").text("");
                      }
      
                      //这里是点击新增按钮弹出模态框
                      $("#emp_add_btn_modal").click(function () {
                          //清除表单数据,即表单重置(完全重置,包括表单的内容和样式)
                          // $("#empAddBtnModal form")[0].reset();
                          remove_form("#empAddBtnModal form");
                          //getDepts :得到下拉框部门的信息
                          getDepts();
                          $("#empAddBtnModal").modal({
                              //发送ajax请求,查出部门信息,显示在下拉列表中
      
                              //弹出模态框
                              backdrop:"static"
                          });
                      });
      
      

第27集 JSR303 数据校验

  • 完整的校验(jquery 前端校验,ajax用户名重复校验,(重点数据)后端校验,数据库唯一性约束)

  • 使用JSR303数据校验 hibernate-validator

  • <!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.16.Final</version>
    </dependency>
    
  • JSR303的使用

    • @RequestMapping(value = "/emp",method = RequestMethod.POST)
          @ResponseBody
          public Msg saveEmp(@Valid Employee employee, BindingResult result){
              
              
              if(result.hasErrors()){
              
              
              //校验失败,应该返回失败,在模态框中显示校验失败的错误信息
                  Map<String,Object> map = new HashMap<String, Object>();
                  List<FieldError> errors = result.getFieldErrors();
                  for (FieldError error : errors) {
              
              
                      System.out.println("错误的字段名:"+error.getField());
                      System.out.println("错误的信息:"+error.getDefaultMessage());
                      map.put(error.getField(),error.getDefaultMessage());
                  }
                  return Msg.fail().add("errorFields",map);
              }else{
              
              
                  employeeServiceImpl.saveEmp(employee);
                  return Msg.success();
              }
      
          }
      
    • 关键字注解:@Valid

    • @Pattern(regexp = "(^[a-zA-Z0-9_-]{6,16}$)|(^[\\u2E80-\\u9FFF]{2,5})",
         message = "用户名可以是6-16位字母和数字的组合或者2-5位汉字!!!")
         private String empName;
       
         private String gender;
         //注意点:"\" 在js和java中的意义略有不同
         @Email(regexp = "^[a-z\\d]+(\\.[a-z\\d]+)*@([\\da-z](-[\\da-z])?)+(\\.{1,2}[a-z]+)+$",
         message = "邮箱格式不正确!!!")
         private String email;
      
    • 关键字注解:@Pattern @Email

    • 注意点:"" 在js和java中的意义略有不同

第28集 实现修改员工信息

  • 逻辑: 首先就是点击修改按钮,然后获取到员工信息,然后修改完成之后是实现保存

  • 1,为修改按钮添加一个点击事件

  • /*更新员工信息*/
                    //1,绑定点击事件,由于click 是在按钮创建之前就绑定了,所以会绑定不上
                    //2,所以可以在按钮创建的时候绑定,但是带来的问题就是耦合高
                    //3,绑定点击.live(),但是新版的jquery 中删除了这个方法,可以用on() 来代替
                    $(document).on("click",".edit_btn",function (){
                        // alert("edit");
                        //1,点击修改弹出模态框
                        $("#empUpdateBtnModal").modal({
                            backdrop:"static"
                        });
                        //2,查出员工信息,显示员工信息
                        getEmp($(this).attr("edit-id"));
                        //3,查询部门信息,显示部门信息
                        getDepts("#select_Update_dept");
                    });
    
  • 2,获取对应的数据

  • 
    

第29集 显示员工信息

  • 上一集只是实现了点击编辑按钮弹出模态框

  • 接着实现获取员工数据和部门数据

  •     //得到员工信息
                    function getEmp(id) {
                        $.ajax({
                            url:"${APP_PATH}/emp/"+id,
                            type:"GET",
                            success:function (result) {
                                // console.log(result);
                                var empData = result.extend.emp;
                                $("#static_Update_empName").text(empData.empName);
                                $("#input_Update_email").val(empData.email);
                                $("#empUpdateBtnModal input[name=gender]").val([empData.gender]);
                                $("#empUpdateBtnModal select").val([empData.dId]);
                            }
                        })
                    }
    
  • 遇到的问题 : 员工信息的性别(gender)和 部门信息获取总是偶尔失效 ,暂时没有解决

  • 将要更新的员工数据:Employee(empId=2024, empName=null, gender=F, [email protected], dId=2, department=null)

第30 31集 实现点击更新按钮实现更新

  • 首先考虑的是根据id更新,将模态框获得的id赋值给更新按钮

  • 然后需要注意的就是之前我们规定的RestFul风格

  • POST与PUT请求

  • 不支持直接发送PUT,需要配置HttpPutFormContentFilter

  • <!-- 3、使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求 -->
        <filter>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <filter>
            <filter-name>HttpPutFormContentFilter</filter-name>
            <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>HttpPutFormContentFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
  • 但是这个视频是17年的,现在2021年了,在web.xml中HttpPutFormContentFilter是显示过时的状态,但是还是会有效果

  • 实际就是使用ajax发送put请求时候,肯定遇到过后端数据无法被接受到的405错误。

  • 基本思路是从request中获取request,getInputStream()的流 inputMessage

    然后将流中的数据封装到Map中 MultiValueMap 最后将数据重新封装到request对象中去,完成put数据的封装

    实现Toncat的Request不满足的PUT请求类似数据封装层对象这一点操作。

  • 官方文档介绍使用这个新的过滤器,并且支持DELETE方法

  •  <!-- 3、使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求 -->
        <filter>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>HiddenHttpMethodFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!--<filter>-->
            <!--<filter-name>HttpPutFormContentFilter</filter-name>-->
            <!--<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>-->
        <!--</filter>-->
        <!--<filter-mapping>-->
            <!--<filter-name>HttpPutFormContentFilter</filter-name>-->
            <!--<url-pattern>/*</url-pattern>-->
        <!--</filter-mapping>-->
        <filter>
            <filter-name>FormContentFilter</filter-name>
            <filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>FormContentFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    
  • 最后之前的性别和部门信息获取有问题还是没有解决

猜你喜欢

转载自blog.csdn.net/dearand/article/details/113823754
今日推荐