ssm练手(CRUD) 7、实现新增功能并用JSR303校验

*新增逻辑
1、 index.jsp页面点击新增
2、 弹出对话框
3、 去数据库查询部门列表(因为部门列表是数据库里面的)
4、 用户输入数据,完成表格
我们首先写下部门的Controller和Service
1)DepartmentService.java
这里写图片描述

package com.atguigu.crud.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.atguigu.crud.bean.Department;
import com.atguigu.crud.dao.DepartmentMapper;
@Service
public class DepartmentService {
    @Autowired
    private DepartmentMapper departmentMapper;
    public List<Department> getDepts() {
        // 返回所有查到的部门
        List<Department> list=departmentMapper.selectByExample(null);
        return list;
    }
}

2)DepartmentController.java
这里写图片描述

package com.atguigu.crud.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.atguigu.crud.bean.Department;
import com.atguigu.crud.bean.Msg;
import com.atguigu.crud.service.DepartmentService;
//处理和部门有关的请求
@Controller
public class DepartmentController {
    @Autowired
    private DepartmentService departmentService;
    //返回所有部门的信息
    @RequestMapping("/depts")
    @ResponseBody
    public Msg getDepts(){
        //查出的所有部门信息
        List<Department> list=departmentService.getDepts();
        return Msg.success().add("depts", list);
    }
}

3)EmployeeController.java添加内容

//用于保存员工
    /*
     * 1、要支持JSR303校验,需要导入Hibernate-Validator的依赖
     * 2、要使用,需要添加@Valid表示要校验Employee(该类中已经添加要求)
     *    还要添加BindingResult来封装校验结果
     */
    @RequestMapping(value="/emp",method=RequestMethod.POST)
    @ResponseBody
    public Msg saveEmp(@Valid Employee employee,BindingResult result){
        if(result.hasErrors()){
            //校验失败,需要返回失败,在模态框中显示校验失败的错误信息,遍历错误信息
            //封装个map,用于返回错误信息
            Map<String,Object> map=new HashMap<>();
            List<FieldError> errors=result.getFieldErrors();
            for(FieldError fieldError:errors){
                System.out.println("错误的字段:"+fieldError.getField());
                System.out.println("错误信息:"+fieldError.getDefaultMessage());
                map.put(fieldError.getField(), fieldError.getDefaultMessage());
            }
            return Msg.fail().add("errorFields", map);
        }else{
            employeeService.saveEmp(employee);
            return Msg.success();
        }
    }

    //检查是否员工重复,输入的用户名是否可用
    @ResponseBody
    @RequestMapping("/checkuser")
    public Msg checkuser(@RequestParam("empName")String empName){
        //先判断用户名是否合法的表达式
        String regx="(^[a-zA-Z0-9_-]{4,16}$)|(^[\u2E80-\u9FFF]{2,5})";
        if(!empName.matches(regx)){
            return Msg.fail().add("va_msg", "用户名必须是4-16数字字母组合,或者2-5位中文(后台校验)");
        }
        //数据库用户名重复校验
        boolean b=employeeService.checkUser(empName);
        if(b){
            return Msg.success();
        }else{
            return Msg.fail().add("va_msg", "用户名已存在(后台校验)");
        }
    }

4)EmployeeService.java添加内容

       //员工保存
    public void saveEmp(Employee employee) {
        // TODO Auto-generated method stub
        employeeMapper.insertSelective(employee);
    }

    //检验用户名是否可用
    //如果没有这条记录,则等于0,则返回true,即当前姓名可用
    public boolean checkUser(String empName) {
        // TODO Auto-generated method stub
        EmployeeExample example=new EmployeeExample();
        Criteria criteria= example.createCriteria();
        criteria.andEmpNameEqualTo(empName);
        //countByExample是自动生成的方法,如果有这条记录,就返回大于0,否则返回0
        long count=employeeMapper.countByExample(example);
        return count==0;
    }

