异常分类,异常处理,全局异常拦截

什么是异常:

如果某个方法不能按照正常的途径完成执行,就可以通过另一种路径退出方法(异常拦截)。在这种情况下会抛出一个封装了错误信息的对象(异常对象)。
异常就是编译和运行时出现的一些错误,Java语言把一些常见的问题封装成了对象。比如ArrayIndexOutofBoundsException,封装了一些错误错的原因,以及其他的一些异常信息

异常的分类:

异常的根类: Throwable

异常的子类: Error (严重错误,无法解决)

编译时异常:Execption (可以通过代码控制解决)

Error:

Error是throwable的子类,他是程序出现严重的问题,这种问题程序解决不了。
如:因为内存溢出或没有可用的内存提供给垃圾回收器时,java虚拟机无法分配一个对象,这时抛出该异常。

Execption:

Exception 又有两个细分 ,一个是运行时异常 RuntimeException , 一 个是检查异常 CheckedException。

RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。 如果出现 RuntimeException,那么一定是程序员代码书写导致的错误.

CheckedException:一般是外部错误,这种异常都发生在编译阶段,Java 编译器会强制程序去捕获此类异常,即会出现要求你把这段可能出现异常的程序进行 try catch

异常处理:

第一种方式try/catch拦截
try{
    xxxxxxxxxx
    xxxxxx
//检测到代码异常,直接进入到catch
}catch(Exception e){
	syso(异常原因:e.getMessage())
	//相关处理
}
第二种方式多异常处理
多异常处理针对复杂代码,在不确定可能抛出异常具体类型的情况下,通过多个catch拦截
注意最大的异常要放在最下面.
try{
    xxxxxxxxxx
    xxxxxx
//检测到代码异常,直接进入到catch
}catch(Exception e){
	syso(异常原因:e.getMessage())
	//相关处理
}catch(Exception e2){
	syso(异常原因:e2.getMessage())
	//相关处理
}catch (Exception e3){
	syso(异常原因:e3.getMessage())
	//相关处理
}
finaly使用
注意:如果finaly同时存在return,先执行finaly在执行return返回
try{
    xxxxxxxxxx
    xxxxxx
//检测到代码异常,直接进入到catch
}catch(Exception e){
	syso(异常原因:e.getMessage())
	//相关处理
}catch(Exception e2){
	syso(异常原因:e2.getMessage())
	//相关处理
}catch (Exception e3){
	syso(异常原因:e3.getMessage())
	//相关处理
} finaly{
	//相关处理
}

抛出异常有三种形式,

throw 和 throws,还有一种系统自动抛异常。

  • throws :抛出异常,在方法声明上,后面跟异常类 示例: throws Exception
  • thorw: 抛出异常在方法体中,后面跟异常对象, 示例: throw new
    SQLIntegrityConstraintViolationException(“单位信息导入模板数据错误,在第” + index + “条记录的企业唯一数据重复!”);
  • 如果异常不进行拦截:
    如果代码中异常不进行try/catch拦截,没有手动抛出,系统会自动把代码抛给方法调用者,这是不允许的,所以合理的异常拦截和处理是非常有必要的.

自定义全局异常拦截

异常示例
	try {
				companyService.insertSelective(com); //新增数据
			} catch (Exception e) { //拦截异常
				String errMsg = e.getMessage();
				//判断异常类型为违反唯一索引异常
				if (StringUtils.isNotBlank(errMsg) && "java.sql.SQLIntegrityConstraintViolationException"
						.equals(e.getCause().getClass().getName())) {
					// 通过throw抛出数据库唯一索引异常,并指定异常内容
					throw new SQLIntegrityConstraintViolationException("单位信息导入模板数据错误,在第" + index + "条记录的企业唯一数据重复!");
				}
				// 抛出大异常Exception
				throw e;
			}
全局异常拦截示例
### @ExceptionHandler 异常处理器:拦截指定异常,在{}花括号内可以同时存在多个异常,中间用逗号分隔
/**
 * shiro 全局异常处理 Controller继承BaseController公共异常类,在抛出异常时会拦截异常处理器
 * 
 * @ExceptionHandler 全局异常处理器
 *                   登录认证异常:UnauthenticatedException,AuthenticationException
 *                   权限认证异常:UnauthorizedException,AuthorizationException
 * @author 张江丰
 *
 */
@Component
public class BaseController {
	/**
	 * 登录认证异常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	// @ExceptionHandler({ UnauthenticatedException.class,
	// AuthenticationException.class })
	@ExceptionHandler({ UnauthenticatedException.class })
	public String authenticationException(HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> map = new HashMap<>();
		map.put("status", "-1000");
		map.put("message", "未登录");
		writeJson(map, response);
		return null;
	}

	/**
	 * 拦截数据库唯一索引异常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@ExceptionHandler({ SQLIntegrityConstraintViolationException.class })
	public void SQLIntegrityConstraintViolationException(HttpServletRequest request, HttpServletResponse response,
			SQLIntegrityConstraintViolationException sql) {
		String path = request.getServletPath();
		System.out.println("====================请求路径:" + path + ";拦截数据库唯一索引错误提示信息:" + sql.getMessage());
		Map<String, Object> map = new HashMap<>();
		if (path.contains("readExcel")) {
			// 导入信息报错
			map.put("code", "-1001");
			//手动throw抛出数据库唯一索引异常,和异常内容
			map.put("msg", sql.getMessage());
		} else {
			map.put("code", "-1001");
			map.put("msg", "新增信息失败,存在唯一数据重复!");
		}
		writeJson(map, response);
	}

	/**
	 * 拦截运行时异常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@ExceptionHandler({ RuntimeException.class })
	public void RuntimeException(HttpServletRequest request, HttpServletResponse response, RuntimeException re) {
		Map<String, Object> map = new HashMap<>();
		String path = request.getServletPath();
		System.out.println("====================全局运行时异常,请求路径:" + path + ";错误提示信息:" + re.getMessage());
		// 其它运行时异常
		map.put("code", "-1001");
		map.put("msg", "信息错误,请联系管理员!");
		writeJson(map, response);
	}

	/**
	 * 权限异常
	 * 
	 * @param request
	 * @param response
	 * @return
	 */
	@ExceptionHandler({ UnauthorizedException.class, AuthorizationException.class })
	public void authorizationException(HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> map = new HashMap<>();
		map.put("code", "-1001");
		map.put("msg", "无操作权限");
		writeJson(map, response);
	}

	private void writeJson(Map<String, Object> map, HttpServletResponse response) {
		// 字符打印流
		PrintWriter out = null;
		try {
			response.setCharacterEncoding("UTF-8");
			response.setContentType("application/json; charset=utf-8");
			out = response.getWriter();
			JSONObject mapJson = JSONObject.fromObject(map);
			String string = mapJson.toString();
			out.write(string);
		} catch (IOException e) {
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}

}

发布了32 篇原创文章 · 获赞 53 · 访问量 2494

猜你喜欢

转载自blog.csdn.net/qq_41714882/article/details/103776983