1 html和json擴(kuò)展名問題
1.1 對(duì)應(yīng)*.html擴(kuò)展名的請(qǐng)求
返回一個(gè)完整頁(yè)面的請(qǐng)求。
1.2 對(duì)應(yīng)*.json擴(kuò)展名的請(qǐng)求
返回JSON數(shù)據(jù)的請(qǐng)求。
{"result":"SUCCESS","message":"NO_MESSAGE","data":
{"pageNum":2,"pageSize":5,"size":5,"startRow":6,"endRow":10,"total":100,"pages":20,"list":
[{"id":6,"name":"role5"},{"id":7,"name":"role6"},{"id":8,"name":"role7"},{"id":9,"name":"role8"},
{"id":10,"name":"role9"}],"firstPage":1,"prePage":1,"nextPage":3,"lastPage":8,"isFirstPage":false,
"isLastPage":false,"hasPreviousPage":true,"hasNextPage":true,"navigatePages":8,"navigatepageNums":
[1,2,3,4,5,6,7,8]}}
1.3 匹配錯(cuò)誤時(shí)的問題
如果請(qǐng)求擴(kuò)展名是*.html,但是實(shí)際返回的響應(yīng)體是JSON格式,Tomcat會(huì)認(rèn)為實(shí)際返回的響應(yīng)和響應(yīng)消息頭中的內(nèi)容類型不匹配,會(huì)拋異常。
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
此時(shí)要解決這個(gè)問題,將返回JSON數(shù)據(jù)的請(qǐng)求擴(kuò)展名設(shè)置為*.json或Tomcat無法識(shí)別的擴(kuò)展名即可。
例如:xxx.json或xxx.rgh都可以。
2. 角色維護(hù)-關(guān)鍵詞查詢功能
2.1 基本思路
在點(diǎn)擊“查詢”按鈕后,獲取文本框中填寫的keyword值,賦值給全局變量keyword,調(diào)用showPage()函數(shù)即可。
- 給“查詢”按鈕標(biāo)記id
- 給“查詢”按鈕綁定單擊響應(yīng)函數(shù)
- 在單擊響應(yīng)函數(shù)中獲取文本框中輸入的數(shù)據(jù)
- 驗(yàn)證輸入數(shù)據(jù)是否有效
- 如果無效,提示,停止函數(shù)執(zhí)行
- 如果有效,賦值給window.keyword
- 調(diào)用showPage()
2.2 代碼
$("#searchBtn").click(function(){
// 在單擊響應(yīng)函數(shù)中獲取文本框中輸入的數(shù)據(jù)
var keyword = $.trim($("#keywordInput").val());
// 驗(yàn)證輸入數(shù)據(jù)是否有效
if(keyword == null || keyword == "") {
// 如果無效,提示,停止函數(shù)執(zhí)行
layer.msg("請(qǐng)輸入關(guān)鍵詞!");
return ;
}
// 如果有效,賦值給window.keyword
window.keyword = keyword;
// 調(diào)用showPage()重新分頁(yè)
showPage();
});
layer.msg('xxx')無法顯示的原因
3 角色維護(hù)-全選功能
3.1 功能在頁(yè)面的位置
3.2 具體實(shí)現(xiàn)
3.2.1 標(biāo)記
總checkbox:/atcrowdfunding-admin-1-webui/src/main/webapp/WEB-INF/role-page.jsp
<thead>
<tr>
<th width="30">#</th>
<th width="30"><input id="summaryBox" type="checkbox"></th>
<th>名稱</th>
<th width="100">操作</th>
</tr>
</thead>
itembox:/atcrowdfunding-admin-1-webui/src/main/webapp/script/my-role.js
// 使用PageInfo數(shù)據(jù)在tbody標(biāo)簽內(nèi)顯示分頁(yè)數(shù)據(jù)
function generateTableBody(pageInfo) {
……
for(var i = 0; i < list.length; i++) {
……
var checkBoxTd = "<td><input roleid='"+role.id+"' class='itemBox' type='checkbox'></td>";
……
}
}
3.2.2 給#summaryBox綁定單擊響應(yīng)函數(shù)
// 全選/全不選功能
$("#summaryBox").click(function(){
// 1.獲取當(dāng)前checkbox的選中狀態(tài)
var currentStatus = this.checked;
// 2.設(shè)置itemBox的選中狀態(tài)
$(".itemBox").prop("checked",currentStatus);
});
4. 角色維護(hù)-批量刪除
4.1 準(zhǔn)備工作
4.1.1 準(zhǔn)備模態(tài)框
<div id="confirmModal" class="modal fade" tabindex="-1" role="dialog">
<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">尚籌網(wǎng)系統(tǒng)彈窗</h4>
</div>
<div class="modal-body">
<p>您確定要?jiǎng)h除下面的顯示的內(nèi)容嗎?</p>
<table class="table table-bordered">
<thead>
<tr>
<th width="30">#</th>
<th>名稱</th>
</tr>
</thead>
<tbody id="confirmModalTableBody"></tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary">OK</button>
</div>
</div>
</div>
</div>
創(chuàng)建include-modal-role-confirm.jsp文件保存模態(tài)框內(nèi)容。
在role-page.jsp中包含include-modal-role-confirm.jsp文件。
……
<%@ include file="/WEB-INF/include-modal-role-confirm.jsp" %>
</body>
4.1.2 getRoleListByRoleIdArray()函數(shù)
// 根據(jù)roleIdArray查詢r(jià)oleList
function getRoleListByRoleIdArray(roleIdArray) {
// 1.將roleIdArray轉(zhuǎn)換成JSON字符串
var requestBody = JSON.stringify(roleIdArray);
// 2.發(fā)送Ajax請(qǐng)求
var ajaxResult = $.ajax({
"url":"role/get/list/by/id/list.json",
"type":"post",
"data":requestBody,
"contentType":"application/json;charset=UTF-8",
"dataType":"json",
"async":false
});
// 3.獲取JSON對(duì)象類型的響應(yīng)體
var resultEntity = ajaxResult.responseJSON;
// 4.驗(yàn)證是否成功
var result = resultEntity.result;
if(result == "SUCCESS") {
// 5.如果成功,則返回roleList
return resultEntity.data;
}
if(result == "FAILED") {
layer.msg(resultEntity.message);
return null;
}
return null;
}
對(duì)應(yīng)的后端代碼:
com.rgh.crowd.funding.handler.RoleHandler
// handler方法
@ResponseBody
@RequestMapping("/role/get/list/by/id/list")
public ResultEntity<List<Role>> getRoleListByIdList(@RequestBody List<Integer> roleIdList) {
List<Role> roleList = roleService.getRoleListByIdList(roleIdList);
return ResultEntity.successWithData(roleList);
}
com.rgh.crowd.funding.service.impl.RoleServiceImpl
// service方法
@Override
public List<Role> getRoleListByIdList(List<Integer> roleIdList) {
// 預(yù)期的SQL語句
// select id,name from t_role where id in (1,2,3,6,12)
// 創(chuàng)建實(shí)體類Role對(duì)應(yīng)的Example對(duì)象
RoleExample roleExample = new RoleExample();
// 在Example對(duì)象中封裝查詢條件
roleExample.createCriteria().andIdIn(roleIdList);
// 執(zhí)行查詢
return roleMapper.selectByExample(roleExample);
}
4.1.3 showRemoveConfirmModal()函數(shù)
// 打開刪除確認(rèn)模態(tài)框
function showRemoveConfirmModal() {
// 1.將模態(tài)框顯示出來
$("#confirmModal").modal("show");
// 2.根據(jù)roleIdList獲取roleList
var roleList = getRoleListByRoleIdArray(window.roleIdArray);
// 3.清空#confirmModalTableBody
$("#confirmModalTableBody").empty();
// 4.填充#confirmModalTableBody
for(var i = 0; i < roleList.length; i++) {
// 5.獲取角色相關(guān)數(shù)據(jù)
var role = roleList[i];
var id = role.id;
var name = role.name;
var trHTML = "<tr><td>"+id+"</td><td>"+name+"</td></tr>";
// 6.執(zhí)行填充
$("#confirmModalTableBody").append(trHTML);
}
}
4.2 給批量刪除按鈕綁定單擊響應(yīng)函數(shù)
4.2.1 標(biāo)記批量刪除按鈕
<button id="batchRemoveBtn" type="button" class="btn btn-danger"
style="float: right; margin-left: 10px;">
<i class=" glyphicon glyphicon-remove"></i> 批量刪除
</button>
4.2.2 檢查itemBox是否被選中
// 給批量刪除按鈕綁定單擊響應(yīng)函數(shù)
$("#batchRemoveBtn").click(function(){
// 獲取被選中的itemBox數(shù)組長(zhǎng)度
var length = $(".itemBox:checked").length;
// 如果長(zhǎng)度為0,說明沒有選擇itemBox
if(length == 0) {
layer.msg("請(qǐng)至少選擇一條!");
return ;
}
// 未完待續(xù)...
});
4.2.3 在彈出的模態(tài)框中顯示confirm信息
// 給批量刪除按鈕綁定單擊響應(yīng)函數(shù)
$("#batchRemoveBtn").click(function(){
// 獲取被選中的itemBox數(shù)組長(zhǎng)度
var length = $(".itemBox:checked").length;
// 如果長(zhǎng)度為0,說明沒有選擇itemBox
if(length == 0) {
layer.msg("請(qǐng)至少選擇一條!");
return ;
}
// 在全局作用域內(nèi)創(chuàng)建roleIdArray
window.roleIdArray = new Array();
// 遍歷$(".itemBox:checked")
$(".itemBox:checked").each(function(){
// 通過checkbox的roleid屬性獲取roleId值
var roleId = $(this).attr("roleid");
// 存入數(shù)組
window.roleIdArray.push(roleId);
});
// 調(diào)用函數(shù)打開模態(tài)框
showRemoveConfirmModal();
});
4.3 點(diǎn)擊模態(tài)框的OK按鈕執(zhí)行刪除
4.3.1 標(biāo)記OK按鈕
<button id="confirmModalBtn" type="button" class="btn btn-primary">OK</button>
4.3.2 綁定單擊響應(yīng)函數(shù)
// 給確認(rèn)模態(tài)框中的OK按鈕綁定單擊響應(yīng)函數(shù)
$("#confirmModalBtn").click(function(){
var requestBody = JSON.stringify(window.roleIdArray);
$.ajax({
"url":"role/batch/remove.json",
"type":"post",
"data":requestBody,
"contentType":"application/json;charset=UTF-8",
"dataType":"json",
"success":function(response){
var result = response.result;
if(result == "SUCCESS") {
layer.msg("操作成功!");
// 如果刪除成功,則重新調(diào)用分頁(yè)方法
showPage();
}
if(result == "FAILED") {
layer.msg(response.message);
}
// 不管成功還是失敗,都需要關(guān)掉模態(tài)框
$("#confirmModal").modal("hide");
},
"error":function(response){
layer.msg(response.message);
}
});
});
4.3.3 后端代碼
com.rgh.crowd.funding.handler.RoleHandler
@ResponseBody
@RequestMapping("/role/batch/remove")
public ResultEntity<String> batchRemove(@RequestBody List<Integer> roleIdList) {
roleService.batchRemove(roleIdList);
return ResultEntity.successWithoutData();
}
com.rgh.crowd.funding.service.impl.RoleServiceImpl
@Override
public void batchRemove(List<Integer> roleIdList) {
RoleExample roleExample = new RoleExample();
roleExample.createCriteria().andIdIn(roleIdList);
roleMapper.deleteByExample(roleExample);
}
5 角色維護(hù)-單條刪除
// 針對(duì).removeBtn這樣動(dòng)態(tài)生成的元素對(duì)象使用on()函數(shù)方式綁定單擊響應(yīng)函數(shù)
// $("動(dòng)態(tài)元素所依附的靜態(tài)元素").on("事件類型","具體要綁定事件的動(dòng)態(tài)元素的選擇器", 事件響應(yīng)函數(shù));
$("#roleTableBody").on("click",".removeBtn", function(){
// 獲取當(dāng)前記錄的roleId
var roleId = $(this).attr("roleId");
// 存入全局變量數(shù)組
window.roleIdArray = new Array();
window.roleIdArray.push(roleId);
// 打開模態(tài)框(后續(xù)所有操作都和批量刪除一樣)
showRemoveConfirmModal();
});
6 角色維護(hù)-新增
6.1 大體步驟
- 給“新增”按鈕綁定單擊響應(yīng)函數(shù)
- 打開模態(tài)框
- 給“保存”按鈕綁定單擊響應(yīng)函數(shù)
- 收集文本框內(nèi)容
- 發(fā)送請(qǐng)求
- 請(qǐng)求處理完成關(guān)閉模態(tài)框、重新分頁(yè)、清理表單
6.2 給“新增”按鈕綁定單擊響應(yīng)函數(shù)
6.2.1 標(biāo)記“新增”按鈕
<button id="addBtn" type="button" class="btn btn-primary"
style="float: right;" >
<i class="glyphicon glyphicon-plus"></i> 新增
</button>
6.2.2 綁定單擊響應(yīng)函數(shù)
$("#addBtn").click(function(){
alert("aaa...");
});
6.3 打開模態(tài)框
6.3.1 準(zhǔn)備模態(tài)框
先準(zhǔn)備模態(tài)框的HTML代碼
<div id="addModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form role="form">
<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">尚籌網(wǎng)系統(tǒng)彈窗</h4>
</div>
<div class="modal-body">
<input type="text" id="roleNameInput" class="form-control" placeholder="請(qǐng)輸入角色名稱" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default"><i class="glyphicon glyphicon-plus"></i> 保存</button>
<button type="reset" class="btn btn-primary"><i class="glyphicon glyphicon-refresh"></i> 重置</button>
</div>
</form>
</div>
</div>
</div>
創(chuàng)建/atcrowdfunding-admin-1-webui/src/main/webapp/WEB-INF/include-modal-role-add.jsp文件
將include-modal-role-add.jsp包含到role-page.jsp
<%@ include file="/WEB-INF/include-modal-role-add.jsp" %>
6.3.2 打開模態(tài)框
$("#addBtn").click(function(){
$("#addModal").modal("show");
});
6.4 給“保存”按鈕綁定單擊響應(yīng)函數(shù)
6.4.1 標(biāo)記“保存”按鈕
<button id="addModalBtn" type="button" class="btn btn-success">
<i class="glyphicon glyphicon-plus"></i>保存
</button>
6.4.2 綁定單擊響應(yīng)函數(shù)
$("#addModalBtn").click(function(){
// 1.收集文本框內(nèi)容
var roleName = $.trim($("#roleNameInput").val());
if(roleName == null || roleName == "") {
layer.msg("請(qǐng)輸入有效角色名稱!");
return ;
}
// 2.發(fā)送請(qǐng)求
$.ajax({
"url":"role/save/role.json",
"type":"post",
"data":{
"roleName":roleName
},
"dataType":"json",
"success":function(response){
var result = response.result;
if(result == "SUCCESS") {
layer.msg("操作成功!");
// 3.操作成功重新分頁(yè)
// 前往最后一頁(yè)
window.pageNum = 999999;
showPage();
}
if(result == "FAILED") {
layer.msg(response.message);
}
// 4.不管成功還是失敗,關(guān)閉模態(tài)框
$("#addModal").modal("hide");
// 5.清理本次在文本框填寫的數(shù)據(jù)
$("#roleNameInput").val("");
},
"error":function(response){
layer.msg(response.message);
}
});
});
6.5 后端代碼
com.rgh.crowd.funding.handler.RoleHandler
@ResponseBody
@RequestMapping("/role/save/role")
public ResultEntity<String> saveRole(@RequestParam("roleName") String roleName) {
roleService.saveRole(roleName);
return ResultEntity.successWithoutData();
}
com.rgh.crowd.funding.service.impl.RoleServiceImpl
@Override
public void saveRole(String roleName) {
roleMapper.insert(new Role(null, roleName));
}
7 角色維護(hù)-更新
7.1 大體步驟
-
給“鉛筆”按鈕綁定單擊響應(yīng)函數(shù)
因?yàn)椤般U筆”按鈕是動(dòng)態(tài)生成的,所以需要使用on()方式
-
打開模態(tài)框
- 準(zhǔn)備模態(tài)框
- 把roleId保存到全局變量
- 獲取到當(dāng)前“鉛筆”按鈕所在行的roleName
- 使用roleName回顯模態(tài)框中的表單
-
給“更新”按鈕綁定單擊響應(yīng)函數(shù)
- 收集文本框內(nèi)容
- 發(fā)送請(qǐng)求
- 請(qǐng)求處理完成關(guān)閉模態(tài)框、重新分頁(yè)
7.2 給“鉛筆”按鈕綁定單擊響應(yīng)函數(shù)
7.2.1 標(biāo)記“鉛筆”按鈕
找到/atcrowdfunding-admin-1-webui/src/main/webapp/script/my-role.js文件
function generateTableBody(pageInfo) {
……
for(var i = 0; i < list.length; i++) {
……
var pencilBtn = "<button roleId='"+role.id+"' type='button' class='btn btn-primary btn-xs editBtn'><i class=' glyphicon glyphicon-pencil'></i></button>";
……
}
}
7.2.2 準(zhǔn)備模態(tài)框
<div id="editModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<form role="form">
<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">尚籌網(wǎng)系統(tǒng)彈窗</h4>
</div>
<div class="modal-body">
<input type="text" id="roleNameInputEdit" class="form-control"
placeholder="請(qǐng)輸入角色名稱" />
</div>
<div class="modal-footer">
<button id="editModalBtn" type="button" class="btn btn-warning">
<i class="glyphicon glyphicon-edit"></i> 更新
</button>
<button type="reset" class="btn btn-primary">
<i class="glyphicon glyphicon-refresh"></i> 重置
</button> </div>
</form>
</div>
</div>
</div>
<%@ include file="/WEB-INF/include-modal-role-edit.jsp" %>
7.2.3 綁定單擊響應(yīng)函數(shù)
$("#roleTableBody").on("click",".editBtn",function(){
// 1.獲取當(dāng)前按鈕的roleId
window.roleId = $(this).attr("roleId");
// 2.獲取當(dāng)前按鈕所在行的roleName
var roleName = $(this).parents("tr").children("td:eq(2)").text();
// 3.修改模態(tài)框中文本框的value值,目的是在顯示roleName
$("#roleNameInputEdit").val(roleName);
// 4.打開模態(tài)框
$("#editModal").modal("show");
});
7.3 給“更新”按鈕綁定單擊響應(yīng)函數(shù)
7.3.1 前端代碼
$("#editModalBtn").click(function(){
// 1.獲取文本框值
var roleName = $.trim($("#roleNameInputEdit").val());
if(roleName == null || roleName == "") {
layer.msg("請(qǐng)輸入有效角色名稱!");
return ;
}
// 2.發(fā)送請(qǐng)求
$.ajax({
"url":"role/update/role.json",
"type":"post",
"data":{
"id":window.roleId,
"name":roleName
},
"dataType":"json",
"success":function(response){
var result = response.result;
if(result == "SUCCESS") {
layer.msg("操作成功!");
// 3.操作成功重新分頁(yè)
showPage();
}
if(result == "FAILED") {
layer.msg(response.message);
}
// 4.不管成功還是失敗,關(guān)閉模態(tài)框
$("#editModal").modal("hide");
}
});
});
7.3.2 后端代碼
@ResponseBody
@RequestMapping("/role/update/role")
public ResultEntity<String> updateRole(Role role) {
roleService.updateRole(role);
return ResultEntity.successWithoutData();
}
@Override
public void updateRole(Role role) {
roleMapper.updateByPrimaryKey(role);
}
8 @RestController
相當(dāng)于@Controller注解+@ResponseBody注解,類使用了@RestController之后相當(dāng)于在每一個(gè)方法上都加了@ResponseBody注解。
9 異常映射兼容異步請(qǐng)求
9.1 問題表現(xiàn)
Ajax請(qǐng)求在服務(wù)器端處理過程中拋出異常,經(jīng)過異常處理器:
com.rgh.crowd.funding.exception.CrowFundingExceptionResolever
@ControllerAdvice
public class CrowdFundingExceptionResolever {
@ExceptionHandler(value=Exception.class)
public ModelAndView catchException(Exception exception) {
ModelAndView mav = new ModelAndView();
mav.addObject("exception", exception);
mav.setViewName("system-error");
return mav;
}
}
目前這個(gè)異常處理機(jī)制,只能返回頁(yè)面,而不能針對(duì)Ajax請(qǐng)求返回JSON格式的響應(yīng)數(shù)據(jù)。所以Ajax請(qǐng)求處理過程中,如果拋出異常,返回異常信息頁(yè)面,Ajax程序無法正常解析,導(dǎo)致頁(yè)面不能正常顯示和工作,也不能給出友好的錯(cuò)誤提示。
9.2 問題解決思路
9.3 異步請(qǐng)求特點(diǎn)
9.4 分辨異步請(qǐng)求的工具方法
在atcrowdfunding-admin-3-common工程加入servlet-api依賴
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
com.rgh.crowd.funding.util.CrowdFundingUtils
/**
* 用于判斷一個(gè)請(qǐng)求是否是異步請(qǐng)求
* @param request
* @return
*/
public static boolean checkAsyncRequest(HttpServletRequest request) {
// 1.獲取相應(yīng)請(qǐng)求消息頭
String accept = request.getHeader("Accept");
String xRequested = request.getHeader("X-Requested-With");
// 2.判斷請(qǐng)求消息頭數(shù)據(jù)中是否包含目標(biāo)特征
if(
(stringEffective(accept) && accept.contains("application/json"))
||
(stringEffective(xRequested) && xRequested.contains("XMLHttpRequest")) ) {
return true;
}
return false;
}
9.5 升級(jí)后的異常處理器
@ControllerAdvice
public class CrowdFundingExceptionResolever {
@ExceptionHandler(value=Exception.class)
public ModelAndView catchException(
Exception exception,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
// 1.對(duì)當(dāng)前請(qǐng)求進(jìn)行檢查
boolean checkAsyncRequestResult = CrowdFundingUtils.checkAsyncRequest(request);
// 2.如果是異步請(qǐng)求
if(checkAsyncRequestResult) {
// 3.創(chuàng)建ResultEntity對(duì)象
ResultEntity<String> resultEntity = ResultEntity.failed(ResultEntity.NO_DATA, exception.getMessage());
// 4.將resultEntity轉(zhuǎn)換為JSON格式
Gson gson = new Gson();
String json = gson.toJson(resultEntity);
// 5.將json作為響應(yīng)數(shù)據(jù)返回給瀏覽器
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(json);
return null;
}
ModelAndView mav = new ModelAndView();
mav.addObject("exception", exception);
mav.setViewName("system-error");
return mav;
}
}
※需要Gson支持
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
9.6 改進(jìn)提示消息
- 所在工程:atcrowdfunding-admin-3-common
- 全類名:com.rgh.crowd.funding.util.CrowdFundingConstant
public static final Map<String, String> EXCEPTION_MESSAGE_MAP = new HashMap<>();
static {
EXCEPTION_MESSAGE_MAP.put("java.lang.ArithmeticException", "系統(tǒng)在進(jìn)行數(shù)學(xué)運(yùn)算時(shí)發(fā)生錯(cuò)誤");
EXCEPTION_MESSAGE_MAP.put("java.lang.RuntimeException", "系統(tǒng)在運(yùn)行時(shí)發(fā)生錯(cuò)誤");
EXCEPTION_MESSAGE_MAP.put("com.rgh.crowd.funding.exception.LoginException", "登錄過程中運(yùn)行錯(cuò)誤");
}
- 所在工程:atcrowdfunding-admin-2-component
- 全類名:com.rgh.crowd.funding.exeption.CrowdFundingExceptionResolever
@ControllerAdvice
public class CrowdFundingExceptionResolever {
@ExceptionHandler(value=Exception.class)
public ModelAndView catchException(
Exception exception,
HttpServletRequest request,
HttpServletResponse response) throws IOException {
// 1.對(duì)當(dāng)前請(qǐng)求進(jìn)行檢查
boolean checkAsyncRequestResult = CrowdFundingUtils.checkAsyncRequest(request);
// 2.如果是異步請(qǐng)求
if(checkAsyncRequestResult) {
// 根據(jù)異常類型在常量中的映射,使用比較友好的文字顯示錯(cuò)誤提示消息
String exceptionClassName = exception.getClass().getName();
String message = CrowdFundingConstant.EXCEPTION_MESSAGE_MAP.get(exceptionClassName);
if(message == null) {
message = "系統(tǒng)未知錯(cuò)誤";
}
// 3.創(chuàng)建ResultEntity對(duì)象
ResultEntity<String> resultEntity = ResultEntity.failed(ResultEntity.NO_DATA, message);
// 4.將resultEntity轉(zhuǎn)換為JSON格式
Gson gson = new Gson();
String json = gson.toJson(resultEntity);
// 5.將json作為響應(yīng)數(shù)據(jù)返回給瀏覽器
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(json);
return null;
}
ModelAndView mav = new ModelAndView();
mav.addObject("exception", exception);
mav.setViewName("system-error");
return mav;
}
}
10 登錄攔截器兼容異步請(qǐng)求
問題的產(chǎn)生和解決的思路都和異常映射部分一致
com.rgh.crowd.funding.interceptor.LoginInterceptor
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 通過request對(duì)象獲取HttpSession對(duì)象
HttpSession session = request.getSession();
// 從Session域嘗試獲取已登錄用戶對(duì)象
Admin admin = (Admin) session.getAttribute(CrowdFundingConstant.ATTR_NAME_LOGIN_ADMIN);
// 如果沒有獲取到Admin對(duì)象
if(admin == null) {
// 進(jìn)一步判斷當(dāng)前請(qǐng)求是否是異步請(qǐng)求
boolean checkAsyncRequestResult = CrowdFundingUtils.checkAsyncRequest(request);
if(checkAsyncRequestResult) {
// 為異步請(qǐng)求的響應(yīng)創(chuàng)建ResultEntity對(duì)象
ResultEntity<String> resultEntity = ResultEntity.failed(ResultEntity.NO_DATA, CrowdFundingConstant.MESSAGE_ACCESS_DENIED);
// 創(chuàng)建Gson對(duì)象
Gson gson = new Gson();
// 將ResultEntity對(duì)象轉(zhuǎn)換為JSON字符串
String json = gson.toJson(resultEntity);
// 設(shè)置響應(yīng)的內(nèi)容類型
response.setContentType("application/json;charset=UTF-8");
// 將JSON字符串作為響應(yīng)數(shù)據(jù)返回
response.getWriter().write(json);
// 表示不能放行,后續(xù)操作不執(zhí)行
return false;
}
// 將提示消息存入request域
request.setAttribute(CrowdFundingConstant.ATTR_NAME_MESSAGE, CrowdFundingConstant.MESSAGE_ACCESS_DENIED);
// 轉(zhuǎn)發(fā)到登錄頁(yè)面
request.getRequestDispatcher("/WEB-INF/admin-login.jsp").forward(request, response);
return false;
}
// 如果admin對(duì)象有效,則放行繼續(xù)執(zhí)行后續(xù)操作
return true;
}
11 分頁(yè)的showPage()函數(shù)修正
// 給服務(wù)器發(fā)送請(qǐng)求獲取分頁(yè)數(shù)據(jù)(pageInfo),并在頁(yè)面上顯示分頁(yè)效果(主體、頁(yè)碼導(dǎo)航條)
function showPage() {
// 給服務(wù)器發(fā)送請(qǐng)求獲取分頁(yè)數(shù)據(jù):PageInfo
var pageInfo = getPageInfo();
console.log(pageInfo);
if(pageInfo == null) {
// 如果沒有獲取到pageInfo數(shù)據(jù),則停止后續(xù)操作
return ;
}
// 在頁(yè)面上的表格中tbody標(biāo)簽內(nèi)顯示分頁(yè)的主體數(shù)據(jù)
generateTableBody(pageInfo);
// 在頁(yè)面上的表格中tfoot標(biāo)簽內(nèi)顯示分頁(yè)的頁(yè)碼導(dǎo)航條
initPagination(pageInfo);
}