前言:
大家好,我是良辰丫,在上一篇文章中我们已经学习了一些统一功能处理的相关知识,今天我们继续深入学习这些知识,主要学习统一异常处理,统一的返回格式,@ControllerAdvice简单分析.💌💌💌
🧑个人主页:良辰针不戳
📖所属专栏:javaEE进阶篇之框架学习
🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。
💦期待大家三连,关注,点赞,收藏。
💌作者能力有限,可能也会出错,欢迎大家指正。
💞愿与君为伴,共探Java汪洋大海。
1. 统一异常处理
1.1 制造一个算术异常
我们首先来制造一个算术异常,除数不能为0.
@RequestMapping("/login")
public String login(){
int num = 10/0;
return "执行了login";
}
我们先不用处理异常,观察我们的浏览器效果.
1.2 处理异常
- 创建一个类,在类上标识注解@ControllerAdvice,这个注解可以感知异常.
- 通过注解 @ExceptionHandler来订阅异常
package com.example.demo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
@ResponseBody
@ControllerAdvice
public class ExDeal {
@ExceptionHandler(ArithmeticException.class)
public HashMap<String, String> arithmeticException(ArithmeticException e) {
HashMap<String, String> result = new HashMap<>();
result.put("code", "-1");
result.put("msg", "算术异常异常:" + e.getMessage()); // 错误码的描述信息
result.put("data", "除数不能为0");
return result;
}
}
Exception包含所有的异常,参数写成Exception也可以,注意是方法的参数.
接下来我们观察浏览器效果.
2. 统一的返回格式
注意 : 我们在上一篇文章学习了拦截器,我们制定了一些拦截规则,我们一会要举一个例子进行测试我们的统一的返回格式,因此我们可以先把拦截器的代码注释掉.
2.1 为什么需要统一返回格式呢?
- ⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据。
- 降低前端程序员和后端程序员的沟通成本,按照某个格式实现就⾏了,因为所有接⼝都是这样返回的。
- 有利于项⽬统⼀数据的维护和修改。
- 有利于后端技术部⻔的统⼀规范的标准制定,不会出现稀奇古怪的返回内容。
- 也就是前后端做出格式约定,可以极大的方便程序员去处理各种各样的问题,格式不统一会有格式转换等不便捷的缺点,也不利于程序员维护.
2.2 写一个随机返回数函数
我们先在user类中写一个随机返回数字代码,运行通过浏览器观察效果.
@RequestMapping("/num")
public Integer num(){
Random random = new Random();
int num = random.nextInt(1000);
return num;
}
然而后端并不知道我们的格式,因为我们可能是字符串,整型等各种各样的数据类型.
2.3 创建一个类并且添加@ControllerAdvice
package com.example.demo;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@ControllerAdvice
public class Respons {
}
2.4 实现ResponseBodyAdvice接口并重写方法
我们要实现ResponseBodyAdvice接口,并且重写supports方法以及beforeBodyWrite方法(统一对象急速在此方法中实现的)
package com.example.demo;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
@ControllerAdvice
public class Response implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
//默认是false,表示开关关掉,意味着下面的重写效果没有用途
// return false;
//返回true的时候才会执行下面的beforeBodyWrite方法
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
HashMap<String,Object> map = new HashMap<>();
//添加状态码,200表示成功
map.put("code","200");
//错误的描述信息
map.put("msg",null);
//数据body
map.put("data",body);
return map;
}
}
然后我们观察统一格式后的效果
2.5 返回格式处理String类型出现问题
我们在login中返回的是一个字符串,当我们通过浏览器访问我们的login页面的时候会发现有一定的问题,错误是不能进行类型转化,这是为什么呢?
- String既不属于基本数据类型,又不属于对象.
- String使用的是自己的格式化工具,我们需要使用jackon进行类型转换.
- 因此如果是String需要特殊处理,我们先要通过属性注入把ObjectMapper注入进来,因为处理String需要这个方法.
package com.example.demo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
@ControllerAdvice
public class Response implements ResponseBodyAdvice {
@Autowired
private ObjectMapper objectMapper;
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
//默认是false,表示开关关掉,意味着下面的重写效果没有用途
// return false;
//返回true的时候才会执行下面的beforeBodyWrite方法
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
HashMap<String,Object> map = new HashMap<>();
//添加状态码,200表示成功
map.put("code","200");
//错误的描述信息
map.put("msg",null);
//数据body
map.put("data",body);
if (body instanceof String) {
// 需要特殊处理,因为 String 在转换的时候会报错
try {
return objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
return map;
}
}
接下来我们再次观察我们的浏览器页面效果.
3. @ControllerAdvice简单分析
- 我们先进入 @ControllerAdvice源码中,我们惊奇的发现@ControllerAdvice也是来自于组件@Component.⽽所有组件初始化都会调⽤InitializingBean 接⼝。
- 接下来我们来看 InitializingBean 有哪些实现类?在资料中我们发现 Spring MVC中的实现⼦类是 RequestMappingHandlerAdapter,我们找到一个initControllerAdviceCache方法.
文章来源:https://www.toymoban.com/news/detail-565542.html
- 我们发现这个⽅法在执⾏是会查找使⽤所有的 @ControllerAdvice 类,发⽣某个事件时,调⽤相应的 Advice ⽅法,⽐如返回数据前调⽤统⼀数据封装,⽐如发⽣异常是调⽤异常的Advice ⽅法实现。
- 换句话来说,就是有各种各样的Advice来处理不同的事件,如果出现了异常事件就会通过@ControllerAdvice注解调用异常事件相关的Advice进行检测异常(就是定位异常),然后通过我们的后端代码处理异常.
后序:
在Spring Boot统一功能处理我们主要学习了统一用户登录权限验证,统一数据格式返回,统一异常处理,这些都是在我们的SSM项目中非常重要的,我们需要重点去掌握.🚀🚀🚀文章来源地址https://www.toymoban.com/news/detail-565542.html
到了这里,关于【Spring Boot统一功能处理】统一异常处理,统一的返回格式,@ControllerAdvice简单分析,即将走进SSM项目的大门! ! !的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!