在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的、不可预知的异常需要处理。每个过程都单独处理异常,系统的代码耦合度高,工作量大且不好统一,维护的工作量也很大。 那么,能不能将所有类型的异常处理从各处理过程解耦出来,这样既保证了相关处理过程的功能较单一,也实现了异常信息的统一处理和维护?答案是肯定的。下面将介绍使用Spring MVC统一处理异常的解决和实现过程

使用Spring MVC提供的SimpleMappingExceptionResolver

实现Spring的异常处理接口HandlerExceptionResolver 自定义自己的异常处理器

使用@ExceptionHandler注解实现异常处理

(一) SimpleMappingExceptionResolver

使用这种方式具有集成简单、有良好的扩展性、对已有代码没有入侵性等优点,但该方法仅能获取到异常信息,若在出现异常时,对需要获取除异常以外的数据的情况不适用。

@Configuration

@EnableWebMvc

@ComponentScan(basePackages = {"com.balbala.mvc.web"})

public class WebMVCConfig extends WebMvcConfigurerAdapter{

@Bean

public SimpleMappingExceptionResolver simpleMappingExceptionResolver()

{

SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver();

Properties mappings = new Properties();

mappings.put("org.springframework.web.servlet.PageNotFound", "page-404");

mappings.put("org.springframework.dao.DataAccessException", "data-access");

mappings.put("org.springframework.transaction.TransactionException", "transaction-Failure");

b.setExceptionMappings(mappings);

return b;

}

}

(二) HandlerExceptionResolver

相比第一种来说,HandlerExceptionResolver能准确显示定义的异常处理页面,达到了统一异常处理的目标

1.定义一个类实现HandlerExceptionResolver接口,这次贴一个自己以前的代码

package com.athena.common.handler;

import com.athena.common.constants.ResponseCode;

import com.athena.common.exception.AthenaException;

import com.athena.common.http.RspMsg;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.servlet.HandlerExceptionResolver;

import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.PrintWriter;

/**

* Created by sam on 15/4/14.

*/

public class GlobalHandlerExceptionResolver implements HandlerExceptionResolver {

private static final Logger LOG = LoggerFactory.getLogger(GlobalHandlerExceptionResolver.class);

/**

* 在这里处理所有得异常信息

*/

@Override

public ModelAndView resolveException(HttpServletRequest req, HttpServletResponse resp, Object o, Exception ex) {

ex.printStackTrace();

if (ex instanceof AthenaException) {

//AthenaException为一个自定义异常

ex.printStackTrace();

printWrite(ex.toString(), resp);

return new ModelAndView();

}

//RspMsg为一个自定义处理异常信息的类

//ResponseCode为一个自定义错误码的接口

RspMsg unknownException = null;

if (ex instanceof NullPointerException) {

unknownException = new RspMsg(ResponseCode.CODE_UNKNOWN, "业务判空异常", null);

} else {

unknownException = new RspMsg(ResponseCode.CODE_UNKNOWN, ex.getMessage(), null); }

printWrite(unknownException.toString(), resp);

return new ModelAndView();

}

/**

* 将错误信息添加到response中

*

* @param msg

* @param response

* @throws IOException

*/

public static void printWrite(String msg, HttpServletResponse response) {

try {

PrintWriter pw = response.getWriter();

pw.write(msg);

pw.flush();

pw.close();

} catch (Exception e) {

e.printStackTrace();

}

}

}

2.加入spring的配置中,这里只贴出了相关部分

import com.athena.common.handler.GlobalHandlerExceptionResolver;

import org.springframework.context.annotation.Bean;

import com.athena.common.handler.GlobalHandlerExceptionResolver;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

/**

* Created by sam on 15/4/14.

*/

public class WebSpringMvcConfig extends WebMvcConfigurerAdapter {

@Bean

public GlobalHandlerExceptionResolver globalHandlerExceptionResolver() {

return new GlobalHandlerExceptionResolver();

}

}

(三)@ExceptionHandler

这是笔者现在项目的使用方式,这里也仅贴出了相关部分

1.首先定义一个父类,实现一些基础的方法

