超详细的JavaWeb用户的增删改查实现总结

开发 后端
本文是基于单体架构实现的角色的增删改查的功能。前台使用Bootstrap+Ajax+Jsp , 后端使Spring+SpringMvc+MyBatis进行开发,相信使用过这些技术的小伙伴应该很好的理解以下的内容。

前言

本文是基于单体架构实现的角色的增删改查的功能。前台使用Bootstrap+Ajax+Jsp , 后端使用Spring+SpringMvc+MyBatis进行开发,相信使用过这些技术的小伙伴应该很好的理解以下的内容,也希望看了这篇文章小伙伴们有所收获。

准备工作

后端技术

前端技术

角色维护-分页实现

分页前端功能实现

创建外部JavaScript源文件,role.js

在页面 role-page.jsp引入role.js文件 

  1. <script type="text/javascript" src="script/my-role.js"></script> 

初始化全局函数

分页实现初始化全局函数,每页的条数,页码,模糊查询的关键词 

  1. //初始化全局变量  
  2. function initGlobalVariable() {  
  3.     window.pageSize = 5; //每页的条数  
  4.     window.pageNum = 1;  //页码  
  5.     window.keyword = ""; //关键词  
  6.  

声明分页函数 

  1. //给服务器发送请求获取分页数据(pageInfo),并在页面上显示分页效果(主体、页码导航条)  
  2. function showPage() {  
  3.     // 给服务器发送请求获取分页数据:PageInfo  
  4.     var pageInfo = getPageInfo();  
  5.     // 在页面上的表格中tbody标签内显示分页的主体数据  
  6.     generateTableBody(pageInfo);  
  7.     // 在页面上的表格中tfoot标签内显示分页的页码导航条  
  8.     initPagination(pageInfo); 
  9.   

获取分页数据 

  1. function getPageInfo() {  
  2.     // 以同步请求方式调用$.ajax()函数并获取返回值(返回值包含全部响应数据)  
  3.     var ajaxResult = $.ajax({  
  4.         "url": "role/search/by/keyword.action",  
  5.         "type": "post",  
  6.         "data": {  
  7.             "pageNum": (window.pageNum == undefined) ? 1 : window.pageNum,  
  8.             "pageSize": (window.pageSize == undefined) ? 5 : window.pageSize,  
  9.             "keyword": (window.keyword == undefined) ? "" : window.keyword  
  10.         },  
  11.         "dataType": "json",  
  12.         "async": false    // 为了保证getPageInfo()函数能够在Ajax请求拿到响应后获取PageInfo,需要设置为同步操作  
  13.     });   
  14.     // 从全部响应数据中获取JSON格式的响应体数据  
  15.     var resultEntity = ajaxResult.responseJSON;  
  16.     // 从响应体数据中获取result,判断当前请求是否成功  
  17.     var result = resultEntity.result;  
  18.     // 如果成功获取PageInfo  
  19.     if (result == "SUCCESS") {  
  20.         return resultEntity.data;  
  21.     }  
  22.     if (result == "FAILED") {  
  23.         layer.msg(resultEntity.message);  
  24.     }  
  25.     return null;  
  26.  

使用PageInfo数据在tbody标签内显示分页数据 

  1. function generateTableBody(pageInfo) {  
  2.     // 执行所有操作前先清空  
  3.     $("#roleTableBody").empty();   //这个对应页面的 <tbody id="roleTableBody"> </tbody>  
  4.     // 获取数据集合  
  5.     var list = pageInfo.list;  
  6.     // 判断list是否有效  
  7.     if (list == null || list.length == 0) {  
  8.         $("#roleTableBody").append("<tr><td colspan='4' style='text-align:center;'>没有查询到数据!</td></tr>");  
  9.         return;  
  10.     }  
  11.     for (var i = 0; i < list.length; i++) {  
  12.         var role = list[i];  
  13.         var checkBtn = "<button type='button' class='btn btn-success btn-xs'><i class=' glyphicon glyphicon-check'></i></button>" 
  14.         var pencilBtn = "<button type='button' id='roleTableBody'  roleid='" + role.id + "' class='btn btn-primary btn-xs  editBtn'><i class=' glyphicon glyphicon-pencil'></i></button>"; 
  15.         var removeBtn = "<button type='button'   roleid='" + role.id + "'  class='btn btn-danger btn-xs  removeBtn'><i class=' glyphicon glyphicon-remove'></i></button>"; 
  16.         var numberTd = "<td>" + (i + 1) + "</td>";  
  17.         var checkBoxTd = "<td><input class='itemBox' roleid='" + role.id + "' type='checkbox'></td>";  
  18.         var roleNameTd = "<td>" + role.name + "</td>";  
  19.         var btnTd = "<td>" + checkBtn + " " + pencilBtn + " " + removeBtn + "</td>";  
  20.         var tr = "<tr>" + numberTd + checkBoxTd + roleNameTd + btnTd + "</tr>";  
  21.         // 将前面拼好的HTML代码追加到#roleTableBody中  
  22.         $("#roleTableBody").append(tr);  
  23.     }  

 声明函数封装导航条初始化操作 

  1. function initPagination(pageInfo) {  
  2.     // 声明变量存储分页导航条显示时的属性设置  
  3.     var paginationProperties = {  
  4.         num_edge_entries: 3,            //边缘页数  
  5.         num_display_entries: 5,        //主体页数  
  6.         callback: pageselectCallback,    //回调函数  
  7.         items_per_page: window.pageSize,    //每页显示数据数量,就是pageSize  
  8.         current_page: (window.pageNum - 1),//当前页页码  
  9.         prev_text: "上一页",            //上一页文本 
  10.          next_text: "下一页"            //下一页文本  
  11.     };  
  12.     // 显示分页导航条 <div id="Pagination" class="pagination"> <!-- 这里显示分页 --> </div>  
  13.     $("#Pagination").pagination(pageInfo.total, paginationProperties);  
  14.  

在每一次点击“上一页”、“下一页”、“页码”时执行这个函数跳转页面 

  1. function pageselectCallback(pageIndex, jq) {  
  2.     // 将全局变量中的pageNum修改为最新值  
  3.     // pageIndex从0开始,pageNum从1开始  
  4.     window.pageNum = pageIndex + 1;  
  5.     // 调用分页函数重新执行分页  
  6.     showPage();  
  7.     return false; 
  8.   

页面初始化,就是我们点击角色维护页面需要加载的内容 

  1. $(function(){      
  2.     // 调用分页参数初始化方法  
  3.     initGlobalVariable();  
  4.     // 执行分页  
  5.     showPage(); 
  6.  });  

关键词查询功能

在点击“查询”按钮后,获取文本框中填写的keyword值,赋值给全局变量keyword,调用showPage()函数即可。 

  1. //关键字查询实现  
  2.         $("#searchBtn").click(function () {  
  3.             //获取关键字查询的值  
  4.             var keywordInput = $.trim($("#keywordInput").val());  
  5.             /*if (keywordInput==null || keywordInput==""){  
  6.                 layer.msg("请输入关键词");  
  7.                 return;  
  8.             }*/  
  9.             window.keyword = keywordInput 
  10.             //执行查询操作  
  11.             showPage();  
  12.         });  

分页后端实现

点击角色维护加载页面数据两种思路:

第一种是我们请求后台把查询到的数据放到Model,前台遍历把数据展示出来。

第二种是我们请求后台把查询到的数据当PageInfo<Role>,然后动态的拼接把数据展示到页面上。(我们采用第二种)

Controller方法的实现 

  1. @ResponseBody  
  2.     @RequestMapping("/role/search/by/keyword")  
  3.     public ResultEntity<PageInfo<Role>> search(  
  4.             @RequestParam(value = "pageNum"defaultValue = "1") Integer pageNum,  
  5.             @RequestParam(value = "pageSize"defaultValue = "5") Integer pageSize,  
  6.             @RequestParam(value = "keyword"defaultValue = "") String keyword) {  
  7.         // 1.查询得到PageInfo对象  
  8.         PageInfo<Role> pageInfo = roleService.queryForKeywordWithPage(pageNum, pageSize, keyword);  
  9.         // 2.封装结果对象返回  
  10.         return ResultEntity.successWithData(pageInfo);  
  11.     }  

Service方法的实现 

  1. public PageInfo<Role> queryForKeywordWithPage(Integer pageNum, Integer pageSize, String keyword) {  
  2.         // 1.开启分页功能  
  3.         PageHelper.startPage(pageNum, pageSize); 
  4.         // 2.执行查询  
  5.         List<Role> list = roleMapper.selectForKeywordSearch(keyword);  
  6.         // 3.封装为PageInfo对象  
  7.         return new PageInfo<Role>(list);  
  8.     }  

Mapper方法的实现 

  1. List<Role> selectForKeywordSearch(String keyword); 

Mapper.xml 

  1. <select id="selectForKeywordSearch" resultMap="BaseResultMap">  
  2.         SELECT  
  3.             id,  
  4.             `name` 
  5.          FROM  
  6.             t_role  
  7.         WHERE  
  8.             `name` LIKE CONCAT('%', #{keyword}, '%')  
  9. </select>  

角色维护-全选功能

功能在页面的位置

具体实现

标记

role-page.jsp 

  1. <thead>  
  2.     <tr>  
  3.         <th width="30">#</th>  
  4.         <th width="30"><input id="summaryBox" type="checkbox"></th>  
  5.         <th>名称</th>  
  6.         <th width="100">操作</th>  
  7.     </tr>  
  8. </thead>  

my-role.js 

  1. for (var i = 0; i < list.length; i++) {  
  2.         //省略  
  3.         var checkBoxTd = "<td><input class='itemBox' roleid='" + role.id + "' type='checkbox'></td>";  
  4.        //省略  
  5.  

给summaryBox绑定单击响应函数 

  1. //全选/全不选功能实现  
  2.  $("#summaryBox").click(function () {  
  3.             //获取当前的选中状态  
  4.             var currentStatus = this.checked;  
  5.             $(".itemBox").prop("checked", currentStatus);  
  6.  });  

角色维护-批量删除

准备模态框

先准备模态框的HTML标签,include-modal-role-confirm.jsp 

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.          pageEncoding="UTF-8"%>  
  3. <div id="confirmModal" class="modal fade" tabindex="-1" role="dialog">  
  4.     <div class="modal-dialog" role="document">  
  5.         <div class="modal-content">  
  6.             <div class="modal-header">  
  7.                 <button type="button" class="close" data-dismiss="modal"  
  8.                         aria-label="Close">  
  9.                     <span aria-hidden="true">&times;</span>  
  10.                 </button>  
  11.                 <h4 class="modal-title">角色维护删除</h4>  
  12.             </div>  
  13.             <div class="modal-body">  
  14.                 <p>您确定要删除下面的显示的内容吗?</p>  
  15.                 <table class="table table-bordered">  
  16.                     <thead>  
  17.                     <tr>  
  18.                         <th width="30">#</th>  
  19.                         <th>名称</th>  
  20.                     </tr>  
  21.                     </thead>  
  22.                     <tbody id="confirmModalTableBody"></tbody>  
  23.                 </table>  
  24.             </div>  
  25.             <div class="modal-footer">  
  26.                 <button id="confirmModalBtn" type="button" class="btn btn-primary">OK</button>  
  27.             </div>  
  28.         </div>  
  29.     </div>  
  30. </div>  

在role-page.jsp中包含include-modal-role-confirm.jsp文件, <%@ include file="/WEB-INF/include-modal-role-confirm.jsp" %>

getRoleListByRoleIdArray()函数 

  1. //id查询角色信息  
  2. function getRoleListByRoleIdArray(roleIdArray) {  
  3.     //roleIdArray转换成JSON字符串  
  4.     var roleIds = JSON.stringify(roleIdArray);  
  5.     var ajaxResult = $.ajax({  
  6.         "url": "role/get/list/by/id/list.action",  
  7.         "type": "post",  
  8.         "data": roleIds,  
  9.         "contentType": "application/json;charset=UTF-8",  
  10.         "dataType": "json",  
  11.         "async": false  
  12.     });  
  13.     // 3.获取JSON对象类型的响应体  
  14.     var resultEntity = ajaxResult.responseJSON;  
  15.     var result = resultEntity.result;  
  16.     if (result == "SUCCESS") {  
  17.         // 5.如果成功,则返回roleList  
  18.         return resultEntity.data;  
  19.     }  
  20.     if (result == "FAILED") {  
  21.         layer.msg(resultEntity.message);  
  22.         return null;  
  23.     }  
  24.     return null;  
  25.  

对应的后端代码: 

  1. @ResponseBody  
  2.    @RequestMapping("role/get/list/by/id/list")  
  3.    public ResultEntity<List<Role>> getRoleListByIdList(@RequestBody List<Integer> roleIds) {  
  4.        List<Role> roleList = roleService.findRoleListByIdList(roleIds);  
  5.        return ResultEntity.successWithData(roleList);  
  6.  
  1. public List<Role> findRoleListByIdList(List<Integer> roleIds) {  
  2.         return roleMapper.findRoleListByIdList(roleIds);  
  3.     }  

showRemoveConfirmModal()函数 

  1. // 打开删除确认模态框  
  2. function showRemoveConfirmModal() {  
  3.     // 1.将模态框显示出来 
  4.     $("#confirmModal").modal("show");  
  5.     //获取角色数据  
  6.     var roleList = getRoleListByRoleIdArray(window.roleIdArray);  
  7.     //清空表格数据  
  8.     $("#confirmModalTableBody").empty();  
  9.     //填充confirmModalTableBody的数据  
  10.     for (var i = 0; i < roleList.length; i++) {  
  11.         // 5.获取角色相关数据  
  12.         var role = roleList[i];  
  13.         var id = role.id;  
  14.         var name = role.name;  
  15.         var trHTML = "<tr><td>" + (i+1) + "</td><td>" + name + "</td></tr>";  
  16.         // 6.执行填充  
  17.         $("#confirmModalTableBody").append(trHTML);  
  18.     }  
  19.  

点击批量删除按钮绑定单击响应函数

标记批量删除按钮 

  1. <button type="button" class="btn btn-danger" id="batchRemoveBtn"  
  2.                             style="float: right; margin-left: 10px;">  
  3.                         <i class=" glyphicon glyphicon-remove"></i> 删除  
  4.  </button>  

检查itemBox是否被选中 

  1. // 给批量删除按钮绑定单击响应函数  
  2.         $("#batchRemoveBtn").click(function () {  
  3.             //获取被选中的itemBox数组长度  
  4.             var length = $(".itemBox:checked").length;  
  5.             if (length == 0) {  
  6.                 layer.msg("请选择要删除的记录!!");  
  7.                 return;  
  8.             }  
  9.            // 未完待续...  
  10.         });  

在弹出的模态框中显示confirm信息

 

  1. // 给批量删除按钮绑定单击响应函数  
  2.        $("#batchRemoveBtn").click(function () {  
  3.            //获取被选中的itemBox数组长度  
  4.            var length = $(".itemBox:checked").length;  
  5.            if (length == 0) {  
  6.                layer.msg("请选择要删除的记录!!");  
  7.                return;  
  8.            }  
  9.            window.roleIdArray = new Array();  
  10.            //遍历复选框  
  11.            $(".itemBox:checked").each(function () {  
  12.                //通过checkbox的roleid属性获取roleId值  
  13.                var roleId = $(this).attr("roleid");  
  14.                //存入数组  
  15.                window.roleIdArray.push(roleId);  
  16.            });  
  17.            // 调用函数打开模态框  
  18.            showRemoveConfirmModal();  
  19.        });  

点击模态框的OK按钮执行删除

标记OK按 

  1. <button **id="confirmModalBtn"** type="button" class="btn btn-primary">OK</button> 

绑定单击响应函数 

  1. $("#confirmModalBtn").click(function () {  
  2.             //数组转成Json 
  3.              var roleIds = JSON.stringify(window.roleIdArray);  
  4.             var ajaxResult = $.ajax({  
  5.                 "url": "role/batch/remove.action",  
  6.                 "type": "post",  
  7.                 "data": roleIds,  
  8.                 "contentType": "application/json;charset=UTF-8",  
  9.                 "dataType": "json",  
  10.                 "async": false,  
  11.                 "success": function (response) {  
  12.                     var result = response.result;  
  13.                     if (result == "SUCCESS") {  
  14.                         layer.msg("操作成功!");  
  15.                         // 如果删除成功,则重新调用分页方法  
  16.                         showPage();  
  17.                     }  
  18.                     if (result == "FAILED") {  
  19.                         layer.msg(response.message);  
  20.                     }  
  21.                     // 不管成功还是失败,都需要关掉模态框  
  22.                     $("#confirmModal").modal("hide");  
  23.                 },  
  24.                 "error": function (response) {  
  25.                     if (result == "FAILED") {  
  26.                         layer.msg(response.message);  
  27.                     }  
  28.                 }  
  29.             });  
  30.         });   

后端代码 

  1. @ResponseBody  
  2.    @RequestMapping(value = "role/batch/remove" 
  3.    public ResultEntity<String> batchAdminList(@RequestBody List<Integer> roleIds) {  
  4.        try {  
  5.            roleService.batchRoleList(roleIds);  
  6.            return ResultEntity.successWithoutData();  
  7.        } catch (Exception e) {  
  8.            return ResultEntity.failed(null, e.getMessage());  
  9.        }  
  10.    }  
  1. public void batchRoleList(List<Integer> roleIds) {  
  2.         roleMapper.batchRoleList(roleIds);  
  3.     }  
  1. <delete id="batchRoleList" parameterType="java.util.List">  
  2.         delete from  t_role where id in  
  3.         <foreach collection="list" item="item" open="(" separator="," close=")" >  
  4.            #{item}  
  5.         </foreach> 
  6.  </delete>  

角色维护-新增

大体步骤

  • 给“新增”按钮绑定单击响应函数
  • 打开模态框
  • 给“保存”按钮绑定单击响应函数
  • 收集文本框内容
  • 发送请求
  • 请求处理完成关闭模态框、重新分页、清理表单

给新增按钮绑定单击响应函数

标记新增按钮 

  1. <button type="button" class="btn btn-primary" id="addBtn"  
  2.                            style="float: right;">  
  3.                        <i class="glyphicon glyphicon-plus"></i> 新增  
  4. </button>  

绑定单击响应函数 

  1. $("#addBtn").click(function(){ alert("aaa..."); }); 

准备模态框

先准备模态框的HTML代码,include-modal-role-add.jsp 

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.          pageEncoding="UTF-8"%>  
  3. <div id="addModal" class="modal fade" tabindex="-1" role="dialog">  
  4.     <div class="modal-dialog" role="document">  
  5.         <div class="modal-content">  
  6.             <form role="form">  
  7.                 <div class="modal-header">  
  8.                     <button type="button" class="close" data-dismiss="modal"  
  9.                             aria-label="Close">  
  10.                         <span aria-hidden="true">&times;</span>  
  11.                     </button>  
  12.                     <h4 class="modal-title">角色添加</h4>  
  13.                 </div>  
  14.                 <div class="modal-body">  
  15.                     <input type="text" id="roleNameInput" class="form-control" placeholder="请输入角色名称" />  
  16.                 </div>  
  17.                 <div class="modal-footer">  
  18.                     <button type="button" id="addModalBtn" class="btn btn-default"><i class="glyphicon glyphicon-plus"></i> 保存</button>  
  19.                     <button type="reset" class="btn btn-primary"><i class="glyphicon glyphicon-refresh"></i> 重置</button>  
  20.                 </div>  
  21.             </form>  
  22.         </div>  
  23.     </div>  
  24. </div>  

将include-modal-role-add.jsp包含到role-page.jsp , <%@ include file="/WEB-INF/include-modal-role-add.jsp" %>

打开模态框 

  1. $("#addBtn").click(function(){ $("#addModal").modal("show"); }); 

给“保存”按钮绑定单击响应函数

标记“保存”按钮 

  1. <button id="addModalBtn" type="button" class="btn btn-success"> <i class="glyphicon glyphicon-plus"></i>保存 </button> 

绑定单击响应函数 

  1. $("#addModalBtn").click(function () {  
  2.             // 1.收集文本框内容  
  3.             var roleName = $.trim($("#roleNameInput").val());  
  4.             if (roleName == null || roleName == "") {  
  5.                 layer.msg("请输入有效角色名称!");  
  6.                 return;  
  7.             }  
  8.             // 2.发送请求  
  9.             $.ajax({  
  10.                 "url": "role/save/role.action",  
  11.                 "type": "post",  
  12.                 "data": {  
  13.                     "roleName": roleName 
  14.                 },  
  15.                 "dataType": "json",  
  16.                 "success": function (response) {  
  17.                     var result = response.result;  
  18.                     if (result == "SUCCESS") {  
  19.                         layer.msg("操作成功!");  
  20.                         // 3.操作成功重新分页  
  21.                         // 前往最后一页  
  22.                         window.pageNum = 999999 
  23.                         showPage();  
  24.                     }  
  25.                     if (result == "FAILED") {  
  26.                         layer.msg(response.message);  
  27.                     }  
  28.                     // 4.不管成功还是失败,关闭模态框  
  29.                     $("#addModal").modal("hide");  
  30.                     // 5.清理本次在文本框填写的数据  
  31.                     $("#roleNameInput").val(""); 
  32.                 },  
  33.                 "error": function (response) {  
  34.                     layer.msg(response.message);  
  35.                 }  
  36.             });  
  37.         });  

后端部分代码 

  1. @ResponseBody  
  2.     @RequestMapping("role/save/role")  
  3.     public ResultEntity<String> saveRole(@RequestParam("roleName") String roleName) {  
  4.         try {  
  5.             roleService.saveRole(roleName);  
  6.             return ResultEntity.successWithoutData();  
  7.         } catch (Exception e) {  
  8.             return ResultEntity.failed(null, e.getMessage());  
  9.         }  
  10.     }  

公共返回代码 

  1. public class ResultEntity<T> {  
  2.     public static final String SUCCESS = "SUCCESS" 
  3.     public static final String FAILED = "FAILED" 
  4.     public static final String NO_MESSAGE = "NO_MESSAGE" 
  5.     public static final String NO_DATA = "NO_DATA" 
  6.     // 方便返回成功结果(不携带查询结果情况)  
  7.     public static ResultEntity<String> successWithoutData() {  
  8.         return new ResultEntity<String>(SUCCESS, NO_MESSAGE, NO_DATA);  
  9.     }  
  10.     // 方便返回成功结果(携带查询结果情况)  
  11.     public static <E> ResultEntity<E> successWithData(E data) {  
  12.         return new ResultEntity<E>(SUCCESS, NO_MESSAGE, data);  
  13.     }  
  14.     // 方便返回失败结果  
  15.     public static <E> ResultEntity<E> failed(E data, String message) {  
  16.         return new ResultEntity<E>(FAILED, message, data);  
  17.     }  
  18.     private String result;  
  19.     private String message;  
  20.     private T data;  
  21.     public ResultEntity() {  
  22.     } 
  23.     public ResultEntity(String result, String message, T data) {  
  24.         super();  
  25.         this.result = result;  
  26.         this.message = message;  
  27.         this.data = data;  
  28.     }  
  29.     @Override  
  30.     public String toString() {  
  31.         return "ResultEntity [result=" + result + "message=" + message + "data=" + data + "]";  
  32.     }  
  33.     public String getResult() {  
  34.         return result;  
  35.     }  
  36.     public void setResult(String result) {  
  37.         this.result = result;  
  38.     }  
  39.     public String getMessage() {  
  40.         return message; 
  41.     }  
  42.     public void setMessage(String message) {  
  43.         this.message = message;  
  44.     }  
  45.     public T getData() {  
  46.         return data; 
  47.     }  
  48.     public void setData(T data) {  
  49.         this.data = data;  
  50.     }  
  51.  

角色维护-更新

大体步骤

给编辑按钮绑定单击响应函数

打开模态框

  • ​ 准备模态框
  • ​ 把roleId保存到全局变量
  • ​ 获取到当前按钮所在行的roleName
  • ​ 使用roleName回显模态框中的表单
  • ​ 给“更新”按钮绑定单击响应函数
  • ​ 收集文本框内容
  • ​ 发送请求
  • ​ 请求处理完成关闭模态框、重新分页

给编辑按钮绑定单击响应函数

标记编辑按钮

my-role.js文件 

  1. function generateTableBody(pageInfo) {  
  2.         //省略  
  3.         var pencilBtn = "<button type='button'   roleid='" + role.id + "' class='btn btn-primary btn-xs  editBtn'><i class=' glyphicon glyphicon-pencil'></i></button>"; 
  4.        //省略  
  5.     }  

 准备模态框 

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.          pageEncoding="UTF-8" %>  
  3. <div id="editModal" class="modal fade" tabindex="-1" role="dialog">  
  4.     <div class="modal-dialog" role="document">  
  5.         <div class="modal-content">  
  6.             <form role="form">  
  7.                 <div class="modal-header">  
  8.                     <button type="button" class="close" data-dismiss="modal"  
  9.                             aria-label="Close">  
  10.                         <span aria-hidden="true">&times;</span>  
  11.                     </button>  
  12.                     <h4 class="modal-title">尚筹网系统弹窗</h4>  
  13.                 </div>  
  14.                 <div class="modal-body">  
  15.                     <input type="text" id="roleNameInputEdit" class="form-control"  
  16.                            placeholder="请输入角色名称" />  
  17.                 </div>  
  18.                 <div class="modal-footer">  
  19.                     <button id="editModalBtn" type="button" class="btn btn-warning">  
  20.                         <i class="glyphicon glyphicon-edit"></i> 更新  
  21.                     </button>  
  22.                     <button type="reset" class="btn btn-primary">  
  23.                         <i class="glyphicon glyphicon-refresh"></i> 重置  
  24.                     </button>                </div>  
  25.             </form>  
  26.         </div>  
  27.     </div>  
  28. </div>  

将include-modal-role-add.jsp包含到role-page.jsp , <%@ include file="/WEB-INF/include-modal-role-edit.jsp" %>

绑定单击响应函数 

  1. $("#roleTableBody").on("click", ".editBtn", function () {  
  2.            // 1.获取当前按钮的roleId  
  3.            window.roleId = $(this).attr("roleId");  
  4.            // 2.获取当前按钮所在行的roleName  
  5.            var roleName = $(this).parents("tr").children("td:eq(2)").text();  
  6.            // 3.修改模态框中文本框的value值,目的是在显示roleName  
  7.            $("#roleNameInputEdit").val(roleName);  
  8.            // 4.打开模态框  
  9.            $("#editModal").modal("show");  
  10.        });  

给“更新”按钮绑定单击响应函数 

  1. $("#editModalBtn").click(function () {  
  2.             // 1.获取文本框值  
  3.             var roleName = $.trim($("#roleNameInputEdit").val());  
  4.             if (roleName == null || roleName == "") {  
  5.                 layer.msg("请输入有效角色名称!");  
  6.                 return;  
  7.             }  
  8.             // 2.发送请求  
  9.             $.ajax({  
  10.                 "url": "role/update.action",  
  11.                 "type": "post",  
  12.                 "data": {  
  13.                     "id": window.roleId,  
  14.                     "name": roleName  
  15.                 },  
  16.                 "dataType": "json",  
  17.                 "success": function (response) {  
  18.                     var result = response.result;  
  19.                     if (result == "SUCCESS") {  
  20.                         layer.msg("操作成功!");  
  21.                         // 3.操作成功重新分页  
  22.                         showPage();  
  23.                     }  
  24.                     if (result == "FAILED") {  
  25.                         layer.msg(response.message);  
  26.                     }  
  27.                     // 4.不管成功还是失败,关闭模态框  
  28.                     $("#editModal").modal("hide");  
  29.                 }  
  30.             });  
  31.         });  

后端部分代码 

  1. @ResponseBody  
  2.     @RequestMapping("role/update")  
  3.     public ResultEntity<String> updateRole(@RequestParam("id") Integer id,  
  4.                                            @RequestParam("name") String name) {  
  5.         Role role = new Role();  
  6.         role.setId(id);  
  7.         role.setName(name);  
  8.         try {  
  9.             roleService.updateRole(role);  
  10.             return ResultEntity.successWithoutData();  
  11.         } catch (Exception e) {  
  12.             return ResultEntity.failed(null, e.getMessage());  
  13.         }  
  14.     }  

异常映射兼容异步请求

问题表现

Ajax请求在服务器端处理过程中抛出异常,经过异常处理器: 

  1. @ControllerAdvice  
  2. public class CrowdFundingExceptionResolever {   
  3.     @ExceptionHandler(value=Exception.class)  
  4.     public ModelAndView catchException(Exception exception) {     
  5.          ModelAndView mav = new ModelAndView();       
  6.          mav.addObject("exception", exception);        
  7.         mav.setViewName("system-error");        
  8.          return mav; 
  9.      }  
  10.  

目前这个异常处理机制,只能返回页面,而不能针对Ajax请求返回JSON格式的响应数据。所以Ajax请求处理过程中,如果抛出异常,返回异常信息页面,Ajax程序无法正常解析,导致页面不能正常显示和工作,也不能给出友好的错误提示。

问题解决思路

异步请求特点

分辨异步请求的工具方法   

  1. /**  
  2.      * 用于判断一个请求是否是异步请求  
  3.      * @param request  
  4.      * @return  
  5.      */  
  6.     public static boolean checkAsyncRequest(HttpServletRequest request) {        
  7.         // 1.获取相应请求消息头  
  8.         String accept = request.getHeader("Accept");  
  9.         String xRequested = request.getHeader("X-Requested-With");        
  10.          // 2.判断请求消息头数据中是否包含目标特征  
  11.         if(  
  12.             (stringEffective(accept) && accept.contains("application/json"))  
  13.             ||   
  14.             (stringEffective(xRequested) && xRequested.contains("XMLHttpRequest")) ) {  
  15.             return true;  
  16.         }        
  17.          return false;  
  18.     }  
  19.     /**  
  20.      * 判断字符串是否有效  
  21.      * @param source 待验证字符串  
  22.      * @return true表示有效,false表示无效  
  23.      */  
  24.     public static boolean stringEffective(String source) {        
  25.          return source != null && source.length() > 0;  
  26.     }  

升级后的异常处理器

首先引入: 

  1. <dependency>  
  2.             <groupId>com.google.code.gson</groupId>  
  3.             <artifactId>gson</artifactId>  
  4.             <version>2.8.5</version>  
  5. </dependency>  
  1. @ControllerAdvice  
  2. public class CrowdFundingExceptionResolever {  
  3.     @ExceptionHandler(value = Exception.class)  
  4.     public ModelAndView catchException(  
  5.             Exception exception,  
  6.             HttpServletRequest request,  
  7.             HttpServletResponse response) throws IOException {  
  8.         // 1.对当前请求进行检查  
  9.         boolean checkAsyncRequestResult = CrowdFundingUtils.checkAsyncRequest(request);  
  10.         // 2.如果是异步请求  
  11.         if(checkAsyncRequestResult) {  
  12.             // 根据异常类型在常量中的映射,使用比较友好的文字显示错误提示消息  
  13.             String exceptionexceptionClassName = exception.getClass().getName(); 
  14.             String message = CrowdFundingConstant.EXCEPTION_MESSAGE_MAP.get(exceptionClassName);  
  15.             if(message == null) {  
  16.                 message = "系统未知错误" 
  17.             }  
  18.             // 3.创建ResultEntity对象  
  19.             ResultEntity<String> resultEntity = ResultEntity.failed(ResultEntity.NO_DATA, message);  
  20.             // 4.将resultEntity转换为JSON格式  
  21.             Gson gson = new Gson();  
  22.             String json = gson.toJson(resultEntity);  
  23.             // 5.将json作为响应数据返回给浏览器  
  24.             response.setContentType("application/json;charset=UTF-8");  
  25.             response.getWriter().write(json);  
  26.             return null;  
  27.         }  
  28.         ModelAndView mav = new ModelAndView();  
  29.         mav.addObject("exception", exception);  
  30.         mav.setViewName("system-error"); 
  31.         return mav;  
  32.     }  
  33.  

常量类 

  1. public class CrowdFundingConstant {      
  2.     public static final Map<String, String> EXCEPTION_MESSAGE_MAP = new HashMap<String, String>();  
  3.     static {  
  4.         EXCEPTION_MESSAGE_MAP.put("java.lang.ArithmeticException", "系统在进行数学运算时发生错误");  
  5.         EXCEPTION_MESSAGE_MAP.put("java.lang.RuntimeException", "系统在运行时发生错误");  
  6.         EXCEPTION_MESSAGE_MAP.put("com.atguigu.crowd.funding.exception.LoginException", "登录过程中运行错误");  
  7.     }  
  8.  

 

责任编辑:庞桂玉 来源: segmentfault
相关推荐

2016-10-13 19:16:28

Python编程语言mysql

2024-02-27 13:07:49

用户画像数据分析HR

2018-08-03 13:12:10

网络故障缓存数据WIFI

2021-02-20 16:29:26

用户画像数据收集流程

2019-11-07 15:39:36

数据库MySQL文章

2022-09-26 09:01:23

JavaScript浅拷贝深拷贝

2012-04-19 10:06:16

ibmdw

2019-08-02 09:13:22

Linux脚本语言欢聚时代

2019-08-05 09:19:45

PG事务隔离级别数据库

2019-07-30 07:43:39

Oracle数据库

2021-08-09 13:34:14

Python开发数据

2020-02-27 14:58:03

LinuxBash编程命令

2021-06-01 08:00:43

KubernetesCentOS版集群

2019-01-15 09:34:30

MySQL高性能优化

2009-11-12 09:18:40

ASP.NET MVC

2019-11-05 14:20:02

Oracle分组函数数据库

2019-10-22 07:50:45

SqlServer数据库触发器

2023-06-08 08:13:43

2021-10-20 09:04:21

Spring Beanscope数据库

2020-06-19 09:55:00

Redis数据库字符串
点赞
收藏

51CTO技术栈公众号