小工具      在线工具  汉语词典  css  js  c++  java

Java 代码中的全局异常处理

Java 额外说明

收录于:42天前

我最近接手了一个新项目。我在写用例的时候,翻了一下代码,发现有些代码缺乏基本的异常处理,包括参数异常和业务异常的处理。我根据自己负责的在异常处理方面比较好的项目,提出了一些开发建议。我也翻阅了之前项目的代码,整理了常用的异常处理方法。

1 Java异常分类


Java把异常当做对象来处理。Throwable是所有错误或异常的超类。Throwable类有两个直接子类:Error类和Exception类。
1、Error是指java运行时系统的内部错误和资源耗尽错误,是程序无法处理的异常,应用程序不会抛出该类对象。
2、Exception是程序本身可以处理的异常,应尽可能去处理这些异常。Exception分两类,一个是运行时异常RuntimeException,一个是检查异常CheckedException。
3、CheckedException一般是外部错误,这种异常都发生在编译阶段,Java编译器会强制程序去捕获此类异常。
4、RuntimeException是那些可能在Java 虚拟机正常运行期间抛出的异常的超类。这种错误是由程序员引起的错误,可以修正代码解决。

2 用@ControllerAdvice+@ExceptionHandler实现全局异常处理

通常在Controller层需要去捕获service层的异常,防止返回一些不友好的错误信息到客户端,但如果Controller层每个方法都用模块化的try-catch代码去捕获异常,会很难看也难维护。
异常处理最好是解耦的,并且都放在一个地方集中管理。Spring能够较好的处理这种问题,核心如下,这里主要关注前两个:
@ExceptionHandler:统一处理某一类异常,从而能够减少代码重复率和复杂度
@ControllerAdvice:异常集中处理,更好的使业务逻辑与异常处理剥离开
@ResponseStatus:可以将某种异常映射为HTTP状态码

单使用@ExceptionHandler,只能在当前Controller中处理异常,与@ControllerAdvice组合使用,则可以实现全局异常处理,不用每个controller都配置。

2.1 全局异常处理类

下面通过一个实际项目代码来看一下@ControllerAdvice+@ExceptionHandler的使用。
@ControllerAdvice定义全局异常处理类GlobalExceptionHandler
@ExceptionHandler声明异常处理方法,使用value指定异常类,value = Exception.class表示处理Controller层抛出的Exception及其子类的异常,这样Controller层代码就不需要进行异常处理了。

GlobalExceptionHandler 类处理多个异常。这些例外分为两类。一种是自定义异常,如 AuthenticationException、BadRequestException,另一种是非自定义异常,如 HttpRequestMethodNotSupportedException、TypeMismatchException 等。

2.2 自定义异常

一般项目中都会出现一些业务相关的(非JVM抛出的)异常。可以使用自定义异常继承相关异常来抛出有用的异常信息。类名应该体现具体的异常信息,这样根据异常名称,就可以知道哪里有异常,并根据异常提示信息进行程序修改。例如遇到NullPointException,可以抛出“xxx is null”的消息来定位异常位置,而不输出堆栈信息。

自定义异常通常定义一个继承自Exception类的子类。一般情况下,它直接继承自Exception类,而不是继承运行时异常类。

下面是项目代码中自定义异常的使用。
定义自定义异常类AuthenticationException,继承Exception类:


在Service层抛出AuthenticationException:

2.3 数据验证异常处理

代码中可以使用@RequestBody+@Valid进行数据绑定和数据校验。
下面是项目代码中对Post请求表单的处理,通过@RequestBody将请求body中的json与表单对象(CreateOrderRequestVO)绑定,使用@Valid进行表单验证。如果不使用@Valid,CreateOrderRequestVO中的@NotNull等注解不生效。

在表单对象CreateOrderRequestVO类的相应字段上添加用于充当校验条件的注解(@NotNull@NotBlank@Min等)。

当数据验证失败时,Spring MVC框架会抛出MethodArgumentNotValidException异常。通过在GlobalExceptionHandler中添加MethodArgumentNotValidException异常的声明和处理,可以全局处理数据验证异常。

概括

本文主要根据项目代码,对全局统一异常处理进行总结和总结。这种异常处理方式将异常处理与业务代码解耦,实现异常信息的统一处理和维护,减少模板代码,提升代码风格。

在日常测试中,有意识地多了解开发代码中写得好的部分,在以后的代码编写中不断为自己积累经验,并及时对开发的代码提出一些建议。

以上转自:https://testerhome.com/topics/12058

附录我公司全局异常处理类

package api.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import api.framework.dto.Result;
import api.framework.exception.ServiceException;