package com.balabala.poet.base.spring;

import com.google.common.base.Throwables;

import com.raiyee.poet.base.exception.MessageException;

import com.raiyee.poet.base.utils.Ajax;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.annotation.AnnotationUtils;

import org.springframework.http.HttpStatus;

import org.springframework.web.bind.annotation.ResponseStatus;

import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.Date;

public class BaseGlobalExceptionHandler {

protected static final Logger logger = null;

protected static final String DEFAULT_ERROR_MESSAGE = "系统忙,请稍后再试";

protected ModelAndView handleError(HttpServletRequest req, HttpServletResponse rsp, Exception e, String viewName, HttpStatus status) throws Exception {

if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null)

throw e;

String errorMsg = e instanceof MessageException ? e.getMessage() : DEFAULT_ERROR_MESSAGE;

String errorStack = Throwables.getStackTraceAsString(e);

getLogger().error("Request: {} raised {}", req.getRequestURI(), errorStack);

if (Ajax.isAjax(req)) {

return handleAjaxError(rsp, errorMsg, status);

}

return handleViewError(req.getRequestURL().toString(), errorStack, errorMsg, viewName);

}

protected ModelAndView handleViewError(String url, String errorStack, String errorMessage, String viewName) {

ModelAndView mav = new ModelAndView();

mav.addObject("exception", errorStack);

mav.addObject("url", url);

mav.addObject("message", errorMessage);

mav.addObject("timestamp", new Date());

mav.setViewName(viewName);

return mav;

}

protected ModelAndView handleAjaxError(HttpServletResponse rsp, String errorMessage, HttpStatus status) throws IOException {

rsp.setCharacterEncoding("UTF-8");

rsp.setStatus(status.value());

PrintWriter writer = rsp.getWriter();

writer.write(errorMessage);

writer.flush();

return null;

}

public Logger getLogger() {

return LoggerFactory.getLogger(BaseGlobalExceptionHandler.class);

}

}

2.针对你需要捕捉的异常实现相对应的处理方式

package com.balabala.poet.base.spring;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.http.HttpStatus;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.bind.annotation.ResponseStatus;

import org.springframework.web.servlet.ModelAndView;

import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

@ControllerAdvice

public class GlobalExceptionHandler extends BaseGlobalExceptionHandler {

//比如404的异常就会被这个方法捕获

@ExceptionHandler(NoHandlerFoundException.class)

@ResponseStatus(HttpStatus.NOT_FOUND)

public ModelAndView handle404Error(HttpServletRequest req, HttpServletResponse rsp, Exception e) throws Exception {

return handleError(req, rsp, e, "error-front", HttpStatus.NOT_FOUND);

}

//500的异常会被这个方法捕获

@ExceptionHandler(Exception.class)

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)

public ModelAndView handleError(HttpServletRequest req, HttpServletResponse rsp, Exception e) throws Exception {

return handleError(req, rsp, e, "error-front", HttpStatus.INTERNAL_SERVER_ERROR);

}

//TODO 你也可以再写一个方法来捕获你的自定义异常

//TRY NOW!!!

@Override

public Logger getLogger() {

return LoggerFactory.getLogger(GlobalExceptionHandler.class);

}

}

以上就三种处理方式,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

