转载自:https://www.cnblogs.com/kebibuluan/p/9014986.html
20、尚硅谷_SSM高级整合_新增_创建员工新增的模态框.avi
1、接下来当我们点击增加按钮的时候会弹出一个员工信息的对话框
知识点1:当点击新增的时候会弹出一个bootstrap的一个模态对话框
<!-- Modal --> <div class="modal fade" id="myModal" 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">×</span></button> <h4 class="modal-title" id="myModalLabel">Modal title</h4> </div> <div class="modal-body"> ... </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary">Save changes</button> </div> </div> </div> </div>
知识点2:如何启动一个模态对话框
只需一行 JavaScript 代码,即可通过元素的 id myModal
调用模态框:
$('#myModal').modal(options),
myModal对于的是modal对于的id
知识点3:接下面我们要在modal的boby中添加表单,我们使用下面的这种bootstap的表单
<form> <div class="form-group"> <label for="exampleInputEmail1">Email address</label> <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Email"> </div> <div class="form-group"> <label for="exampleInputPassword1">Password</label> <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password"> </div> <div class="form-group"> <label for="exampleInputFile">File input</label> <input type="file" id="exampleInputFile"> <p class="help-block">Example block-level help text here.</p> </div> <div class="checkbox"> <label> <input type="checkbox"> Check me out </label> </div> <button type="submit" class="btn btn-default">Submit</button> </form>
知识点4:接下来我们要使用到性别的单选按钮
整个页面的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> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <% pageContext.setAttribute("APP_PATH", request.getContextPath()); %> <!-- web路径: 不以/开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题。 以/开始的相对路径,找资源,以服务器的路径为标准(http://localhost:3306);需要加上项目名 http://localhost:3306/crud --> <script type="text/javascript" src="${APP_PATH}/static/js/jquery-2.1.1.js"></script> <link href="${APP_PATH }/static/bootstrap-3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="${APP_PATH}/static/bootstrap-3.3.7/dist/js/bootstrap.min.js"></script> </head> <body> <!-- 新增员工信息的对话框 --> <div class="modal fade" id="addEmpModal" 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">×</span></button> <h4 class="modal-title" id="myModalLabel">新增员工</h4> </div> <div class="modal-body"> <!-- 实体类的表单,表单项 的name需要给实体bean对象的一一对应起来,springmvc会帮我们自动封装--> <form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="empNameModal" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="emailModal" placeholder="Password"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="F"> 男 </label> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="M"> 女 </label> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">部门</label> <div class="col-sm-5"> <select name="dId" id="dIdModal"class="form-control"> <option>1</option> <option>2</option> <option>3</option> <option>4</option> <option>5</option> </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">保存</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="addEmp">新增</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>deptName</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> <!-- 当页面加载完成之后发起ajax请求获得数据 ,不清楚的看锋利jquery教程相当的经典--> <script type="text/javascript"> $(function(){ //页面加载完毕,去首页获得对应的数据 to_page(1); }); //使用ajax到后台服务器查询数据 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); //3、解析显示分页条数据 build_page_nav(result); } }); } //解析服务器返回的json数据,并在员工表中显示出来 function build_emps_table(result){ //在构建之前先清空所有的数据 $("#emps_table tbody").empty(); //第一步:获得所有的员工数据 var emps = result.extend.pageInfo.list; //第二步:对员工数据进行遍历显示出来 $.each(emps,function(index,item){ var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); var gender = item.gender == 'M'?"男":"女"; var genderTd = $("<td></td>").append(gender); var emailTd = $("<td></td>").append(item.email); var departmentNameTd = $("<td></td>").append(item.department.deptName); //添加编辑按钮 var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn") .append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //将上面的table表td数据添加到tr中,这里是一个链式操作 $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(departmentNameTd) .append(btnTd) .appendTo("#emps_table tbody"); //"#emps_table tbody"表示选取id为emps_table下的所有的<tbody>的元素,不清楚的看锋利的jquery书籍相当的经典 }); } //解析显示分页信息 function build_page_info(result){ $("#page_info_area").empty(); $("#page_info_area").append("当前第"+result.extend.pageInfo.pageNum+"页,"+"总共"+result.extend.pageInfo.pages+"页,"+"总共"+ result.extend.pageInfo.total+"条记录"); } //解析右下角的导航栏 function build_page_nav(result){ //page_nav_area $("#page_nav_area").empty(); var ul = $("<ul></ul>").addClass("pagination"); //构建元素 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有前一页,如果没有前一页就不能点击 if(result.extend.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //给前一页和首页添加按钮点击事件 firstPageLi.click(function(){ to_page(1); }); prePageLi.click(function(){ //跳转到当前页的前一页 to_page(result.extend.pageInfo.pageNum-1); }); var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //如果没有下一页不能被点击 if(result.extend.pageInfo.hasNextPage == false){ nextPageLi.addClass("disabled"); lastPageLi.addClass("disabled"); } //给下一页和尾页添加点击事件 nextPageLi.click(function(){ to_page(result.extend.pageInfo.pageNum+1); }); lastPageLi.click(function(){ to_page(result.extend.pageInfo.pages); }); //添加首页和前一页 的提示 ul.append(firstPageLi).append(prePageLi); //1,2,3遍历给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(){ //点击的时候重新使用ajax到服务器查询数据 to_page(item); }); ul.append(numLi); }); //添加下一页和末页 的提示 ul.append(nextPageLi).append(lastPageLi); //把ul加入到nav var navEle = $("<nav></nav>").append(ul); navEle.appendTo("#page_nav_area"); } //点击新增按钮,弹出新增加员工的对话框 $("#addEmp").click(function(){ $('#addEmpModal').modal({ backdrop:'static' }) }); </script> </div> </body> </html>
21、尚硅谷_SSM高级整合_新增_Ajax显示部门信息.avi
对于上面的部门,我们应该使用ajax到后天去查询到部门的信息,然后再显示出来
在后台我们新建一个部门的控制类DepartmentController.java
package com.atguigu.crud.controller; import java.util.HashMap; 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 service; @RequestMapping("/depts") @ResponseBody public Msg getAllDepts(){ List<Department> depts = service.getDepts(); Msg msg = new Msg(); msg.setCode(100); msg.setMsg("查找部门成功"); msg.getExtend().put("depts", depts); return msg; } }
对于的业务操作类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(){ return departmentMapper.selectByExample(null); } }
我们在浏览器输入:http://weiyuan-pc:8080/ssm-curd/depts
就可以查询得到服务器方法的部门的json数据如下
{ "code": 100, "msg": "查找部门成功", "extend": { "depts": [ { "deptId": 1, "deptName": "研发部" }, { "deptId": 2, "deptName": "测试部" } ] } }
接下来我们来看看具体的代码
<%@ 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> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <% pageContext.setAttribute("APP_PATH", request.getContextPath()); %> <!-- web路径: 不以/开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题。 以/开始的相对路径,找资源,以服务器的路径为标准(http://localhost:3306);需要加上项目名 http://localhost:3306/crud --> <script type="text/javascript" src="${APP_PATH}/static/js/jquery-2.1.1.js"></script> <link href="${APP_PATH }/static/bootstrap-3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="${APP_PATH}/static/bootstrap-3.3.7/dist/js/bootstrap.min.js"></script> </head> <body> <!-- 新增员工信息的对话框 --> <div class="modal fade" id="addEmpModal" 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">×</span></button> <h4 class="modal-title" id="myModalLabel">新增员工</h4> </div> <div class="modal-body"> <!-- 实体类的表单,表单项 的name需要给实体bean对象的一一对应起来,springmvc会帮我们自动封装--> <form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="empNameModal" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="emailModal" placeholder="Password"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="F"> 男 </label> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="M"> 女 </label> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">部门</label> <div class="col-sm-5"> <select name="dId" id="dIdModal"class="form-control"> </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">保存</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="addEmp">新增</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>deptName</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> <!-- 当页面加载完成之后发起ajax请求获得数据 ,不清楚的看锋利jquery教程相当的经典--> <script type="text/javascript"> $(function(){ //页面加载完毕,去首页获得对应的数据 to_page(1); }); //使用ajax到后台服务器查询数据 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); //3、解析显示分页条数据 build_page_nav(result); } }); } //解析服务器返回的json数据,并在员工表中显示出来 function build_emps_table(result){ //在构建之前先清空所有的数据 $("#emps_table tbody").empty(); //第一步:获得所有的员工数据 var emps = result.extend.pageInfo.list; //第二步:对员工数据进行遍历显示出来 $.each(emps,function(index,item){ var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); var gender = item.gender == 'M'?"男":"女"; var genderTd = $("<td></td>").append(gender); var emailTd = $("<td></td>").append(item.email); var departmentNameTd = $("<td></td>").append(item.department.deptName); //添加编辑按钮 var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn") .append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //将上面的table表td数据添加到tr中,这里是一个链式操作 $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(departmentNameTd) .append(btnTd) .appendTo("#emps_table tbody"); //"#emps_table tbody"表示选取id为emps_table下的所有的<tbody>的元素,不清楚的看锋利的jquery书籍相当的经典 }); } //解析显示分页信息 function build_page_info(result){ $("#page_info_area").empty(); $("#page_info_area").append("当前第"+result.extend.pageInfo.pageNum+"页,"+"总共"+result.extend.pageInfo.pages+"页,"+"总共"+ result.extend.pageInfo.total+"条记录"); } //解析右下角的导航栏 function build_page_nav(result){ //page_nav_area $("#page_nav_area").empty(); var ul = $("<ul></ul>").addClass("pagination"); //构建元素 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有前一页,如果没有前一页就不能点击 if(result.extend.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //给前一页和首页添加按钮点击事件 firstPageLi.click(function(){ to_page(1); }); prePageLi.click(function(){ //跳转到当前页的前一页 to_page(result.extend.pageInfo.pageNum-1); }); var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //如果没有下一页不能被点击 if(result.extend.pageInfo.hasNextPage == false){ nextPageLi.addClass("disabled"); lastPageLi.addClass("disabled"); } //给下一页和尾页添加点击事件 nextPageLi.click(function(){ to_page(result.extend.pageInfo.pageNum+1); }); lastPageLi.click(function(){ to_page(result.extend.pageInfo.pages); }); //添加首页和前一页 的提示 ul.append(firstPageLi).append(prePageLi); //1,2,3遍历给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(){ //点击的时候重新使用ajax到服务器查询数据 to_page(item); }); ul.append(numLi); }); //添加下一页和末页 的提示 ul.append(nextPageLi).append(lastPageLi); //把ul加入到nav var navEle = $("<nav></nav>").append(ul); navEle.appendTo("#page_nav_area"); } //点击新增按钮,弹出新增加员工的对话框 $("#addEmp").click(function(){ var parent = $("#dIdModal"); //使用ajax请求部门的数据 $.ajax( { url:"${APP_PATH}/depts", type:"GET", success:function(result){ //对result数据进行解析添加到 var depts = result.extend.depts; $.each(depts,function(index,item){ //给option选项设置值应该是deptid var opt = $("<option></option>").append(item.deptName).attr("value",item.deptId); parent.append(opt); }); } } ); $('#addEmpModal').modal({ backdrop:'static' }) }); </script> </div> </body> </html>
22、尚硅谷_SSM高级整合_新增_新增基本完成.avi
接下面我们实现当员工点击保存的时候,实现人员的保存,暂时不实现对输入数据在前台页面和后台的校验
这里要采用restful风格的操作
/emp/id 如果采用get方式 查询id的联系人
/emp post方式保存联系人
/emp/id put方式修改联系人
/emp/id delete方式删除联系人
这里我们使用ajax的方式保存联系人,保存联系人成功之后在ajax成功的回调函数中跳转到最后一页查看刚刚新增成功的联系人,跳转到最后一页需要重新使用ajax再次去查询下联系人。
第二保存联系人成功之后,我们需要关闭新建联系人的摸态对话框
现在我们来看下代码
EmployeeController.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.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.atguigu.crud.bean.Employee; import com.atguigu.crud.bean.Msg; import com.atguigu.crud.dao.EmployeeMapper; import com.atguigu.crud.service.EmployeeService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; /** * * 处理员工的增删改查操作 * */ @Controller public class EmployeeController { @Autowired private EmployeeService employeeService; /** * 负责将PageInfo对象转化成json对象 * */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue ="1") Integer pn) { //使用mybatis分页插件 pn表示当前查询的页数,5表示每页显示第几条 System.out.println("EmployeeController is called pn"+pn); PageHelper.startPage(pn, 5); //在PageHelper.startPage(pn, 5);后面的查询语句就可以实现分页查询 List<Employee> list = employeeService.getAll(); //我们将查询的结果封装到PageInfo对象之中,5表示右下角导航栏的数目是5 PageInfo info = new PageInfo(list,5); Msg msg = new Msg(); msg.setCode(100); msg.setMsg("业务操作成功"); msg.getExtend().put("pageInfo", info); return msg; } /** * 这里一定要注意采用的resetful风格,请求方式必须是post * */ @RequestMapping(value="/save",method=RequestMethod.POST) @ResponseBody public Msg save(Employee employee){ System.out.println("save is calle:"+employee.toString()); Msg msg = new Msg(); employeeService.save(employee); msg.setCode(100); msg.setMsg("保存员工数据成功"); return msg; } }
EmployeeService.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.Employee; import com.atguigu.crud.dao.EmployeeMapper; @Service public class EmployeeService { @Autowired private EmployeeMapper employeeMapper; public List<Employee> getAll(){ List<Employee> list = employeeMapper.selectByExampleWithDept(null); return list; } public void save(Employee employee) { // TODO Auto-generated method stub //这里要注意insert和insertSelevite的区别,使用insert将会null字段插入到数据库中。insertselct不会 //现在要实现员工的id自增长,employee中的id字段传递过来的值是null字段,所以不能使用insert,会将null字段插入 employeeMapper.insertSelective(employee); } }
对应的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> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <% pageContext.setAttribute("APP_PATH", request.getContextPath()); %> <!-- web路径: 不以/开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题。 以/开始的相对路径,找资源,以服务器的路径为标准(http://localhost:3306);需要加上项目名 http://localhost:3306/crud --> <script type="text/javascript" src="${APP_PATH}/static/js/jquery-2.1.1.js"></script> <link href="${APP_PATH }/static/bootstrap-3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="${APP_PATH}/static/bootstrap-3.3.7/dist/js/bootstrap.min.js"></script> </head> <body> <!-- 新增员工信息的对话框 --> <div class="modal fade" id="addEmpModal" 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">×</span></button> <h4 class="modal-title" id="myModalLabel">新增员工</h4> </div> <div class="modal-body"> <!-- 实体类的表单,表单项 的name需要给实体bean对象的一一对应起来,springmvc会帮我们自动封装--> <form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="empNameModal" placeholder="Email"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="emailModal" placeholder="Password"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="F"> 男 </label> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="M"> 女 </label> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">部门</label> <div class="col-sm-5"> <select name="dId" id="dIdModal"class="form-control"> </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 ="saveEmp">保存</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="addEmp">新增</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>deptName</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> <!-- 当页面加载完成之后发起ajax请求获得数据 ,不清楚的看锋利jquery教程相当的经典--> <script type="text/javascript"> //定义一个全局变量,获得当前中的记录数 var total; $(function(){ //页面加载完毕,去首页获得对应的数据 to_page(1); }); //使用ajax到后台服务器查询数据 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); //3、解析显示分页条数据 build_page_nav(result); } }); } //解析服务器返回的json数据,并在员工表中显示出来 function build_emps_table(result){ //在构建之前先清空所有的数据 $("#emps_table tbody").empty(); //第一步:获得所有的员工数据 var emps = result.extend.pageInfo.list; //第二步:对员工数据进行遍历显示出来 $.each(emps,function(index,item){ var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); var gender = item.gender == 'M'?"男":"女"; var genderTd = $("<td></td>").append(gender); var emailTd = $("<td></td>").append(item.email); var departmentNameTd = $("<td></td>").append(item.department.deptName); //添加编辑按钮 var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn") .append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //将上面的table表td数据添加到tr中,这里是一个链式操作 $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(departmentNameTd) .append(btnTd) .appendTo("#emps_table tbody"); //"#emps_table tbody"表示选取id为emps_table下的所有的<tbody>的元素,不清楚的看锋利的jquery书籍相当的经典 }); } //解析显示分页信息 function build_page_info(result){ $("#page_info_area").empty(); $("#page_info_area").append("当前第"+result.extend.pageInfo.pageNum+"页,"+"总共"+result.extend.pageInfo.pages+"页,"+"总共"+ result.extend.pageInfo.total+"条记录"); total = result.extend.pageInfo.total; } //解析右下角的导航栏 function build_page_nav(result){ //page_nav_area $("#page_nav_area").empty(); var ul = $("<ul></ul>").addClass("pagination"); //构建元素 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有前一页,如果没有前一页就不能点击 if(result.extend.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //给前一页和首页添加按钮点击事件 firstPageLi.click(function(){ to_page(1); }); prePageLi.click(function(){ //跳转到当前页的前一页 to_page(result.extend.pageInfo.pageNum-1); }); var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //如果没有下一页不能被点击 if(result.extend.pageInfo.hasNextPage == false){ nextPageLi.addClass("disabled"); lastPageLi.addClass("disabled"); } //给下一页和尾页添加点击事件 nextPageLi.click(function(){ to_page(result.extend.pageInfo.pageNum+1); }); lastPageLi.click(function(){ to_page(result.extend.pageInfo.pages); }); //添加首页和前一页 的提示 ul.append(firstPageLi).append(prePageLi); //1,2,3遍历给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(){ //点击的时候重新使用ajax到服务器查询数据 to_page(item); }); ul.append(numLi); }); //添加下一页和末页 的提示 ul.append(nextPageLi).append(lastPageLi); //把ul加入到nav var navEle = $("<nav></nav>").append(ul); navEle.appendTo("#page_nav_area"); } //点击新增按钮,弹出新增加员工的对话框 $("#addEmp").click(function(){ var parent = $("#dIdModal"); //使用ajax请求部门的数据 $.ajax( { url:"${APP_PATH}/depts", type:"GET", success:function(result){ //对result数据进行解析添加到 var depts = result.extend.depts; $.each(depts,function(index,item){ //给option选项设置值应该是deptid var opt = $("<option></option>").append(item.deptName).attr("value",item.deptId); parent.append(opt); }); } } ); $('#addEmpModal').modal({ backdrop:'static' }) }); //点击保存联系人 $("#saveEmp").click(function(){ $.ajax({ url:"${APP_PATH}/save", data:$("#addEmpModal form").serialize(), type:"post", success:function(result){ //保存联系人成功需要做下面的几件事情 //第一件事情就是让新建联系人的对话框摸太框消失 $("#addEmpModal").modal('hide'); //第二个跳转到最后一页 //这里如何跳转到最后一页了,mybatis分页插件这里提供了一个功能,例如现在员工总数是100人,每页显示5人,最大的分页数目就是5,你如果输入6 //也是按照最大的5来进行查询。员工的总数肯定是大于最大的分页数目的,现在要查询最后一页的数据,我以员工的总数进行查询 //使用ajax重新再查询下最后一页员工的数目 // to_page(total); } }); }); </script> </div> </body> </html>
补充知识点:
data:$("#addEmpModal form").serialize(),使用ajax将表单的数据提交到后台不清楚的看锋利的jquer教程第六章ajax的使用,相当的经典。
23、尚硅谷_SSM高级整合_新增_jQuery前端校验完成.avi
上面我们完成了对新建联系人的添加操作,但是没有对输入的信息进行校验,例如输入的邮箱必须满足邮箱格式,输入的姓名必须满足特定的格式,并且新建的联系人在后台数据库中不能存在
24、尚硅谷_SSM高级整合_新增_校验信息显示优化.avi
Bootstrap 对表单控件的校验状态,如 error、warning 和 success 状态,都定义了样式。使用时,添加 .has-warning
、.has-error
或 .has-success
类到这些控件的父元素即可。任何包含在此元素之内的 .control-label
、.form-control
和 .help-block
元素都将接受这些校验状态的样式。
现在例如:
要实现上面的这种功能,如何实现了找到
原理就是校验失败的时候,给当前input的父元素添加has-error属性,显示文字给span元素添加help-block属性,在添加属性之前记得先清除掉之前的所有属性
整个代码如下
<%@ 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> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <% pageContext.setAttribute("APP_PATH", request.getContextPath()); %> <!-- web路径: 不以/开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题。 以/开始的相对路径,找资源,以服务器的路径为标准(http://localhost:3306);需要加上项目名 http://localhost:3306/crud --> <script type="text/javascript" src="${APP_PATH}/static/js/jquery-2.1.1.js"></script> <link href="${APP_PATH }/static/bootstrap-3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="${APP_PATH}/static/bootstrap-3.3.7/dist/js/bootstrap.min.js"></script> </head> <body> <!-- 新增员工信息的对话框 --> <div class="modal fade" id="addEmpModal" 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">×</span></button> <h4 class="modal-title" id="myModalLabel">新增员工</h4> </div> <div class="modal-body"> <!-- 实体类的表单,表单项 的name需要给实体bean对象的一一对应起来,springmvc会帮我们自动封装--> <form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="empNameModal" placeholder="name"> <span id="name_span" class="help-block"></span> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="emailModal" placeholder="eamil"> <span id="email_span" class="help-block"></span> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="F"> 男 </label> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="M"> 女 </label> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">部门</label> <div class="col-sm-5"> <select name="dId" id="dIdModal"class="form-control"> </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 ="saveEmp">保存</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="addEmp">新增</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>deptName</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> <!-- 当页面加载完成之后发起ajax请求获得数据 ,不清楚的看锋利jquery教程相当的经典--> <script type="text/javascript"> //定义一个全局变量,获得当前中的记录数 var total; $(function(){ //页面加载完毕,去首页获得对应的数据 to_page(1); }); //使用ajax到后台服务器查询数据 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); //3、解析显示分页条数据 build_page_nav(result); } }); } //解析服务器返回的json数据,并在员工表中显示出来 function build_emps_table(result){ //在构建之前先清空所有的数据 $("#emps_table tbody").empty(); //第一步:获得所有的员工数据 var emps = result.extend.pageInfo.list; //第二步:对员工数据进行遍历显示出来 $.each(emps,function(index,item){ var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); var gender = item.gender == 'M'?"男":"女"; var genderTd = $("<td></td>").append(gender); var emailTd = $("<td></td>").append(item.email); var departmentNameTd = $("<td></td>").append(item.department.deptName); //添加编辑按钮 var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn") .append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //将上面的table表td数据添加到tr中,这里是一个链式操作 $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(departmentNameTd) .append(btnTd) .appendTo("#emps_table tbody"); //"#emps_table tbody"表示选取id为emps_table下的所有的<tbody>的元素,不清楚的看锋利的jquery书籍相当的经典 }); } //解析显示分页信息 function build_page_info(result){ $("#page_info_area").empty(); $("#page_info_area").append("当前第"+result.extend.pageInfo.pageNum+"页,"+"总共"+result.extend.pageInfo.pages+"页,"+"总共"+ result.extend.pageInfo.total+"条记录"); total = result.extend.pageInfo.total; } //解析右下角的导航栏 function build_page_nav(result){ //page_nav_area $("#page_nav_area").empty(); var ul = $("<ul></ul>").addClass("pagination"); //构建元素 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有前一页,如果没有前一页就不能点击 if(result.extend.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //给前一页和首页添加按钮点击事件 firstPageLi.click(function(){ to_page(1); }); prePageLi.click(function(){ //跳转到当前页的前一页 to_page(result.extend.pageInfo.pageNum-1); }); var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //如果没有下一页不能被点击 if(result.extend.pageInfo.hasNextPage == false){ nextPageLi.addClass("disabled"); lastPageLi.addClass("disabled"); } //给下一页和尾页添加点击事件 nextPageLi.click(function(){ to_page(result.extend.pageInfo.pageNum+1); }); lastPageLi.click(function(){ to_page(result.extend.pageInfo.pages); }); //添加首页和前一页 的提示 ul.append(firstPageLi).append(prePageLi); //1,2,3遍历给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(){ //点击的时候重新使用ajax到服务器查询数据 to_page(item); }); ul.append(numLi); }); //添加下一页和末页 的提示 ul.append(nextPageLi).append(lastPageLi); //把ul加入到nav var navEle = $("<nav></nav>").append(ul); navEle.appendTo("#page_nav_area"); } //点击新增按钮,弹出新增加员工的对话框 $("#addEmp").click(function(){ var parent = $("#dIdModal"); //使用ajax请求部门的数据 $.ajax( { url:"${APP_PATH}/depts", type:"GET", success:function(result){ //对result数据进行解析添加到 var depts = result.extend.depts; $.each(depts,function(index,item){ //给option选项设置值应该是deptid var opt = $("<option></option>").append(item.deptName).attr("value",item.deptId); parent.append(opt); }); } } ); $('#addEmpModal').modal({ backdrop:'static' }) }); //点击保存联系人 $("#saveEmp").click(function(){ //首先判断输入的参数是否满足规则 if(!validate_add_form()){ return false; } $.ajax({ url:"${APP_PATH}/save", data:$("#addEmpModal form").serialize(), type:"post", success:function(result){ //保存联系人成功需要做下面的几件事情 //第一件事情就是让新建联系人的对话框摸太框消失 $("#addEmpModal").modal('hide'); //第二个跳转到最后一页 //这里如何跳转到最后一页了,mybatis分页插件这里提供了一个功能,例如现在员工总数是100人,每页显示5人,最大的分页数目就是5,你如果输入6 //也是按照最大的5来进行查询。员工的总数肯定是大于最大的分页数目的,现在要查询最后一页的数据,我以员工的总数进行查询 //使用ajax重新再查询下最后一页员工的数目 // to_page(total); } }); }); //juqery前台校验数据 //校验表单数据 function validate_add_form(){ //1、拿到要校验的数据,使用正则表达式 var empName = $("#empNameModal").val(); var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[u2E80-u9FFF]{2,5})/; if(!regName.test(empName)){ //添加元素状态之前。先清空清除当前元素的校验状态 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").next("span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text("姓名格式不正确"); return false; }else{ $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").next("span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text(""); }; //2、校验邮箱信息 var email = $("#emailModal").val(); var regEmail = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/; if(!regEmail.test(email)){ $("#emailModal").parent().removeClass("has-success has-error"); $("#email_span").next("span").text(""); $("#emailModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#email_span").addClass("help-block").text("邮箱格式不正确"); return false; }else{ $("#emailModal").parent().removeClass("has-success has-error"); $("#email_span").next("span").text(""); $("#emailModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#email_span").addClass("help-block").text(""); } return true; } </script> </div> </body> </html>
25、尚硅谷_SSM高级整合_新增_Ajax校验用户名是否重复.avi
接下来实现下面的功能,当点击保存的时候校验当前的用户在后台数据库中是否已经存在了,要使用ajax功能
应该给员工姓名的输入框当输入的姓名发送改变的时候使用ajax校验当前用户名是否可用
,如果当前用户不可用,在对应的父节点和<span>节点中添加has-error属性和help-block提示当时用户已经存在,
第二:如果当前用户存在,点击保存按钮的时候,无法保存数据
第三:这里还需要一个主意点的是每次点击新增联系人,弹出新增联系人摸态框界面的时候,都已经将数据清空
这里可以将jquery对象转化成docment对象,调用docment对象的rese函数,不清楚的看锋利jquery教程
EmployeeController.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.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.atguigu.crud.bean.Employee; import com.atguigu.crud.bean.Msg; import com.atguigu.crud.dao.EmployeeMapper; import com.atguigu.crud.service.EmployeeService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; /** * * 处理员工的增删改查操作 * */ @Controller public class EmployeeController { @Autowired private EmployeeService employeeService; /** * 负责将PageInfo对象转化成json对象 * */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue ="1") Integer pn) { //使用mybatis分页插件 pn表示当前查询的页数,5表示每页显示第几条 System.out.println("EmployeeController is called pn"+pn); PageHelper.startPage(pn, 5); //在PageHelper.startPage(pn, 5);后面的查询语句就可以实现分页查询 List<Employee> list = employeeService.getAll(); //我们将查询的结果封装到PageInfo对象之中,5表示右下角导航栏的数目是5 PageInfo info = new PageInfo(list,5); Msg msg = new Msg(); msg.setCode(100); msg.setMsg("业务操作成功"); msg.getExtend().put("pageInfo", info); return msg; } /** * 这里一定要注意采用的resetful风格,请求方式必须是post * */ @RequestMapping(value="/save",method=RequestMethod.POST) @ResponseBody public Msg save(Employee employee){ System.out.println("save is calle:"+employee.toString()); Msg msg = new Msg(); employeeService.save(employee); msg.setCode(100); msg.setMsg("保存员工数据成功"); return msg; } @RequestMapping("/isUserExist") @ResponseBody public Msg isUserExist(@RequestParam("empName") String empName){ System.out.println("isUserExist is called:"+empName); Msg msg = new Msg(); Boolean exits = employeeService.isUserExist(empName); if(exits){ //200表示联系人已经存在 msg.setCode(200); }else{ //100表示联系人可用 msg.setCode(100); } return msg; } }
EmployeeService.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.Employee; import com.atguigu.crud.bean.EmployeeExample; import com.atguigu.crud.bean.EmployeeExample.Criteria; import com.atguigu.crud.dao.EmployeeMapper; @Service public class EmployeeService { @Autowired private EmployeeMapper employeeMapper; public List<Employee> getAll(){ List<Employee> list = employeeMapper.selectByExampleWithDept(null); return list; } public void save(Employee employee) { // TODO Auto-generated method stub //这里要注意insert和insertSelevite的区别,使用insert将会null字段插入到数据库中。insertselct不会 //现在要实现员工的id自增长,employee中的id字段传递过来的值是null字段,所以不能使用insert,会将null字段插入 employeeMapper.insertSelective(employee); } public Boolean isUserExist(String empName) { // TODO Auto-generated method stub //采用mybatis的高级查找功能,判断当前用户是否存在 /*** * MyBatis的Mapper接口以及Example的实例函数及详解 * mybatis的逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分 xxxExample example = new xxxExample(); Criteria criteria = new Example().createCriteria(); User user = XxxMapper.selectByPrimaryKey(100); //相当于select * from user where id = 100 * */ EmployeeExample example = new EmployeeExample(); Criteria createCriteria = example.createCriteria(); createCriteria.andEmpNameEqualTo(empName); long countByExample = employeeMapper.countByExample(example); if(countByExample > 0){ return true; }else{ return false; } } }
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> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <% pageContext.setAttribute("APP_PATH", request.getContextPath()); %> <!-- web路径: 不以/开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题。 以/开始的相对路径,找资源,以服务器的路径为标准(http://localhost:3306);需要加上项目名 http://localhost:3306/crud --> <script type="text/javascript" src="${APP_PATH}/static/js/jquery-2.1.1.js"></script> <link href="${APP_PATH }/static/bootstrap-3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="${APP_PATH}/static/bootstrap-3.3.7/dist/js/bootstrap.min.js"></script> </head> <body> <!-- 新增员工信息的对话框 --> <div class="modal fade" id="addEmpModal" 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">×</span></button> <h4 class="modal-title" id="myModalLabel">新增员工</h4> </div> <div class="modal-body"> <!-- 实体类的表单,表单项 的name需要给实体bean对象的一一对应起来,springmvc会帮我们自动封装--> <form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="empNameModal" placeholder="name"> <span id="name_span" class="help-block"></span> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="emailModal" placeholder="eamil"> <span id="email_span" class="help-block"></span> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="F"> 男 </label> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="M"> 女 </label> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">部门</label> <div class="col-sm-5"> <select name="dId" id="dIdModal"class="form-control"> </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 ="saveEmp">保存</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="addEmp">新增</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>deptName</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> <!-- 当页面加载完成之后发起ajax请求获得数据 ,不清楚的看锋利jquery教程相当的经典--> <script type="text/javascript"> //定义一个全局变量,获得当前中的记录数 var total; $(function(){ //页面加载完毕,去首页获得对应的数据 to_page(1); }); //使用ajax到后台服务器查询数据 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); //3、解析显示分页条数据 build_page_nav(result); } }); } //解析服务器返回的json数据,并在员工表中显示出来 function build_emps_table(result){ //在构建之前先清空所有的数据 $("#emps_table tbody").empty(); //第一步:获得所有的员工数据 var emps = result.extend.pageInfo.list; //第二步:对员工数据进行遍历显示出来 $.each(emps,function(index,item){ var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); var gender = item.gender == 'M'?"男":"女"; var genderTd = $("<td></td>").append(gender); var emailTd = $("<td></td>").append(item.email); var departmentNameTd = $("<td></td>").append(item.department.deptName); //添加编辑按钮 var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn") .append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //将上面的table表td数据添加到tr中,这里是一个链式操作 $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(departmentNameTd) .append(btnTd) .appendTo("#emps_table tbody"); //"#emps_table tbody"表示选取id为emps_table下的所有的<tbody>的元素,不清楚的看锋利的jquery书籍相当的经典 }); } //解析显示分页信息 function build_page_info(result){ $("#page_info_area").empty(); $("#page_info_area").append("当前第"+result.extend.pageInfo.pageNum+"页,"+"总共"+result.extend.pageInfo.pages+"页,"+"总共"+ result.extend.pageInfo.total+"条记录"); total = result.extend.pageInfo.total; } //解析右下角的导航栏 function build_page_nav(result){ //page_nav_area $("#page_nav_area").empty(); var ul = $("<ul></ul>").addClass("pagination"); //构建元素 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有前一页,如果没有前一页就不能点击 if(result.extend.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //给前一页和首页添加按钮点击事件 firstPageLi.click(function(){ to_page(1); }); prePageLi.click(function(){ //跳转到当前页的前一页 to_page(result.extend.pageInfo.pageNum-1); }); var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //如果没有下一页不能被点击 if(result.extend.pageInfo.hasNextPage == false){ nextPageLi.addClass("disabled"); lastPageLi.addClass("disabled"); } //给下一页和尾页添加点击事件 nextPageLi.click(function(){ to_page(result.extend.pageInfo.pageNum+1); }); lastPageLi.click(function(){ to_page(result.extend.pageInfo.pages); }); //添加首页和前一页 的提示 ul.append(firstPageLi).append(prePageLi); //1,2,3遍历给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(){ //点击的时候重新使用ajax到服务器查询数据 to_page(item); }); ul.append(numLi); }); //添加下一页和末页 的提示 ul.append(nextPageLi).append(lastPageLi); //把ul加入到nav var navEle = $("<nav></nav>").append(ul); navEle.appendTo("#page_nav_area"); } //点击新增按钮,弹出新增加员工的对话框 $("#addEmp").click(function(){ //首先清空页面的所有数据 //将jquery对象转化成docment对象,调用docment对象的reset方法 $("#addEmpModal form")[0].reset(); $("#name_span").text(""); $("#empNameModal").parent().removeClass("has-success has-error"); var parent = $("#dIdModal"); //使用ajax请求部门的数据 $.ajax( { url:"${APP_PATH}/depts", type:"GET", success:function(result){ //对result数据进行解析添加到 var depts = result.extend.depts; $.each(depts,function(index,item){ //给option选项设置值应该是deptid var opt = $("<option></option>").append(item.deptName).attr("value",item.deptId); parent.append(opt); }); } } ); $('#addEmpModal').modal({ backdrop:'static' }) }); //点击保存联系人 $("#saveEmp").click(function(){ //判断当前的联系人是否可用 if( $(this).attr("isUserExist")=="yes"){ return false; } //首先判断输入的参数是否满足规则 if(!validate_add_form()){ return false; } $.ajax({ url:"${APP_PATH}/save", data:$("#addEmpModal form").serialize(), type:"post", success:function(result){ //保存联系人成功需要做下面的几件事情 //第一件事情就是让新建联系人的对话框摸太框消失 $("#addEmpModal").modal('hide'); //第二个跳转到最后一页 //这里如何跳转到最后一页了,mybatis分页插件这里提供了一个功能,例如现在员工总数是100人,每页显示5人,最大的分页数目就是5,你如果输入6 //也是按照最大的5来进行查询。员工的总数肯定是大于最大的分页数目的,现在要查询最后一页的数据,我以员工的总数进行查询 //使用ajax重新再查询下最后一页员工的数目 // to_page(total); } }); }); //juqery前台校验数据 //校验表单数据 function validate_add_form(){ //1、拿到要校验的数据,使用正则表达式 var empName = $("#empNameModal").val(); var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[u2E80-u9FFF]{2,5})/; if(!regName.test(empName)){ //添加元素状态之前。先清空清除当前元素的校验状态 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text("姓名格式不正确"); return false; }else{ $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text(""); }; //2、校验邮箱信息 var email = $("#emailModal").val(); var regEmail = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/; if(!regEmail.test(email)){ $("#emailModal").parent().removeClass("has-success has-error"); $("#email_span").text(""); $("#emailModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#email_span").addClass("help-block").text("邮箱格式不正确"); return false; }else{ $("#emailModal").parent().removeClass("has-success has-error"); $("#email_span").text(""); $("#emailModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#email_span").addClass("help-block").text(""); } return true; } //给输入联系人的input添加change事件,判断当前联系人是否可用 $("#empNameModal").change(function(){ //this表示当前操作的对象,是docment类型 //获得当前输入的name的值 var name=$(this).val(); $.ajax({ url:"${APP_PATH}/isUserExist", type:"post", data:"empName="+name, success:function(result){ if(result.code == 200){ //说明该联系人已经在后台存在不可以 //添加元素状态之前。先清空清除当前元素的校验状态 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text("该联系人已经存在"); //如果当前联系人已经存在,点击保存联系人案例的时候,就会失败,我们给保存联系人的按钮添加一个自定义属性用来标识当前添加的联系人是否存在 $("#saveEmp").attr("isUserExist","yes"); }else{ //说明该联系人可用 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text("该联系人可用"); $("#saveEmp").attr("isUserExist","no"); } } }); }); </script> </div> </body> </html>
整个工程的目录结构为:
27、尚硅谷_SSM高级整合_新增_JSR303校验.avi
对于前段的任何校验,用户都可以绕过前端的校验,例如浏览器去掉校验的js,对于关键的数据,为了保证安全性都必须在后端进行校验,用户都可以绕过给后台发送非法数据,重要的数据为了保证安全性,都必须进行后端校验。
接下来我们在后端我们可以使用jrs303校验
使用jrs303数据校验,需要导入下面的jar
<!--JSR303数据校验支持;tomcat7及以上的服务器,
tomcat7以下的服务器:el表达式。额外给服务器的lib包中替换新的标准的el
-->
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency>
我们要使用jrs3030校验,自己在我们需要校验的javabean字段上面进行
@NotNull
@Size(min = 5,max = 10,message = "用户名长度5到10")
private String username;
@NotNull
@Size(min = 5,max = 10,message = "密码长度5到10")
private String password;
我们这里使用的是自定义的正则表达式,如下形式
package com.atguigu.crud.bean; import javax.validation.constraints.Pattern; public class Employee { private Integer empId; @Pattern(regexp="(^[a-zA-Z0-9_-]{6,16}$)|(^[u2E80-\u9FFF]{2,5})",message="用户名必须是2-6位中文或者6-16位的数字和英文的组合") private String empName; private String gender; @Pattern(regexp="^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$",message="邮箱格式不正确") private String email; private Integer dId; //希望查询员工的同时部门信息也是查询好的 private Department department; public Employee() { super(); } public Employee(Integer empId, String empName, String gender, String email, Integer dId) { super(); this.empId = empId; this.empName = empName; this.gender = gender; this.email = email; this.dId = dId; } public Department getDepartment() { return department; } public void setDepartment(Department department) { this.department = department; } public Integer getEmpId() { return empId; } public void setEmpId(Integer empId) { this.empId = empId; } public String getEmpName() { return empName; } public void setEmpName(String empName) { this.empName = empName == null ? null : empName.trim(); } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender == null ? null : gender.trim(); } public String getEmail() { return email; } public void setEmail(String email) { this.email = email == null ? null : email.trim(); } public Integer getdId() { return dId; } public void setdId(Integer dId) { this.dId = dId; } @Override public String toString() { return "Employee [empId=" + empId + ", empName=" + empName + ", gender=" + gender + ", email=" + email + ", dId=" + dId + ", department=" + department + "]"; } }
这里有两个地方需要注意的:为了保证前端和后端校验规则尽量保证一致性,我们要使用相同的校验规则,但是在使用的时候要小心一点
对于jsp:校验规则是
var regEmail = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/;
在java代码使用的时候,必须把前后的/去掉,第二点是校验规则中使用到的\,在java代码中使用\代替,否则会出现问题
regexp="^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$"
然后再控制端如何使用校验了,值需要在控制器端需要使用的方法中使用@valid和BindingResult就可以了
我们来看下代码:
EmployeeController.java
package com.atguigu.crud.controller; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.atguigu.crud.bean.Employee; import com.atguigu.crud.bean.Msg; import com.atguigu.crud.dao.EmployeeMapper; import com.atguigu.crud.service.EmployeeService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; /** * * 处理员工的增删改查操作 * */ @Controller public class EmployeeController { @Autowired private EmployeeService employeeService; /** * 负责将PageInfo对象转化成json对象 * */ @RequestMapping("/emps") @ResponseBody public Msg getEmpsWithJson(@RequestParam(value="pn",defaultValue ="1") Integer pn) { //使用mybatis分页插件 pn表示当前查询的页数,5表示每页显示第几条 System.out.println("EmployeeController is called pn"+pn); PageHelper.startPage(pn, 5); //在PageHelper.startPage(pn, 5);后面的查询语句就可以实现分页查询 List<Employee> list = employeeService.getAll(); //我们将查询的结果封装到PageInfo对象之中,5表示右下角导航栏的数目是5 PageInfo info = new PageInfo(list,5); Msg msg = new Msg(); msg.setCode(100); msg.setMsg("业务操作成功"); msg.getExtend().put("pageInfo", info); return msg; } /** * 这里一定要注意采用的resetful风格,请求方式必须是post * */ @RequestMapping(value="/save",method=RequestMethod.POST) @ResponseBody public Msg save(@Valid Employee employee,BindingResult result){ System.out.println("save is calle:"+employee.toString()); //这里首先要判断用户输入的参数是否合法 Map<String,Object> err_map = new HashMap<String, Object>(); Msg msg = new Msg(); if(result.hasErrors()){ List<FieldError> errors = result.getFieldErrors(); for( FieldError error: errors){ System.out.println("错误的字段是:"+error.getField()); System.out.println("错误的消息是:"+error.getDefaultMessage()); err_map.put(error.getField(), error.getDefaultMessage()); } msg.setCode(200); msg.setMsg("员工保存失败"); msg.getExtend().put("err_map", err_map); }else{ employeeService.save(employee); msg.setCode(100); msg.setMsg("保存员工数据成功"); } return msg; } @RequestMapping("/isUserExist") @ResponseBody public Msg isUserExist(@RequestParam("empName") String empName){ System.out.println("isUserExist is called:"+empName); Msg msg = new Msg(); Boolean exits = employeeService.isUserExist(empName); if(exits){ //200表示联系人已经存在 msg.setCode(200); }else{ //100表示联系人可用 msg.setCode(100); } return msg; } }
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> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <% pageContext.setAttribute("APP_PATH", request.getContextPath()); %> <!-- web路径: 不以/开始的相对路径,找资源,以当前资源的路径为基准,经常容易出问题。 以/开始的相对路径,找资源,以服务器的路径为标准(http://localhost:3306);需要加上项目名 http://localhost:3306/crud --> <script type="text/javascript" src="${APP_PATH}/static/js/jquery-2.1.1.js"></script> <link href="${APP_PATH }/static/bootstrap-3.3.7/dist/css/bootstrap.min.css" rel="stylesheet"> <script src="${APP_PATH}/static/bootstrap-3.3.7/dist/js/bootstrap.min.js"></script> </head> <body> <!-- 新增员工信息的对话框 --> <div class="modal fade" id="addEmpModal" 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">×</span></button> <h4 class="modal-title" id="myModalLabel">新增员工</h4> </div> <div class="modal-body"> <!-- 实体类的表单,表单项 的name需要给实体bean对象的一一对应起来,springmvc会帮我们自动封装--> <form class="form-horizontal"> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">姓名</label> <div class="col-sm-10"> <input type="text" name="empName" class="form-control" id="empNameModal" placeholder="name"> <span id="name_span" class="help-block"></span> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">邮箱</label> <div class="col-sm-10"> <input type="text" name="email" class="form-control" id="emailModal" placeholder="eamil"> <span id="email_span" class="help-block"></span> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">性别</label> <div class="col-sm-10"> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="F"> 男 </label> <label class="radio-inline"> <input type="radio" name="gender" id="genderModal" value="M"> 女 </label> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">部门</label> <div class="col-sm-5"> <select name="dId" id="dIdModal"class="form-control"> </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 ="saveEmp">保存</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="addEmp">新增</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>deptName</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> <!-- 当页面加载完成之后发起ajax请求获得数据 ,不清楚的看锋利jquery教程相当的经典--> <script type="text/javascript"> //定义一个全局变量,获得当前中的记录数 var total; $(function(){ //页面加载完毕,去首页获得对应的数据 to_page(1); }); //使用ajax到后台服务器查询数据 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); //3、解析显示分页条数据 build_page_nav(result); } }); } //解析服务器返回的json数据,并在员工表中显示出来 function build_emps_table(result){ //在构建之前先清空所有的数据 $("#emps_table tbody").empty(); //第一步:获得所有的员工数据 var emps = result.extend.pageInfo.list; //第二步:对员工数据进行遍历显示出来 $.each(emps,function(index,item){ var empIdTd = $("<td></td>").append(item.empId); var empNameTd = $("<td></td>").append(item.empName); var gender = item.gender == 'M'?"男":"女"; var genderTd = $("<td></td>").append(gender); var emailTd = $("<td></td>").append(item.email); var departmentNameTd = $("<td></td>").append(item.department.deptName); //添加编辑按钮 var editBtn = $("<button></button>").addClass("btn btn-primary btn-sm edit_btn") .append($("<span></span>").addClass("glyphicon glyphicon-pencil")).append("编辑"); var delBtn = $("<button></button>").addClass("btn btn-danger btn-sm delete_btn") .append($("<span></span>").addClass("glyphicon glyphicon-trash")).append("删除"); var btnTd = $("<td></td>").append(editBtn).append(" ").append(delBtn); //将上面的table表td数据添加到tr中,这里是一个链式操作 $("<tr></tr>").append(empIdTd) .append(empNameTd) .append(genderTd) .append(emailTd) .append(departmentNameTd) .append(btnTd) .appendTo("#emps_table tbody"); //"#emps_table tbody"表示选取id为emps_table下的所有的<tbody>的元素,不清楚的看锋利的jquery书籍相当的经典 }); } //解析显示分页信息 function build_page_info(result){ $("#page_info_area").empty(); $("#page_info_area").append("当前第"+result.extend.pageInfo.pageNum+"页,"+"总共"+result.extend.pageInfo.pages+"页,"+"总共"+ result.extend.pageInfo.total+"条记录"); total = result.extend.pageInfo.total; } //解析右下角的导航栏 function build_page_nav(result){ //page_nav_area $("#page_nav_area").empty(); var ul = $("<ul></ul>").addClass("pagination"); //构建元素 var firstPageLi = $("<li></li>").append($("<a></a>").append("首页").attr("href","#")); var prePageLi = $("<li></li>").append($("<a></a>").append("«")); //判断是否有前一页,如果没有前一页就不能点击 if(result.extend.pageInfo.hasPreviousPage == false){ firstPageLi.addClass("disabled"); prePageLi.addClass("disabled"); } //给前一页和首页添加按钮点击事件 firstPageLi.click(function(){ to_page(1); }); prePageLi.click(function(){ //跳转到当前页的前一页 to_page(result.extend.pageInfo.pageNum-1); }); var nextPageLi = $("<li></li>").append($("<a></a>").append("»")); var lastPageLi = $("<li></li>").append($("<a></a>").append("末页").attr("href","#")); //如果没有下一页不能被点击 if(result.extend.pageInfo.hasNextPage == false){ nextPageLi.addClass("disabled"); lastPageLi.addClass("disabled"); } //给下一页和尾页添加点击事件 nextPageLi.click(function(){ to_page(result.extend.pageInfo.pageNum+1); }); lastPageLi.click(function(){ to_page(result.extend.pageInfo.pages); }); //添加首页和前一页 的提示 ul.append(firstPageLi).append(prePageLi); //1,2,3遍历给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(){ //点击的时候重新使用ajax到服务器查询数据 to_page(item); }); ul.append(numLi); }); //添加下一页和末页 的提示 ul.append(nextPageLi).append(lastPageLi); //把ul加入到nav var navEle = $("<nav></nav>").append(ul); navEle.appendTo("#page_nav_area"); } //点击新增按钮,弹出新增加员工的对话框 $("#addEmp").click(function(){ //首先清空页面的所有数据 //将jquery对象转化成docment对象,调用docment对象的reset方法 $("#addEmpModal form")[0].reset(); $("#name_span").text(""); $("#empNameModal").parent().removeClass("has-success has-error"); var parent = $("#dIdModal"); //使用ajax请求部门的数据 $.ajax( { url:"${APP_PATH}/depts", type:"GET", success:function(result){ //对result数据进行解析添加到 var depts = result.extend.depts; $.each(depts,function(index,item){ //给option选项设置值应该是deptid var opt = $("<option></option>").append(item.deptName).attr("value",item.deptId); parent.append(opt); }); } } ); $('#addEmpModal').modal({ backdrop:'static' }) }); //点击保存联系人 $("#saveEmp").click(function(){ //判断当前的联系人是否可用 if( $(this).attr("isUserExist")=="yes"){ return false; } //首先判断输入的参数是否满足规则 if(!validate_add_form()){ return false; } $.ajax({ url:"${APP_PATH}/save", data:$("#addEmpModal form").serialize(), type:"post", success:function(result){ //首先需要判断后端返回的结果中,后端对用户的校验结果 //alert(result.extend.err_map.email); //alert(result.extend.err_map.empName); //这里需要注意的是如果邮箱格式错误,姓名正确,result.extend.err_map.email中就像携带错误的信息,result.extend.err_map.empName的信息是undefined if(result.code == 100){ //保存联系人成功需要做下面的几件事情 //第一件事情就是让新建联系人的对话框摸太框消失 $("#addEmpModal").modal('hide'); //第二个跳转到最后一页 //这里如何跳转到最后一页了,mybatis分页插件这里提供了一个功能,例如现在员工总数是100人,每页显示5人,最大的分页数目就是5,你如果输入6 //也是按照最大的5来进行查询。员工的总数肯定是大于最大的分页数目的,现在要查询最后一页的数据,我以员工的总数进行查询 //使用ajax重新再查询下最后一页员工的数目 // to_page(total); }else{ alert(result.extend.err_map.email); //说明邮箱格式错误 if(undefined != result.extend.err_map.email){ alert(result.extend.err_map.email); $("#emailModal").parent().removeClass("has-success has-error"); $("#email_span").text(""); $("#emailModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#email_span").addClass("help-block").text(result.extend.err_map.email); } //说明姓名格式有错误 if(undefined != result.extend.err_map.empName){ //添加元素状态之前。先清空清除当前元素的校验状态 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text(result.extend.err_map.empName); } } } }); }); //juqery前台校验数据 //校验表单数据 function validate_add_form(){ //1、拿到要校验的数据,使用正则表达式 var empName = $("#empNameModal").val(); var regName = /(^[a-zA-Z0-9_-]{6,16}$)|(^[u2E80-u9FFF]{2,5})/; if(!regName.test(empName)){ //添加元素状态之前。先清空清除当前元素的校验状态 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text("姓名格式不正确"); return false; }else{ $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text(""); }; //2、校验邮箱信息 var email = $("#emailModal").val(); var regEmail = /^([a-z0-9_.-]+)@([da-z.-]+).([a-z.]{2,6})$/; if(!regEmail.test(email)){ $("#emailModal").parent().removeClass("has-success has-error"); $("#email_span").text(""); $("#emailModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#email_span").addClass("help-block").text("邮箱格式不正确"); return false; }else{ $("#emailModal").parent().removeClass("has-success has-error"); $("#email_span").text(""); $("#emailModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#email_span").addClass("help-block").text(""); } return true; } //给输入联系人的input添加change事件,判断当前联系人是否可用 $("#empNameModal").change(function(){ //this表示当前操作的对象,是docment类型 //获得当前输入的name的值 var name=$(this).val(); $.ajax({ url:"${APP_PATH}/isUserExist", type:"post", data:"empName="+name, success:function(result){ if(result.code == 200){ //说明该联系人已经在后台存在不可以 //添加元素状态之前。先清空清除当前元素的校验状态 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-error"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text("该联系人已经存在"); //如果当前联系人已经存在,点击保存联系人案例的时候,就会失败,我们给保存联系人的按钮添加一个自定义属性用来标识当前添加的联系人是否存在 $("#saveEmp").attr("isUserExist","yes"); }else{ //说明该联系人可用 $("#empNameModal").parent().removeClass("has-success has-error"); $("#name_span").text(""); //给当前节点的父元素添加has-error属性 $("#empNameModal").parent().addClass("has-success"); //给span节点添加.help-block属性 $("#name_span").addClass("help-block").text("该联系人可用"); $("#saveEmp").attr("isUserExist","no"); } } }); }); </script> </div> </body> </html>
spring_mvc的配置文件为
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> <!-- 配置扫描控制器 ,springmvc值扫描controler,其他的对象都让spring去管理,这里use-default-filters="false"要设置成false--> <context:component-scan base-package="com.atguigu" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 配置视图解析器 --> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 配置视图解析器的前缀和后缀 --> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 配置允许访问静态资源文件 --> <mvc:default-servlet-handler/> <!-- 支持springmvc的更加高级的东西 --> <mvc:annotation-driven></mvc:annotation-driven> </beans>
这样需要注意一点的是:在tomcat服务器上运行的时候,jrs3030不支持tomact7以下的版本
我们发布的时候要选择tomact7,否则你跑的时候发现验证功能没有效果
整个项目代码的下载地址为
链接:https://pan.baidu.com/s/13ny24LsK1UBASgduHo4uBQ 密码:pj2o