5)Employee.java中添加JSR303用于后台校验输入是否正确(如果还没引入所需jar包,请看第六步引入所依赖的包)
只需要在email上添加@Email(message="邮箱格式错误")
以及empName上添加

//Pattern表示自定义注解,regexp属性是正则表达式
    @Pattern(regexp="(^[a-zA-Z0-9_-]{4,16}$)|(^[\u2E80-\u9FFF]{2,5})"
            ,message="用户名必须是4-16数字字母组合,或者2-5位中文(后台校验)")

如图:
这里写图片描述

6)pom中添加后台校验JSR303(Hibernate-Validator)

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>

7)index2.jsp
说明下,form表单中的name属性,对应着bean的属性的话,项目会自动帮我们进行对应配置的,此处我们用bootstrap框架的表单,以及其检验表单数据,在<script> 中进行操作。
此处主要是各种校验功能,关键数据一定要放在后台中校验,毕竟前端校验可以通过浏览器改变来跳过校验。所以应该是(前端+后端+数据库信息)三者加起来进行校验。此处后端校验用JSR303

此处主要校验的内容是:姓名格式是否正确,邮件格式是否正确,新增时姓名是否已存在(可以后用于检验用户名不重复)。index.jsp代码特别乱,但是还在跟着学习就先不管那么多,等全部学完后把代码重新整理下

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>员工列表</title>
<%
    pageContext.setAttribute("APP_PATH", request.getContextPath());
%>
<script type="text/javascript"
    src="${ APP_PATH }/static/js/jquery-1.11.1.min.js"></script>