java全局异常处理_详解Spring全局异常处理的三种方式相关推荐

  1. Spring框架学习教程,详解Spring注入bean的几种方式

    首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入. 依赖注入是指:让调用类对某一接口的实现类的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Sprin ...

  2. html正方形边框,详解HTML设置边框的三种方式

    HTML设置边框的三种方式 border-width: 1px 2px 2px; border-style: solid dashed dotted; border-color:red green b ...

  3. java按钮权限控制_详解Spring Security 中的四种权限控制方式

    Spring Security 中对于权限控制默认已经提供了很多了,但是,一个优秀的框架必须具备良好的扩展性,恰好,Spring Security 的扩展性就非常棒,我们既可以使用 Spring Se ...

  4. java webmethod 参数_java详解Spring接收web请求参数的方式

    本篇文章给大家带来的内容是java详解Spring接收web请求参数的方式 .有一定的参考价值,有需要的朋友可以参考一下,希望对你们有所帮助. 1 查询参数 请求格式:url?参数1=值1&参 ...

  5. python可以播放音乐吗_详解python播放音频的三种方法

    第一种 使用pygame模块 pygame.mixer.init() pygame.mixer.music.load(self.wav_file) pygame.mixer.music.set_vol ...

  6. python调用cmd命令释放端口_详解python调用cmd命令三种方法

    目前我使用到的python中执行cmd的方式有三种 使用os.system("cmd") 该方法在调用完shell脚本后,返回一个16位的二进制数,低位为杀死所调用脚本的信号号码, ...

  7. mysql临键锁_详解 MySql InnoDB 中的三种行锁(记录锁、间隙锁与临键锁)

    详解 MySql InnoDB 中的三种行锁(记录锁.间隙锁与临键锁) 前言 InnoDB 通过 MVCC 和 NEXT-KEY Locks,解决了在可重复读的事务隔离级别下出现幻读的问题.MVCC  ...

  8. java 定时任务插件_详解Spring整合Quartz实现动态定时任务

    最近项目中需要用到定时任务的功能,虽然spring 也自带了一个轻量级的定时任务实现,但感觉不够灵活,功能也不够强大.在考虑之后,决定整合更为专业的Quartz来实现定时任务功能. 普通定时任务 首先 ...

  9. java batch基础_详解Spring Batch 轻量级批处理框架实践

    实践内容 从 MariaDB 一张表内读 10 万条记录,经处理后写到 MongoDB . 具体实现 1.新建 Spring Boot 应用,依赖如下: org.springframework.boo ...

最新文章

  1. stl algorithm清单
  2. mpc 安全多方计算协议_BNC公链 | 不看到数据却能进行计算?一文了解安全多方计算...
  3. 检测1的个数_冲床电永磁夹紧系统(PMCS),实现1分钟的快速换模~
  4. MySQL统计函数GROUP_CONCAT使用及报错分析
  5. mysql攻城掠地_【图片】攻城掠地单机版本服务端+攻城掠地GM工具【单兆权吧】_百度贴吧...
  6. python rename dataframe,python rename dataframe_python – 重命名Pandas DataFra
  7. 畅通工程---并查集
  8. 2016年度太和顾问北京高科技行业人力资本数据信息发布
  9. Unity3D 制作绿草地,草坪,模型表面生成草地,草地效果Shader实现 草着色器 Brute Force - Grass Shader
  10. 软件测试最牛的8本书籍—你有读过吗?
  11. Twaver-HTML5基础学习(13)连线(Link)连线的绑定与展开
  12. 谷歌又放大招 Disco Diffusion!AI生成超高质量绘画!
  13. openwrt新3路由lede动态dns如何使用,阿里云ddns+ipv6
  14. 初学RabbitMQ(三),了解回调函数,并手动确认消息进行消费
  15. 【分享】ArcGIS实现分子分母等标注实用技巧
  16. 【毕业季·进击的技术er】青春不散场 恰同学少年
  17. ubuntu安装和使用labellmg(含pyqt4的安装教程)
  18. windows连接的蓝牙设备(如小爱同学),无法调节音量
  19. 基于机器学习中集成学习的stacking方式进行的金线莲质量鉴别研究(python进行数据处理并完成建模,对品种进行预测)
  20. 基于Python的JS逆向和AST抽象语法树

热门文章

  1. 12-1 12 防盗链 访问控制 php解析 代理
  2. 《Nmap渗透测试指南》—第7章7.8节后台打印机服务漏洞
  3. Cntlm安装和配置心得
  4. Node.jsNPM的安装与配置(转)
  5. Linux下Socket网络编程
  6. opencv (一) 学习通过OpenCV图形界面及基础
  7. VMware文件共享
  8. leetcode 477. 汉明距离总和(位运算)
  9. leetcode 665. 非递减数列(贪心算法)
  10. leetcode面试题 10.05. 稀疏数组搜索(二分法)