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

在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);

}

}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/398126.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

hibernate select语句返回的类型

2019独角兽企业重金招聘Python工程师标准>>> Person类中包含有MyEvent这个类 public class Person{private Long id;private String name;private MyEvent myEvent; } 一、HQL from语句 1、结果类型&#xff1a;List<Person> from Person 或者 from Person…

RDLC系列之五 初试XAML

本章只讲解xaml部分&#xff0c;其余都和winform下一样 1.xaml代码 <Window x:Class"RDLC.WPF.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:r…

thinkphp内置标签简单讲解

thinkphp内置标签简单讲解 1、volist循环 name 需要遍历的数据 id 类似于foreach中 value offset 截取数据起始位置 length 截取数据的个数 mod 奇偶数 empty 数据为空的使用 key 编号 2、foreach循环 name 需要遍历的数据 item 类似于foreach中的value key 类似于foreach中的k…

hashcode java_java 的Object类的hashcode()方法具体是怎么实现的?

轻松解说Object.hashcode()的实现&#xff0c;让你看着不累&#xff01;intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {// 如果启用偏向锁if (UseBiasedLocking) {// NOTE: many places throughout the JVM do not expect a safepoint// to be taken h…

Android 数据库升级解决方案

转自&#xff1a;http://blog.csdn.net/leehong2005/article/details/9128501 请考虑如下情况&#xff1a; 在数据库升级时&#xff0c;不同版本的数据库&#xff0c;他们定义的表结构完全可能是不一样的&#xff0c;比如V1.0的表A有10个column&#xff0c;而在V1.1的表A有12个…

区间素数筛法

给定整数a和b&#xff0c;请问区间[a,b)内有多少个素数&#xff1f; a<b<10^12 b-a<10^6 因为b以内合数的最小质因数一定不超过sqrt(b),如果有sqrt(b)以内的素数表的话&#xff0c;就可以把筛选法用在[a,b)上了,先分别做好[2,sqrt(b))的表和[a,b)的表&#xff0c;然后…

[php入门] 3、WAMP中的集成MySQL相关基础操作

前言&#xff1a;本文以小白视角了解WAMP集成开发环境中的MYSQL&#xff0c;涉及的面广而浅&#xff0c;算是导读性质。 1、启动运行熟悉WAMP中的MySQL 先有库、再有表、数据最终以记录的形式插入表中。其中对数据进行操作使用SQL语句&#xff0c;SQL是结构化的查询语言。 在wa…

apns java 证书_APNS推送服务证书制作 图文详解教程(新)

iOS消息推送的工作机制可以简单的用下图来概括&#xff1a;Provider是指某个iPhone软件的Push服务器&#xff0c;APNS是Apple Push Notification Service的缩写&#xff0c;是苹果的服务器。上图可以分为三个阶段&#xff1a;第一阶段&#xff1a;应用程序把要发送的消息、目的…

java 凑整_Java语言中的取整运算(包括截尾取整,四舍五入,凑整)? – 日记

import java.math.BigDecimal;import java.text.DecimalFormat;public class TestGetInt{public static void main(String[] args){double i2, j2.1, k2.5, m2.9;System.out.println(”舍掉小数取整:Math.floor(2)” (int)Math.floor(i));System.out.println(”舍掉小数取整:M…

企业员工工资管理系统

企业工资管理是人力资源管理的一个核心环节,在市场经济和全球一体化的大背景下&#xff0c;随着人力资源管理在战略层面上发挥着越来越重要的作用&#xff0c;传统的薪酬制度已于现代化的要求不匹配&#xff0c;并越来越限制着企业的发展。本系统以员工的考勤信息作为基础&…

Android近场通信---NFC基础(二)(转)

转自 http://blog.csdn.net/think_soft/article/details/8171256 应用程序如何调度NFC标签 当标签调度系统完成对NFC标签和它的标识信息封装的Intent对象的创建时&#xff0c;它会把该Intent对象发送给感兴趣的应用程序。如果有多个应用程序能够处理该Intent对象&#xff0c;就…

:base(参数)

:base(必须有值)&#xff1a;作用是将父类的值继承过来&#xff0c;如果不在构造函数中加入&#xff1a;base(变量) 的话&#xff0c;原父类中的 Model则无法继承过来。 例如&#xff1a;在父类MSG_Model,有连个属性&#xff0c;如图 1.子类构造函数不写:base(参数) 2.1.子类构…

如何在{{input}}中使用action

文章来源&#xff1a;Ember Teach 开发中经常遇到需要在一个input输入框触发JS函数&#xff0c;那么对于Ember.js的{{input}}又如何才能出发自定义的action呢&#xff1f; 实现起来非常简单&#xff01;请看下面的代码演示&#xff1a; 旧版本实现方式 {{input type"text&…

java json utf-8_Java 编码 和JSON

1.编码序列化(urlencode编码)&#xff1a;经过urlencode编码String a"[{\"clubNo\":\"10000002\",\"clubType\":\"1\"},{\"clubNo\":\"10000003\",\"clubType\":\"4\"},{\"clubNo\…

MVC5 + EF6 完整入门教程三

MVC5 EF6 完整入门教程三 原文:MVC5 EF6 完整入门教程三期待已久的EF终于来了。 学完本篇文章&#xff0c;你将会掌握基于EF数据模型的完整开发流程。 本次将会完成EF数据模型的搭建和使用。 基于这个模型&#xff0c;将之前的示例添加数据库查询验证功能。 文章提纲 概…

纯手写的css3正方体旋转效果

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>css3旋转立方体效果</title><style type"text/css">*{margin: 0;padding: 0;}.box{width: 400px;height: 400px;border: 1px solid #000;margin: 30p…

Expect 教程中文版

http://blog.csdn.net/chinalinuxzend/article/details/1842588原贴&#xff1a;http://blog.chinaunix.net/u/13329/showart.php?id110100 Expect 教程中文版[From] http://www.linuxeden.com/edu/doctext.php?docid799  本教程由*葫芦娃*翻译&#xff0c;并做…

java boolean转int,java如何将int转换为boolean

When i convert:int B1;boolean AB;It gives error: Incompatible types, which is trueBut when I write this code:int C0;boolean AC1;it gives falsewhile if I change value of C to 1 it gives true.I dont understand how compiler is doing it.解决方案int C0;boolean …

习惯看新闻头条 一个程序员分享的工作心得

原本想找链接的。可是...我还是选择手打 原作者&#xff1a;刘鹏看未来 原文标题 10程序员总结的20条经验教训 开发 1.从小事做起&#xff0c;然后再扩展 无论是创建一个新的系统&#xff0c;还是添加功能到现有的系统中&#xff0c;我总是从一个简单到几乎任何所需功能的版…

Java-JUC(十):线程按序交替执行

问题&#xff1a; 有a、b、c三个线程&#xff0c;使得它们按照abc依次执行10次。 实现&#xff1a; package com.dx.juc.test;import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public…