一.说明
1.1 异常处理的5种方式
1.自定义错误页面
2.使用注解@ExeceptionHandler
3.使用@ControllerAdvice+@HadlerException 实现全局异常的处理
4.使用SimpleMappingExceptionResult全局异常处理类
5.使用HandlerExceptionResolver自定义全局处理异常类
1.2 全局异常设置@ControllerAdvice+@ExceptionHandler
通过注解@ControllerAdvice 定义一个处理全局 异常的类,在需要捕捉异常的方法上加上@ExceptionHandler(value=Exception.class)这个注解。
@ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody
如下图
二 案例操作
2.1 执行逻辑
配置一个检测异常的全局类,发生异常时,根据配置的code,msg,url等信息,以json串的形式,返回的前端,进行友好的提示。
2.2 项目的结构
2.3 搭建项目
2.3.1 pom文件
<!-- springBoot 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
package com.ljf.spring.boot.demo.controller;
import com.ljf.spring.boot.demo.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Date;
/**
* @ClassName: UserController
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/03/26 11:24:40
* @Version: V1.0
**/
@Controller
public class UserController {
@RequestMapping("/showUser")
@ResponseBody
public Object showUser(Model model){
System.out.println("controller进来了");
//int k=5/0;
return new User(11, "sfsfds", "1000000", new Date());
}
}
2.3.2 model
package com.ljf.spring.boot.demo.model;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
public class User {
private int age;
@JsonIgnore
private String pwd;
@JsonProperty("account")
@JsonInclude(Include.NON_NULL)
private String phone;
@JsonFormat(pattern="yyyy-MM-dd hh:mm:ss",locale="zh",timezone="GMT+8")
private Date createTime;
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public User() {
super();
}
public User(int age, String pwd, String phone, Date createTime) {
super();
this.age = age;
this.pwd = pwd;
this.createTime = createTime;
}
}
2.3.3 启动类
package com.ljf.spring.boot.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
System.out.println( "Hello World!" );
}
}
2.4 正常访问
2.4.1 启动访问
ok,通过这样访问没有问题。
2.5 方法一:springboot默认异常处理
在controller,设置int k/0,让程序报错,springboot,会给出一个空白页提示出现错误,不太友好,如下图
2.6 方法二:使用@ControllerAdvice+@HadlerException 实现全局异常的处理
2.6.1 定义一个处理异常的类
package com.ljf.spring.boot.demo.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: CustomerException
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/03/26 11:39:01
* @Version: V1.0
**/
@RestControllerAdvice //@ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody
public class CustomerException {
private static final Logger LOG = LoggerFactory.getLogger(CustomerException.class);
//捕获全局异常,处理所有不可知的异常
@ExceptionHandler(value=Exception.class)
Object handleException(Exception e, HttpServletRequest request){
LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
Map<String, Object> map = new HashMap<>();
map.put("code", 400);
map.put("msg", "错误信息如下:"+e.getMessage());
map.put("url", "请求地址:"+request.getRequestURL());
return map;
}
}
2.6.2 再次访问
实现了我们想要的结果,返回错误信息的提示。
2.6.3 根据不同异常,返回不同提示信息
1.controller类:
2.全局异常类:
package com.ljf.spring.boot.demo.exception;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName: CustomerException
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/03/26 11:39:01
* @Version: V1.0
**/
@RestControllerAdvice //@ControllerAdvice 如果是返回json数据 则用 RestControllerAdvice,就可以不加 @ResponseBody
public class CustomerException {
private static final Logger LOG = LoggerFactory.getLogger(CustomerException.class);
//捕获全局异常,处理所有不可知的异常
@ExceptionHandler(value=Exception.class)
Object handleException(Exception e, HttpServletRequest request){
LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
Map<String, Object> map = new HashMap<>();
map.put("code", 400);
map.put("msg", "错误信息如下:"+e.getMessage());
map.put("url", "请求地址:"+request.getRequestURL());
return map;
}
/**
* java.lang.ArithmeticException
* 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
* 参数Exception e:会将产生异常对象注入到方法中
*/
@ExceptionHandler(value={java.lang.ArithmeticException.class})
public Object arithmeticExceptionHandler(Exception e,HttpServletRequest request){
LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
Map<String, Object> map = new HashMap<>();
map.put("code", 401);
map.put("msg", "错误信息如下:"+e.getMessage());
map.put("url", "请求地址:"+request.getRequestURL());
return map;
}
/**
* java.lang.NullPointerException
* 该方法需要返回一个ModelAndView:目的是可以让我们封装异常信息以及视图的指定
* 参数Exception e:会将产生异常对象注入到方法中
*/
@ExceptionHandler(value={java.lang.NullPointerException.class})
public Object nullPointerExceptionHandler(Exception e,HttpServletRequest request){
LOG.error("url {}, msg {}",request.getRequestURL(), e.getMessage());
Map<String, Object> map = new HashMap<>();
map.put("code", 402);
map.put("msg", "错误信息如下:"+e.getMessage());
map.put("url", "请求地址:"+request.getRequestURL());
return map;
}
}
2.6.4 再次访问
算术异常:
空指针异常:
2.6 方法三:使用@SimpleMappingExceptionResolver实现全局异常的处理
2.6.1 controller类
package com.ljf.spring.boot.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* @ClassName: ExceptionController
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/03/07 12:07:43
* @Version: V1.0
**/
@Controller
public class ExceptionController {
@RequestMapping("/show")
public String showInfo(){
String str = null;
str.length();
return "index";
}
@RequestMapping("/show2")
public String showInfo2(){
int a = 10/0;
return "index";
}
}
2.6.2 定义全局异常处理类
package com.ljf.spring.boot.demo.exception;
/**
* @ClassName: GlobalException
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/03/27 11:15:18
* @Version: V1.0
**/
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import java.util.Properties;
/**
* 通过SimpleMappingExceptionResolver做全局异常处理
*
*
*/
@Configuration
public class GlobalException {
/**
* 该方法必须要有返回值。返回值类型必须是:SimpleMappingExceptionResolver
*/
@Bean
public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
/**
* 参数一:异常的类型,注意必须是异常类型的全名
* 参数二:视图名称
*/
mappings.put("java.lang.ArithmeticException", "error-kong");
mappings.put("java.lang.NullPointerException","error-sushu");
//设置异常与视图映射信息的
resolver.setExceptionMappings(mappings);
return resolver;
}
}
2.6.3 定义页面
1.error-kong页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>出现空指针异常......<span th:text="${exception}"></span></h1>
</body>
</html>
2.error-sushu页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>出现算术异常了!!!!<span th:text="${exception}"></span></h1>
</body>
</html>
2.6.4 页面访问
1.算术异常
2.空指针异常
2.7 方法四:自定义HandlerExceptionResolver实现处理异常
2.7.1 编写自定义的全局异常处理类
执行的时候,将之前编写的全局异常处理类,进行注释掉
package com.ljf.spring.boot.demo.exception;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName: GloabalExceptionByDefine
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/03/27 12:12:32
* @Version: V1.0
**/
@Configuration
public class GloabalExceptionByDefine implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
ModelAndView mv = new ModelAndView();
//判断不同异常类型,做不同视图跳转
if(ex instanceof ArithmeticException){
mv.setViewName("error-kong");
}
if(ex instanceof NullPointerException){
mv.setViewName("error-sushu");
}
mv.addObject("exception", ex.toString());
return mv;
}
}
2.7.2 访问
1.算术异常
2.空指针异常