SSM全局异常处理——两种实用实现方案

news/2025/6/19 17:38:45
## SSM全局异常处理——两种实用实现方案 ##先前做项目时自己不是很门清这块,在网上查阅资料后发现资料也不是很全面,因此自己摸索出来后就想着赶紧给大家分享一下,尽管此技术点很基础,但是希望能够帮到大家。

为什么实现:

  • 在我们的项目运行过程中,无法完全避免出现一些位置的运行时异常(比如NullPointerException ),而恰恰我们并没有对该异常进行处理,那么就会将此异常抛向用户。
  • 当用户浏览页面时突然眼前蹦出一堆看不懂的“外星文”,可想而知用户的体验度是非常差的。
  • 而如果简单的配置一下异常处理的话可以在web.xml中进行配置异常后跳转的页面,例如404
  <error-page><error-code>404</error-code><location>/404err.jsp</location></error-page>

            这种方法现在已经low到爆哦,如果我们是json请求呢?因此我们需要自己实现一套完美的异常处理,保证我们系统是健壮的!

 

 
springmvc HandlerExceptionResolver异常处理器:
今天我们就在springmvc的这个接口上进行一番操作(异常处理器啥是?)

public class SpringExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {

参数:

      request:当前请求

      response:当前响应对象

      ex: 当本次方法执行异常,这个参数就是当前异常对象

 

 
实现方式A——根据请求类型,选择不同的异常处理方式(不要忽略代码注释哦)
我们项目中的请求在一种角度可上分页面请求、json请求。因此根据请求类型,选择不同的异常处理方式就可以理解为:如果是页面请求异常了,我们就选择页面请求异常处理来返回错误信息。如果是json请求异常,那么就以json的形式返回。

 

开始前准备两个异常类型,为我们手动抛异常能区分开请求类型
CustomException:使用场景是前台发送json请求,那么我们在该请求的service层抛出CustomException,前台就会收到异常信息。

/*** 如果抛出此异常,系统会以json格式向前台返回异常信息* 使用方式: throw new CustomException("这里填入异常信息,会发送到前台");*/
public class CustomException extends Exception{private static final long serialVersionUID = -1668707977736987938L;//异常信息public String message;public CustomException (String message) {super(message);this.message = message;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}

 

/**
* @ClassName: ReturnViewException 
* @Description: 此异常类型用来向前台返回页面*/
public class ReturnViewException extends Exception{private static final long serialVersionUID = -1668707977736987938L;//异常信息public String message;public ReturnViewException (String message) {super(message);this.message = message;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}

 

public class IntegrateException implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,Exception ex) {//判断是否为ajax请求,默认不是boolean isAjaxRequest = false;  //这段代码能够得知是否为ajax请求,也就是我们说的json请求if(!StringUtils.isBlank(request.getHeader("x-requested-with")) && request.getHeader("x-requested-with").equals("XMLHttpRequest")){  isAjaxRequest = true; }//如果是ajax请求if(isAjaxRequest) {CustomException  customException = null;if(ex instanceof CustomException) {customException = (CustomException) ex;}else {//如果抛出的不是系统自定义的异常则重新构造一个未知错误异常//这里我就也有CustomException省事了,实际中应该要再定义一个新的异常customException = new CustomException ("系统未知错误,请联系管理员");}String message = customException.getMessage();//向前台返回错误信息ModelAndView model = new ModelAndView();FastJsonJsonView view = new FastJsonJsonView();Map<String,Object> map = new HashMap<String,Object>();map.put("code", 5000);map.put("message", message);view.setAttributesMap(map);model.setView(view);return model;}else {//如果不是ajax请求 那么异常后需要返回页面ReturnViewException returnViewException = null;//如果抛出的异常类型是我们预想的,会想前台返回我们指定在参数里的页面if(ex instanceof ReturnViewException) {returnViewException = (ReturnViewException) ex;}else {//这里的500是我资源下的500.jsp,使用了mvc的映射省去了前缀后缀//系统默认跳转到500页面returnViewException = new ReturnViewException("500"); }ModelAndView model = new ModelAndView();model.setViewName(returnViewException.getMessage());return model;}}
}

在此同时我们需要在springmvc.xml中配置我们的全局异常处理类,bean id别随意更改..

<bean id="exceptionHandler" class="com.bdqn.oa.exception.IntegrateException"></bean>

现在就可以开始使用了~~~~

手动使用:

throw new CustemException("错误了"); //向前台返回 '错误了' 异常信息
throw new ReturnViewException("500err") //前台重定向到500err.jsp

当然出现未知异常后,回自动向前台返回我们默认的异常信息

 
实现方式B——自定义项目接口规则,判断特定的异常处理方式
实现的主要原理更简单明亮:

方才A方案是判断请求类型,这里我们更加暴力,假如我规定项目的json请求全部以 .json结尾,页面请求全部以 .page结尾,那么我们就可以在异常处理器拦截到异常时,判断请求的后缀来决定怎么处理了。不同点就在这里,但是虽然A复杂点,我还是推荐使用A

好,抛代码,这是springmvc.xml