/**
 * 全局异常处理器,处理新增的异常,对于有特殊逻辑的返回直接定义个新方法,参考ServiceException
 */
@ControllerAdvice
@Component
@ResponseBody
public class GlobalExceptionHandler {
	
	private final static Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);
	
	@ExceptionHandler(ServiceException.class)
	public Result<String> handlerServiceException(ServiceException e){
        return new Result<String>("error", e.getMessage(), "", "", e.getCode());
	}
	

	@ExceptionHandler(Exception.class)
	public Result<String> handlerException(Exception e){
		LOGGER.error("Oops", e);
        return new Result<String>("error", "网络异常", "", "", "500");
	}
}
package api.framework.exception;

/**
 * <p>
 * 业务异常,这里约定每个业务场景的错误都是有一个错误码的。
 * </p>
 * <p>
 * 这个错误码需要展示给前端。前端需要根据这个码值做一些特殊的判断。如余额不足,
 * 错误码 001,那么前端根据这个码值引导用户去充值页面。
 * <p>
 */
public class ServiceException extends RuntimeException{

	private static final long serialVersionUID = 228211L;
	
	private String code;
	
	/**
	 * 构造一个业务异常类
	 * 
	 * @param code 错误码,注意约定的业务错误码都是大于600的
	 * @param message 错误信息
	 */
	public ServiceException(String code, String message){
		super(message);
		this.code = code;
	}

	/**
	 * 返回错误码
	 * @return 错误码
	 */
	public String getCode() {
		return code;
	}
}

. . .

相关推荐

额外说明

canvas学习(十一):阴影

使用canvas绘制为图形添加阴影比较简单,主要是四个方法: shadowColor:设置阴影颜色   shadowOffsetX:设置图形与阴影的水平距离,也是水平偏移量。当shadowOffsetX=0时,表示阴影位于形状的正下方,shadowOff

额外说明

MyEclipse8.6安装Spket插件

1、从http://www.spket.com/download.html下载spket插件:spket-1.6.23.jar,该插件用于ExtJs代码编写以及提示。如图: 下载ExtJs的API:ext-4.0.2a-commercial.zip。如图

额外说明

JSP之四大作用域(pageContext,request,session,application)

JSP的四大作用域的存储和获取数据的方式一样,差别在于取值的范围不同。 四大域各自作用范围为: pageContext:当前JSP页面有效 request:请求有效 session:会话有效(关闭浏览器则失效) application:整个Web应用有效

额外说明

计算机网络——校园网端口流量passby分析

合伙创业、商业需求 Q:1274510382 热点登陆认证 一般 没有认证登陆 访问HTTP网站时候 请求会被拦截 并转跳到热点 但是 直接访问 https 响应超时 —> 可能 与 SSL加密和第三方认证有关 而且有些 UDP开放 ---->鉴

额外说明

Linux组合键

1.终止当前进程进行 Ctrl + C 2.键盘输入结束 Ctrl + D 3.清空当前终端中已有内容(清屏) Ctrl + L 或者clear

额外说明

Unity3d:读取FBX中的动画

从模型中获得切割好的动画clip,并且对其中设置好的动画事件进行修改方法: 1.动画模型后缀为.FBX.在Unity3d中,能够显示FBX中的动画。要加载模型中的AnimationClip,只要AssetDatabase.LoadAssetsAtPath

额外说明

shell编程(一) : [Linux基础] 基本Linux命令行

你学shell干嘛? 一个脚本就完事了,省出来的时间可以躺在病床上思考人生。 零、一样的开始 就像大多数文章介绍一样,要从它的历史开始,本文也例行公事介绍一下Linux和shell的历史。 Linux系统是Linus Torvalds在赫尔辛基大学上学时

额外说明

The type List is not generic; it cannot be parameterized with arguments <User>

导错包 import java.awt.List;是错误的 应导入import java.until.List;

额外说明

【Java 基础篇】Java Lambda表达式详解

Lambda表达式是Java编程语言中引入的一个强大的特性,它使得编写更加简洁、可读性更强的代码变得更容易。本文将详细介绍Lambda表达式的概念、语法、用法以及示例,以帮助基础的Java开发者理解和应用Lambda表达式。 什么是Lambda表达式 L

额外说明

PTA基础编程题目集 6-7 统计某类完全平方数

本题要求实现一个函数,判断任一给定整数N是否满足条件:它是完全平方数,又至少有两位数字相同,如144、676等。 函数接口定义: int IsTheNumber ( const int N ); 其中N是用户传入的参数。如果N满足条件,则该函数必须返回

ads via 小工具