javaweb异常提示信息统一处理(使用springmvc,附源码)
一、前言
后台出现异常如何友好而又高效地回显到前端呢?直接将一堆的错误信息抛给用户界面,显然不合适。
先不考虑代码实现,我们希望是这样的:
(1)如果是页面跳转的请求,出现异常了,我们希望跳转到一个异常显示页面,如下:
当然,这里的界面不够美观,但是理论是这样的。
(2)如果是ajax请求,那么我们,希望后台将合理的错误显示返回到ajax的回调函数里面,如下:
$.ajax({
type: "post",
url: "<%=request.getContextPath()%>" + "/businessException.json",
data: {},
dataType: "json",
contentType : "application/json",
success: function(data) {
if(data.success == false){
alert(data.errorMsg);
}else{
alert("请求成功无异常");
}
},
error: function(data) {
alert("调用失败....");
}
});
将回调函数的data.errorMsg打印出来:
下面,我们根据上面的思路我们来看看代码的实现。因此本文实例包含了异常自定义分装,为了无障碍阅读下文,请猿友移步先看完博主的另外一篇文章:Java异常封装(自己定义错误码和描述,附源码)。
二、实例详解
本实例使用的环境 eclipse+maven,其中maven只是为了方便引入jar包。
使用的技术:springmvc
在Spring MVC中,所有用于处理在请求映射和请求处理过程中抛出的异常的类,都要实现HandlerExceptionResolver接口。HandlerExceptionResolver接口有一个方法resolveException,当controller层出现异常之后就会进入到这个方法resolveException。
下面我们直接实现HandlerExceptionResolver接口,代码如下:
package com.luo.exceptionresolver;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.druid.support.json.JSONUtils;
import com.luo.exception.BusinessException;
import org.springframework.web.servlet.HandlerExceptionResolver;
public class MySimpleMappingExceptionResolver implements
HandlerExceptionResolver {
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object object, Exception exception) {
// 判断是否ajax请求
if (!(request.getHeader("accept").indexOf("application/json") > -1 || (request
.getHeader("X-Requested-With") != null && request.getHeader(
"X-Requested-With").indexOf("XMLHttpRequest") > -1))) {
// 如果不是ajax,JSP格式返回
// 为安全起见,只有业务异常我们对前端可见,否则否则统一归为系统异常
Map<String, Object> map = new HashMap<String, Object>();
map.put("success", false);
if (exception instanceof BusinessException) {
map.put("errorMsg", exception.getMessage());
} else {
map.put("errorMsg", "系统异常!");
}
//这里需要手动将异常打印出来,由于没有配置log,实际生产环境应该打印到log里面
exception.printStackTrace();
//对于非ajax请求,我们都统一跳转到error.jsp页面
return new ModelAndView("/error", map);
} else {
// 如果是ajax请求,JSON格式返回
try {
response.setContentType("application/json;charset=UTF-8");
PrintWriter writer = response.getWriter();
Map<String, Object> map = new HashMap<String, Object>();
map.put("success", false);
// 为安全起见,只有业务异常我们对前端可见,否则统一归为系统异常
if (exception instanceof BusinessException) {
map.put("errorMsg", exception.getMessage());
} else {
map.put("errorMsg", "系统异常!");
}
writer.write(JSONUtils.toJSONString(map));
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
上面的代码,归结为以下几点:
(1)判断如果不是ajax请求,那么统一跳转到error.jsp页面,否则返回json数据。
(2)如果是业务异常,我们直接打印异常信息,否则,我们统一归为系统异常,如果不明白这里的业务异常为何物,请阅读博主博客:Java异常封装(自己定义错误码和描述,附源码)。
另外,需要在springmvc配置文件添加如下配置:
<!-- 框架异常处理Handler -->
<bean id="exceptionResolver" class="com.luo.exceptionresolver.MySimpleMappingExceptionResolver"></bean>
下面我们直接看controller代码:
package com.luo.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.luo.errorcode.LuoErrorCode;
import com.luo.exception.BusinessException;
@Controller
public class UserController {
@RequestMapping("/index.jhtml")
public ModelAndView getIndex(HttpServletRequest request) throws Exception {
ModelAndView mav = new ModelAndView("index");
return mav;
}
@RequestMapping("/exceptionForPageJumps.jhtml")
public ModelAndView exceptionForPageJumps(HttpServletRequest request) throws Exception {
throw new BusinessException(LuoErrorCode.NULL_OBJ);
}
@RequestMapping(value="/businessException.json", method=RequestMethod.POST)
@ResponseBody
public String businessException(HttpServletRequest request) {
throw new BusinessException(LuoErrorCode.NULL_OBJ);
}
@RequestMapping(value="/otherException.json", method=RequestMethod.POST)
@ResponseBody
public String otherException(HttpServletRequest request) throws Exception {
throw new Exception();
}
}
关于controller代码没什么好解释的,下面我们直接看结果吧:
(1)如果跳转页面过程中出现异常,访问http://localhost:8080/web_exception_project/exceptionForPageJumps.jhtml的结果:
(2)如果ajax请求过程中出现异常,访问http://localhost:8080/web_exception_project/index.jhtml,然后,点击业务异常按钮结果:
点击其他异常按钮结果:
(3)HandlerExceptionResolver接口并不能处理404错误,这种错误我们再web.xml里面添加如下配置:
<!-- 错误跳转页面 -->
<error-page>
<!-- 路径不正确 -->
<error-code>404</error-code>
<location>/WEB-INF/view/404.jsp</location>
</error-page>
然后404.jsp代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<taglib uri="http://java.sun.com /jsp/jstl/core" prefix="c" />
<html>
<head>
<title>错误页面</title>
</head>
<body>
页面被黑洞吸走了......
</body>
</html>
然后访问一个不存在的连接:http://localhost:8080/web_exception_project/123456.jhtml,结果如下:
三、本工程源码下载
javaweb异常提示信息统一处理(使用springmvc,附源码)的更多相关文章
- Javaweb异常提示信息统一处理
Java异常封装(自己定义错误码和描述,附源码) 2016年01月29日 22:30:54 小宝鸽 阅读数:23262 标签: java异常 更多 个人分类: Java基础 所属专栏: Java工作实 ...
- Javaweb中提到的反射浅析(附源码)
反射:一个jdk5.0的新特性,高级运用.在后期的框架中,这个是一大重点,现在估计我们都不会太多的接触他的.但是为了后面的铺垫,我想还是先了解一下: 先构造一个类,然后我们用反射来获取,调用里面的方法 ...
- Mybatis+SpringMVC实现分页查询(附源码)
Maven+Mybatis+Spring+SpringMVC实现分页查询(附源码) 一.项目搭建 关于项目搭建,小宝鸽以前写过一篇Spirng+SpringMVC+Maven+Mybatis+MySQ ...
- (原创)通用查询实现方案(可用于DDD)[附源码] -- 简介
[声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html). [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...
- 通用查询实现方案(可用于DDD)[附源码] -- 简介
原文:通用查询实现方案(可用于DDD)[附源码] -- 简介 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html). [ ...
- 阿里P7终于讲完了JDK+Spring+mybatis+Dubbo+SpringMvc+Netty源码
前言 这里普及一下,每个公司都有职别定级系统,阿里也是,技术岗以 P 定级,一般校招 P5, 社招 P6 起.其实阅读源码也是有很多诀窍的,这里分享几点心得: 首先要会用.你要知道这个库是干什么的,掌 ...
- C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码)
前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件.和上篇不同的是,这篇的有几个组件需要某些js文件的支持. 本文原创地址:http://www.cnblog ...
- Entity Framework在Asp.net MVC中的实现One Context Per Request(附源码)
上篇中"Entity Framework中的Identity map和Unit of Work模式", 由于EF中的Identity map和Unit of Work模式,EF体现 ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(6)-Unity 2.x依赖注入by运行时注入[附源码]
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(6)-Unity 2.x依赖注入by运行时注入[附源码] Unity 2.x依赖注入(控制反转)IOC,对 ...
随机推荐
- Entry的验证
Entry组件是支持验证输入的合法性的, 比如要求输入数字,你输入了字母就是非法. 实现该功能,需要通过设置validate,validatecommand,invalidcommand选项. 1.首 ...
- C#使用AutoMapper6.2.2.0进行对象映射
先说说DTO DTO是个什么东东? DTO(Data Transfer Object)就是数据传输对象,说白了就是一个对象,只不过里边全是数据而已. 为什么要用DTO? 1.DTO更注重数据,对领域对 ...
- Python的hasattr() getattr() setattr() 函数使用方法详解 (转)
来自:https://www.cnblogs.com/cenyu/p/5713686.html hasattr(object, name)判断一个对象里面是否有name属性或者name方法,返回BOO ...
- [Luogu 3919]【模板】可持久化数组(可持久化线段树/平衡树)
Description 如题,你需要维护这样的一个长度为 N 的数组,支持如下几种操作 在某个历史版本上修改某一个位置上的值 访问某个历史版本上的某一位置的值 此外,每进行一次操作(对于操作2,即为生 ...
- [Luogu 3414]SAC#1 - 组合数
Description 辣鸡蒟蒻SOL是一个傻逼,他居然觉得数很萌! 今天他萌上了组合数.现在他很想知道simga(C(n,i))是多少:其中C是组合数(即C(n,i)表示n个物品无顺序选取i个的方案 ...
- hihoCoder 1596 : Beautiful Sequence
Description Consider a positive integer sequence a[1], ..., a[n] (n ≥ 3). If for every 2 ≤ i ≤ n-1, ...
- hdu 5510 Bazinga(字符串kmp)
Bazinga Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- Blocks
Description solution 这题和之前做过的一题的一个套路非常类似:把不是更优的决策给去掉,使得序列变得具有单调性,分析这题: 发现如果两个右端点 \(i\),\(j\) 满足 \(su ...
- bzoj1493[NOI2007]项链工厂 线段树
1493: [NOI2007]项链工厂 Time Limit: 30 Sec Memory Limit: 64 MBSubmit: 1712 Solved: 723[Submit][Status] ...
- 【图文详解】linux下配置远程免密登录
linux下各种集群搭建往往需要配置远程免密登录,本文主要描述了CentOs6.3系统下配置免密登录的详细过程. ssh远程登录,两种身份验证: 用户名+密码 密钥验证 机器1生成密钥对并将公钥发给机 ...