   <!--我们的异常处理器--><bean class="com.mmall.common.SpringExceptionResolver" /><!--关键点就是我们使用这两个只不过这是spring整合了jackson,不需要我们再引用阿里的fastjson了--><bean class="org.springframework.web.servlet.view.BeanNameViewResolver" /><bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />

 

创建异常类(这个东西,根据需要判多少种异常类型,我们可以创很多的,不仅限于一两个)

public class ParamException extends RuntimeException {public ParamException() {super();}public ParamException(String message) {super(message);}public ParamException(String message, Throwable cause) {super(message, cause);}public ParamException(Throwable cause) {super(cause);}protected ParamException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}
public class PermissionException extends RuntimeException {public PermissionException() {super();}public PermissionException(String message) {super(message);}public PermissionException(String message, Throwable cause) {super(message, cause);}public PermissionException(Throwable cause) {super(cause);}protected PermissionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}
}

然后我们上最关键的异常处理器

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {String url = request.getRequestURL().toString();ModelAndView mv;String defaultMsg = "System error";// 这里我们要求项目中所有请求json数据,都使用.json结尾if (url.endsWith(".json")) {if (ex instanceof PermissionException || ex instanceof ParamException) {JsonData result = JsonData.fail(ex.getMessage());mv = new ModelAndView("jsonView", result.toMap());} else {log.error("unknown json exception, url:" + url, ex);JsonData result = JsonData.fail(defaultMsg);mv = new ModelAndView("jsonView", result.toMap());}} else if (url.endsWith(".page")){ // 这里我们要求项目中所有请求page页面,都使用.page结尾log.error("unknown page exception, url:" + url, ex);JsonData result = JsonData.fail(defaultMsg);mv = new ModelAndView("exception", result.toMap());} else {log.error("unknow exception, url:" + url, ex);JsonData result = JsonData.fail(defaultMsg);mv = new ModelAndView("jsonView", result.toMap());}return mv;}

结束语:

这就是我整理出来的两种ssm全局异常处理方式了,希望能够帮助到大家。本人也处于学习的阶段,发表此文章也是希望能够得到更多的技术交流和帮助,文中的不足还有劳大家指出!

SSM全局异常处理——两种实用实现方案

csdn:https://blog.csdn.net/qq_4182...


https://dhexx.cn/news/show-400858.html

相关文章

loadrunner Lr_类函数之 lr_peek_events()

lr_peek_events&#xff08;&#xff09; 检查事件。 void lr_peek_events&#xff08;&#xff09;; lr_peek_events函数暂停Vuser脚本运行&#xff0c;并在恢复之前检查事件。 使用C语言编写的脚本在内部执行此检查。因此&#xff0c;不需要使用lr_peek_events函数。 用Jav…

大型网站的HTTPS实践一:HTTPS协议和原理三

4.1.2 对称内容加密非对称密钥交换过程结束之后就得出了本次会话需要使用的对称密钥。对称加密又分为两种模式&#xff1a;流式加密和分组加密。流式加密现在常用的就是 RC4&#xff0c;不过 RC4 已经不再安全&#xff0c;微软也建议网站尽量不要使用 RC4 流式加密。一种新的替…

HTML第一天

1、h系列的标签 h&#xff1a;headline 缩写&#xff0c;标题。 h 系列的标签有六个等级&#xff1a;h1,h2,h3,h4,h5,h6 分别表示从一到六标题&#xff1a; <h1>我是一级标题</h1> <h2>我是二级标题</h2> <h3>我是三级标题</h3> <h4…

如何创建Exchange2007邮件服务器

规划和安装Exchange2007<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />实验案例一&#xff1a;安装Exchange2007实验目标掌握安装Exchange2007的邮箱服务器角色&#xff0c;中心传输服务器角色和客户端访问服务器角色。需求分析…

46 WebGL网页上显示三维物体

案例查看地址&#xff1a;点击这里 想要把三维物体显示到网页上面&#xff0c;很简单&#xff0c;只要会css&#xff0c;懂得盒子模型&#xff0c;定位&#xff0c;就可以在网页上面随意放置模型&#xff0c;控制canvas位置就可以。 这次的案例直接body添加了一个背景&#xff…

loadrunner Lr_类函数之 lr_rendezvous()

lr_rendezvous&#xff08;&#xff09; 在Vuser脚本中创建会合点。 int lr_rendezvous&#xff08;const char * rendezvous_name&#xff09;; 参数说明&#xff1a; rendezvous_name&#xff1a;集合的名称。 lr_rendezvous函数在Vuser脚本中创建集合点。执行此语句时&am…

linux /usr/local/apache/bin/apxs 路径是在的,为什么会提示You must specify a valid --with-apxs path...

linux 下编译捍You must specify a valid --with-apxs path原因是&#xff1a;在没有安装prel就先安装apache造成的解决方法&#xff1a;[rootapache bin]# vi /usr/local/apache/bin/apxs修改下面的第一行#!/usr/bin/perl -w## Licensed to the Apache Software Foundation (A…

Java 复习

基本知识点 文件名必须和类型一致&#xff0c;类名首字母要大写&#xff0c;例如&#xff1a;MyClass注释-Commonts Java 注释&#xff08;Java Comments&#xff09;&#xff0c;单行注释 //&#xff0c;在 // 至当前行行位之间的内容&#xff0c;都会被忽略多行注释&#xff…

第一节、oracle的安装及数据库和表的创建,知识整理

1.1oracle安装省略 2.1sql*plus连接数据库 进入dos界面输入“c:\sqlplus /nolog” SQL>conn system/orclorclDB SQL>select * from scott.emp; 连接指定数据库&#xff1a;sqlplus username/passwordhost:port/sid 在进入sql*plus之后&#xff0c;可以使用conn连接到其他…

用客户端写博客(包括51CTO博客)

最近觉得在不同网站的博客管理发布很麻烦&#xff0c;于是想找一种快速写博客的办法在好几个博客同时发布文章&#xff1a; 1。先说用客户端在51CTO发布博文吧&#xff1a;因为51客服的博客上已经写得很详细了&#xff0c;我就不再重写了直接转过来&#xff0c;关键是这之后的…