在项目中经常出现系统异常的情况,比如NullPointerException等等。如果默认未处理的情况下,springboot会响应默认的错误提示,这样对用户体验不是友好,系统层面的错误,用户不能感知到,即使为500的错误,可以给用户提示一个类似服务器开小差的友好提示等。
异常发生,而我们又没有及时处理,这是也可以通过全局异常处理机制,记录异常信息并格式化异常信息返回给客户端,让客户端知道,服务器出现了异常,可以根据情况给用户相应的提示。
@ControllerAdvice
public class GlobalExceptionHandler {
//空指针异常
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public String nullPointerExceptionHandler(NullPointerException ex) {
ex.printStackTrace();
return "NullPointerException捕获了";
}
//类型转换异常
@ExceptionHandler(ClassCastException.class)
@ResponseBody
public String classCastExceptionHandler(ClassCastException ex) {
ex.printStackTrace();
return "ClassCastException捕获了";
}
//IO异常
@ExceptionHandler(IOException.class)
@ResponseBody
public String iOExceptionHandler(IOException ex) {
ex.printStackTrace();
return "IOException捕获了";
}
}
@ControllerAdvice
修改controller,增加产生异常接口,代码如下:
@RequestMapping(value = "/runerr")
public String runError(Model model) {
System.out.println("runError .......");
String msg = null;
if(msg.length()>0)
System.out.println("hello world");
return "index";
}
有一些系统异常,通过之前的方法,还是无法捕获的,比如经常出现的404错误。那么这种错误怎么捕获呢?可以分为以下几个步骤:
修改配置文件application.properties的内容如下:
# 出现错误时, 直接抛出异常(便于异常统一处理,否则捕获不到404)
spring.mvc.throw-exception-if-no-handler-found=true
# 是否开启默认的资源处理,默认为true
spring.resources.add-mappings=false
上述配置在SpringBoot 2.5.x以后过时了,需要使用一下配置
# 出现错误时, 直接抛出异常(便于异常统一处理,否则捕获不到404)
spring.mvc.throw-exception-if-no-handler-found=true
# 是否开启默认的资源处理,默认为true
spring.web.resources.add-mappings=false
package com.shenmazong.shenmablogserver.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
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.client.HttpServerErrorException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import java.io.IOException;
/**
* @Description: 全局异常
* @Author david
* @Date 2021/5/3 16:55
* @Copyright www.shenmazong.com
* @Version V1.0.0
*/
@Slf4j
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(Exception.class)
public ModelAndView customException(Exception ex) {
ex.printStackTrace();
ModelAndView mv = new ModelAndView();
mv.addObject("message", ex.getMessage());
mv.setViewName("page_error");
return mv;
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.class)
public String handle404(Exception ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "您访问的页面不存在!");
return "page_error";
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(HttpServerErrorException.InternalServerError.class)
public String handle500(Exception ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "服务器内部错误!");
return "page_error";
}
//运行时异常
@ExceptionHandler(RuntimeException.class)
public String runtimeExceptionHandler(RuntimeException ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "运行时发生错误!");
return "page_error";
}
//空指针异常
@ExceptionHandler(NullPointerException.class)
public String nullPointerExceptionHandler(NullPointerException ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "空指针错误!");
return "page_error";
}
//类型转换异常
@ExceptionHandler(ClassCastException.class)
public String classCastExceptionHandler(ClassCastException ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "类型转换错误!");
return "page_error";
}
//IO异常
@ExceptionHandler(IOException.class)
public String iOExceptionHandler(IOException ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "IO错误!");
return "page_error";
}
//未知方法异常
@ExceptionHandler(NoSuchMethodException.class)
public String noSuchMethodExceptionHandler(NoSuchMethodException ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "未知方法错误!");
return "page_error";
}
//数组越界异常
@ExceptionHandler(IndexOutOfBoundsException.class)
public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex, Model model) {
ex.printStackTrace();
model.addAttribute("message", "数组越界错误!");
return "page_error";
}
}
全局异常主要注解:
@ExceptionHandler(NoHandlerFoundException.class)
@ExceptionHandler(value = NullPointerException.class)