<link rel="stylesheet"
    href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script
    src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

    <!-- 员工添加的模态框,bootstrap的JavaScript插件,在<script>里写上事件 -->
    <!-- Modal -->
    <div class="modal fade" id="empAddModal" tabindex="-1" role="dialog"
        aria-labelledby="myModalLabel">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal"
                        aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                    <h4 class="modal-title" id="myModalLabel">员工添加</h4>
                </div>
                <div class="modal-body">
                    <!-- 从bootstrap上添加的表单模块 -->
                    <form class="form-horizontal">
                        <div class="form-group">
                            <label class="col-sm-2 control-label">empName</label>
                            <div class="col-sm-10">
                                <!-- name属性可以让spring自动配置,要求就是要对应bean的属性 -->
                                <input type="text" class="form-control" id="empName_add_input"
                                    placeholder="empName" name="empName"> <span
                                    class="help-block"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">email</label>
                            <div class="col-sm-10">
                                <input type="text" class="form-control" id="email_add_input"
                                    placeholder="email@atguigu.com" name="email"> <span
                                    class="help-block"></span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">gender</label>
                            <div class="col-sm-10">
                                <label class="radio-inline"> <input type="radio"
                                    name="gender" id="gender1_add_input" value="M"
                                    checked="checked"></label> <label class="radio-inline"> <input type="radio"
                                    name="gender" id="gender2_add_input" value="F"></label>
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-sm-2 control-label">deptName</label>
                            <div class="col-sm-4">
                                <!-- 部门提交部门id即可 -->
                                <select class="form-control" name="dId" id="dept_add_select">

                                </select>
                            </div>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                    <button type="button" class="btn btn-primary" id="emp_save_btn">保存</button>
                </div>
            </div>
        </div>
    </div>



    <div class="container">
        <!-- 标题 -->
        <div class="row">
            <div class="col-md-12">
                <h1>SSM-CRUD</h1>
            </div>
        </div>
        <!-- 两个按钮 -->
        <div class="row">
            <div class="col-md-4 col-md-offset-8">
                <button class="btn btn-primary" id="emp_add_modal_btn">新增</button>
                <button class="btn btn-danger">删除</button>
            </div>
        </div>
        <!-- 显示表格 -->
        <div class="row">
            <div class="col-md-12">
                <table class="table table-hover" id="emps_table">
                    <thead>
                        <tr>
                            <th>#</th>
                            <th>empName</th>
                            <th>gender</th>
                            <th>email</th>
                            <th>department</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>

                    </tbody>
                </table>
            </div>
        </div>

        <!-- 显示分页信息 -->
        <div class="row">
            <!-- 分页信息 -->
            <div class="col-md-6" id="page_info_area"></div>
            <!-- 分页条信息 -->
            <div class="col-md-6" id="page_nav_area"></div>
        </div>
    </div>
    <script type="text/javascript">
        //全员总记录数
        var totalRecord;

        /*页面加载完成后,直接发送一个ajax请求,要到分页数据*/
        $(function() {
            //直接去第一页
            to_page(1);
        });
        /*==========封装方法:跳到第几页=========*/
        function to_page(pn) {
            $.ajax({
                url : "${APP_PATH}/emps",
                data : "pn=" + pn,
                type : "GET",
                success : function(result) {
                    //console.log(result);
                    //1、解析并显示员工数据
                    build_emps_table(result);
                    //2、解析并显示分页信息
                    build_page_info(result);
                    build_page_nav(result);
                }
            });
        }

        /*=============解析员工数据,并添加到列表下面,形成完整列表模式框架==========*/
        function build_emps_table(result) {
            //在构建之前,先清空,不然数据会叠加
            $("#emps_table tbody").empty();

            //此处要对照JSON数据,获取到员工的list
            var emps = result.extend.pageInfo.list;
            //jquery的遍历,emps为要遍历的参数,后面的为每次遍历返回的内容;index为下标,item为当前的数据
            $.each(emps, function(index, item) {
                //创建列表
                var empIdTd = $("<td></td>").append(item.empId);
                var empNameTd = $("<td></td>").append(item.empName);
                var genderTd = $("<td></td>").append(
                        item.gender == 'M' ? "男" : "女");
                var emailTd = $("<td></td>").append(item.email);
                var deptNameTd = $("<td></td>")
                        .append(item.department.deptName);
                //编辑按钮,利用jquery添加bootstrap所依赖的class
                var editBtn = $("<button></button>").addClass(
                        "btn btn-primary btn-sm").append(
                        $("<span></span>").addClass(
                                "glyphicon glyphicon-pencil")).append("编辑");
                var delBtn = $("<button></button>").addClass(
                        "btn btn-danger btn-sm").append(
                        $("<span></span>")
                                .addClass("glyphicon glyphicon-trash")).append(
                        "删除");
                //把两个按钮写在一起,并且在其中添加一个空格
                var btnTd = $("<td></td>").append(editBtn).append(" ").append(
                        delBtn);
                //append方法执行完成后,还是返回原来的元素,所以可以不停使用append方法添加内容
                $("<tr></tr>").append(empIdTd).append(empNameTd).append(
                        genderTd).append(emailTd).append(deptNameTd).append(
                        btnTd).appendTo("#emps_table tbody");
            });
        }

        /*======================解析页面左下角的信息=======================*/
        function build_page_info(result) {
            $("#page_info_area").empty();
            //找到id=page_info_area的div块 进行操作
            $("#page_info_area").append(
                    "当前" + result.extend.pageInfo.pageNum + "页,总共"
                            + result.extend.pageInfo.pages + "页,总共"
                            + result.extend.pageInfo.total + "记录");
            totalRecord = result.extend.pageInfo.total;
        }
        /*===========用于解析右下角的分页条,创建分页条,并实现跳转功能=========*/
        function build_page_nav(result) {
            $("#page_nav_area").empty();
            //此处的建议对照之前的index.jsp的html部分的代码看,不如太作死
            /*开始构建 首页 末页,第一页...等元素,最后一次性加进去下面 第一段代码就完成了
              <li><a href="#">首页</a></li> 这段代码
             */
            var ul = $("<ul></ul>").addClass("pagination");

            var firstPageLi = $("<li></li>").append(
                    $("<a></a>").append("首页").attr("href", "#"));
            var prePageLi = $("<li></li>").append(
                    $("<a></a>").append("&laquo;"));
            //判断能不能点击前一页或者首页
            if (result.extend.pageInfo.hasPreviousPage == false) {
                firstPageLi.addClass("disabled");
                prePageLi.addClass("disabled");
            } else {
                //为元素添加点击翻页的事件
                firstPageLi.click(function() {
                    to_page(1);
                });
                prePageLi.click(function() {
                    to_page(result.extend.pageInfo.pageNum - 1);
                })
            }

            var nextPageLi = $("<li></li>").append(
                    $("<a></a>").append("&raquo;"));
            var lastPageLi = $("<li></li>").append(
                    $("<a></a>").append("末页").attr("href", "#"));
            //判断能不能点击下一页或者末页
            if (result.extend.pageInfo.hasNextPage == false) {
                nextPageLi.addClass("disabled");
                lastPageLi.addClass("disabled");
            } else {
                nextPageLi.click(function() {
                    to_page(result.extend.pageInfo.pageNum + 1);
                });
                lastPageLi.click(function() {
                    to_page(result.extend.pageInfo.pages);
                })
            }

            //先把首页和前一页图标加上去
            ul.append(firstPageLi).append(prePageLi)
            //遍历页码号 第一页第二页。。。遍历给ul中添加页码提示
            $.each(result.extend.pageInfo.navigatepageNums, function(index,
                    item) {
                var numLi = $("<li></li>").append($("<a></a>").append(item));
                //让当前页面高亮
                if (result.extend.pageInfo.pageNum == item) {
                    numLi.addClass("active");
                }
                //添加单击事件
                numLi.click(function() {
                    to_page(item);
                })
                ul.append(numLi);
            });
            //最后添加后一页和末页提示
            ul.append(nextPageLi).append(lastPageLi);
            //把ul加入到nav元素
            var navEle = $("<nav></nav>").append(ul);
            navEle.appendTo("#page_nav_area");
        }

        /*============每次新增后,再点开新增原来的内容都没消除,此方法就是消除上一条新增后框框中的信息===*/
        function reset_form(ele) {
            //重置内容
            $(ele)[0].reset();
            //清空样式,找到该元素下的所有内容里包含这两个class的内容,清掉它们
            $(ele).find("*").removeClass("has-error has-success");
            //找到所有class为helt-block(提示框所在的一小块区域),清空内容
            $(ele).find(".help-block").text("");
        }

        /*=============点击新增按钮弹出悬浮框,(在“新增”键处)============*/
        $("#emp_add_modal_btn").click(function() {
            //重置表单
            reset_form("#empAddModal form");
            //发送ajax请求,查出部门信息,显示在下拉列表中
            getDepats();
            //弹出框框
            $("#empAddModal").modal({
                //令悬浮框不会删除
                backdrop : "static"
            });
        });

        /*==============封装方法:查出总共有几个部门,然后添加到下拉表中======================*/
        function getDepats() {
            //每次请求前 先清空数据
            $("#dept_add_select").empty();
            $.ajax({
                url : "${APP_PATH}/depts",
                type : "GET",
                success : function(result) {
                    //显示部门信息在下拉列表中
                    $.each(result.extend.depts, function() {
                        var optionEle = $("<option></option>").append(
                                this.deptName).attr("value", this.deptId);
                        optionEle.appendTo("#dept_add_select");
                    });
                }
            });
        }

        /* ===========前端检验数据是否合理,但是这样不保险,在下面还有后台检验====================*/
        function validate_add_form() {
            //1、拿到要校验的数据,使用正则表达式进行校验
            var empName = $("#empName_add_input").val();
            //bootstrap的内容,在input的父元素上添加如下class
            var regName = /(^[a-zA-Z0-9_-]{4,16}$)|(^[\u2E80-\u9FFF]{2,5})/;
            if (!regName.test(empName)) {

                show_validate_msg("#empName_add_input", "error",
                        "用户名格式错误(前端校验)");
                return false;
            } else {
                show_validate_msg("#empName_add_input", "success", "");
            }
            //校验邮箱
            var email = $("#email_add_input").val();
            var regEmail = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/;
            if (!regEmail.test(email)) {
                //bootstrap的内容,在input的父元素上添加如下class
                show_validate_msg("#email_add_input", "error", "邮件格式错误(前端校验)");
                return false;
            } else {
                show_validate_msg("#email_add_input", "success", "");
            }
            return true;
        }

        /*=======================封装检验重复的方法,便于多处引用===============================*/
        function show_validate_msg(ele, status, msg) {
            //应该清空这个元素之前的样式
            $(ele).parent().removeClass("has-success has-error");
            $(ele).next("span").text("");
            if ("success" == status) {
                $(ele).parent().addClass("has-success");
                $(ele).next("span").text("");
            } else if ("error" == status) {
                $(ele).parent().addClass("has-error");
                $(ele).next("span").text(msg);
            }
        }

        /*===========================检验员工是否重复,并进行提示========================*/
        $("#empName_add_input").change(
                function() {
                    var empName = this.value;
                    //发送ajax请求是否可用
                    $.ajax({
                        url : "${APP_PATH}/checkuser",
                        data : "empName=" + empName,
                        type : "POST",
                        success : function(result) {
                            //此处code是Msg.java中的属性
                            if (result.code == 100) {
                                show_validate_msg("#empName_add_input",
                                        "success", "用户名可用");
                                //如果成功,给保存按钮的键添加个自定义的属性,用于判断能不能点下保存
                                $("#emp_save_btn").attr("ajax-va", "success");
                            } else {
                                //传出的错误信息,是在EmployeeController中自定义的va_msg
                                show_validate_msg("#empName_add_input",
                                        "error", result.extend.va_msg);
                                $("#emp_save_btn").attr("ajax-va", "error");
                            }
                        }
                    });
                });

        /*======================点击按钮后,就会保存数据,并且实现在这实现后台检验=====================*/
        $("#emp_save_btn")
                .click(
                        function() {
                            //对提交的数据进行校验
                            if (!validate_add_form()) {
                                return false;
                            }
                            //1、判断之前的ajax用户名是否成功,如果成功,才发送ajax
                            if ($(this).attr("ajax-va") == "error") {
                                return false;
                            }
                            //2、ajax保存员工
                            $
                                    .ajax({
                                        url : "${APP_PATH}/emp",
                                        type : "POST",
                                        data : $("#empAddModal form")
                                                .serialize(),
                                        success : function(result) {
                                            //员工保存成功后,判断返回后台返回的结果状态码(JSR303)
                                            if (result.code == 100) {
                                                //1、关闭模态框;就用bootstrap的方法
                                                $("#empAddModal").modal('hide');

                                                //2、来到最后一页,显示保存的数据
                                                //发送ajax请求显示最后一页数据即可
                                                //此处利用pagehelper中,如果跳转的页面数大,则自动访问最后一页
                                                to_page(totalRecord);
                                            } else {
                                                //有哪个字段的错误信息就显示哪个字段的,undefined是没有错误下会自动带上的信息
                                                if (undefined != result.extend.errorFields.email) {
                                                    //显示邮箱错误信息
                                                    show_validate_msg(
                                                            "#email_add_input",
                                                            "error",
                                                            result.extend.errorFields.email);
                                                }
                                                if (undefined != result.extend.errorFields.empName) {
                                                    //显示员工错误信息
                                                    show_validate_msg(
                                                            "#empName_add_input",
                                                            "error",
                                                            result.extend.errorFields.empName);
                                                }
                                            }
                                        }
                                    });
                        });

        /* ============================以下是修改员工内容======================================== */
    </script>
</body>
</html>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值