0
点赞
收藏
分享

微信扫一扫

SpringBoot学习-(二十一)SpringBoot异常统一处理


SpringBoot自带的异常处理

SpringBoot默认返回的异常信息

{
"timestamp": 1517369509468,
"status": 500,
"error": "Internal Server Error",
"exception": "java.lang.IndexOutOfBoundsException",
"message": "No message available",
"path": "/v1/users/"}

实现ErrorController接口

SpringBoot中自带的ErrorController接口,源码如下

/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.boot.autoconfigure.web;

import org.springframework.stereotype.Controller;

/**
* Marker interface used to indicate that a {@link Controller @Controller} is used to
* render errors. Primarily used to know the error paths that will not need to be secured.
*
* @author
public interface ErrorController

/**
* Returns the path of the error page.
* @return

这个接口有一个子类,AbstractErrorController
AbstractErrorController有一个子类BasicErrorController,SpringBoot自带的异常处理信息就是由BasicErrorController返回的

参考BasicErrorController,自定义异常处理

package com.ahut.action;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
*
* @ClassName: ErrorAction
* @Description:异常处理控制层
* @author cheng
* @date
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class ErrorAction implements ErrorController

/**
* 复写接口中的方法
*/
@Override
public String getErrorPath() {
return "/error";
}

/**
*
* @Title: error
* @Description: 自定义异常处理
* @param request
* @return
@RequestMapping
@ResponseBody
public Map<String, Object> error(HttpServletRequest request) {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("userName", "rick");
returnMap.put("thing", "新增用户");
returnMap.put("desc", "自定义异常处理");
return

异常返回

{
"userName": "rick",
"thing": "新增用户",
"desc": "自定义异常处理"}

使用@ExceptionHandler 注解

单一的Controller异常处理
直接在对应的 Controller 里面增加一个异常处理的方法,并使用 @ExceptionHandler 标识它即可。

/**
*
* @Title: error
* @Description: 异常处理
* @param request
* @return
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<String, Object> error() {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("userName", "cheng");
returnMap.put("thing", "用户控制层异常");
returnMap.put("desc", "自定义异常处理");
return

异常处理

{
"userName": "cheng",
"thing": "用户控制层异常",
"desc": "自定义异常处理"}

父级 Controller 异常处理
定义父级controller
需要异常处理的controller需要继承父类

package com.ahut.action;

import java.util.HashMap;
import java.util.Map;

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

/**
*
* @ClassName: BaseAction
* @Description:父级action
* @author cheng
* @date
public class BaseAction

/**
*
* @Title: error
* @Description: 异常处理
* @param request
* @return
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<String, Object> error() {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("userName", "cheng");
returnMap.put("thing", "父级控制层处理异常");
returnMap.put("desc", "自定义异常处理");
return

异常处理

{
"userName": "cheng",
"thing": "父级控制层处理异常",
"desc": "自定义异常处理"}

ErrorAction和BaseAction的区别

  • ErrorAction: 调用的action抛出异常时,自身没有做任何处理,所以会打印出堆栈信息,但这个异常会被 Servlet 容器捕捉到,Servlet 容器再将请求转发给注册好的异常处理映射 /error 做处理,客户端收到的实际是 ErrorAction的处理结果,而不是 调用的action的。
  • BaseAction: 异常的处理方法直接被定义在调用action里面,也就是说,在异常抛出的时候,action会使用自己的方法去做异常处理,而不会抛出给 Servlet 容器,所以这个地方没有打印堆栈信息。

如果需要打印异常信息,将该异常作为一个参数传递给异常处理方法,然后在处理方法里面做相应的操作即可,代码如下

/**
*
* @Title: error
* @Description: 异常处理
* @param request
* @return
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<String, Object> error(Exception e) {
e.printStackTrace();
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("userName", "cheng");
returnMap.put("thing", "父级控制层处理异常");
returnMap.put("desc", "自定义异常处理");
return

advice异常处理
解除耦合,不需要继承
使用@ControllerAdvice注解

package com.ahut.action;

import java.util.HashMap;
import java.util.Map;

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

/**
*
* @ClassName: ErrorActionAdvice
* @Description:advice异常处理
* @author cheng
* @date
@ControllerAdvice
public class ErrorActionAdvice

/**
*
* @Title: error
* @Description: 异常处理
* @param request
* @return
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<String, Object> error() {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("userName", "cheng");
returnMap.put("thing", "advice处理异常");
returnMap.put("desc", "自定义异常处理");
return

异常处理

{
"userName": "cheng",
"thing": "advice处理异常",
"desc": "自定义异常处理"}

多类别异常处理(推荐)

实际的开发场景中,异常是区分很多类别的,不同类别的异常需要给用户不同的反馈。

使用@ControllerAdvice注解时,可以精确处理各种异常类型

package com.ahut.action;

import java.util.HashMap;
import java.util.Map;

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

/**
*
* @ClassName: ErrorActionAdvice
* @Description:advice异常处理
* @author cheng
* @date
@ControllerAdvice
public class ErrorActionAdvice

/**
*
* @Title: error
* @Description: 异常处理
* @param request
* @return
@ExceptionHandler(Exception.class)
@ResponseBody
public Map<String, Object> error1() {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("userName", "cheng");
returnMap.put("thing", "Exception类型异常处理");
returnMap.put("desc", "自定义异常处理");
return returnMap;
}

/**
*
* @Title: error
* @Description: 异常处理
* @param request
* @return
@ExceptionHandler(IndexOutOfBoundsException.class)
@ResponseBody
public Map<String, Object> error2() {
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("userName", "cheng");
returnMap.put("thing", "IndexOutOfBoundsException类型异常处理");
returnMap.put("desc", "自定义异常处理");
return

当程序发生IndexOutOfBoundsException类型异常时,会精确匹配到该方法,异常处理如下

{
"userName": "cheng",
"thing": "IndexOutOfBoundsException类型异常处理",
"desc": "自定义异常处理"}


举报

相关推荐

0 条评论