贵阳网站seo外包,在一个城市做相亲网站,福州网站搜索引擎优化,免费店铺logo在线制作目录
拦截器:是Spring框架提供的核心功能之一#xff0c;主要用来拦截用户的请求#xff0c;在指定方法前后#xff0c;根据业务需要执行预先设定的代码:
自定义拦截器
统一数据格式#xff0c;要包含状态码#xff0c;错误信息编辑
出现针对String类型的错误…
目录
拦截器:是Spring框架提供的核心功能之一主要用来拦截用户的请求在指定方法前后根据业务需要执行预先设定的代码:
自定义拦截器
统一数据格式要包含状态码错误信息编辑
出现针对String类型的错误
为什么要统一
统一功能来实现捕捉到异常。编辑
ControllerAdvice源码分析 数据结构面试:HashMap,ConcurrentHashMap,ThreadLocal要看(建议看源码) 网络:TCP,UDP,HTTP 并发编程:线程创建方式,线程的状态锁synchronized,volatile 数据库 基本操作关键字 JVM-内存结构GC Linux 引入拦截器的原因。 拦截器:是Spring框架提供的核心功能之一主要用来拦截用户的请求在指定方法前后根据业务需要执行预先设定的代码: (指定在哪些方法前后执行) JDK17把之前Java的包都换为Jakarta。 指定方法——指我们登录验证的某些方法比如图书的增删改查怎样可以不用动太多代码实现这个功能 预先设定的代码对用户是否登录进行验证 拦截器的实现分为两步:作用维度以url为维度) 1.定义一个拦截器 2.把拦截器注册到项目中 自定义拦截器:实现HandlerInterceptor接口并重写所有方法 拦截器的定义 自定义拦截器 /* 一级路径 能匹配/user,/book,/login,不能匹配/user/login /** 任意级路径 能匹配 /user,/user/login,/book /book/* /book下的一级路径 能匹配/book/addBook,不能匹配/book/addBook /book/** /book下的任意级路径 能匹配/book,/book/addBook,/book/addBook/2...。 正常工作方式 用户调用-(拦截器)-控制器层Controller)-调用服务层(Service)-数据持久层(Mapper)-数据库 1.添加拦截器后, 执⾏Controller的⽅法之前, 请求会先被拦截器拦截住. 执⾏ preHandle() ⽅法 这个⽅法需要返回⼀个布尔类型的值. 如果返回true, 就表⽰放⾏本次操作, 继续访问controller中的 ⽅法. 如果返回false则不会放⾏(controller中的⽅法也不会执⾏). 2. controller当中的⽅法执⾏完毕后再回过来执⾏ postHandle() 这个⽅法以及 afterCompletion() ⽅法执⾏完毕之后最终给浏览器响应数据 DispatcherServletDispatcher调度器servlet生命周期 源码环节 适配器模式和门面模式区别 1.适配器模式是适配两者之间的差异为了补救设计上的缺陷应用这种模式也是无心之举门面模式是统合了底层系统我认为一个像是七巧板把两个不同的连接起来门面模式就像是给他装了一个套它里面不变只是说可以调用他们两个我们通过外面的套来调用里面。 统一数据格式要包含状态码错误信息 supports⽅法: 判断是否要执⾏beforeBodyWrite⽅法. true为执⾏, false不执⾏. 通过该⽅法可以 选择哪些类或哪些⽅法的response要进⾏处理, 其他的不进⾏处理. beforeBodyWrite⽅法: 对response⽅法进⾏具体操作处理 出现针对String类型的错误 快速⼊⻔ 统⼀的数据返回格式使⽤ ControllerAdvice 和 ResponseBodyAdvice 的⽅式实现
ControllerAdvice 表⽰控制器通知类 添加类 ResponseAdvice , 实现 ResponseBodyAdvice 接⼝, 并在类上添加
ControllerAdvice 注解
import com.example.demo.model.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
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.ResponseBodyAdvice;
ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;}
Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest
request, ServerHttpResponse response) {
return Result.success(body);}
} 解决方法 public class TestController {
RequestMapping(/t1)
public String t1(){
return t1;}
RequestMapping(/t2)
public boolean t2(){
return true;}
RequestMapping(/t3)
public Integer t3(){
return 200;}
}
解决⽅案:
import com.example.demo.model.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
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.ResponseBodyAdvice;
Slf4j
ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
private static ObjectMapper mapper new ObjectMapper();
Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;}
SneakyThrows
Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest
request, ServerHttpResponse response) {
//如果返回结果为String类型, 使⽤SpringBoot内置提供的Jackson来实现信息的序列化
if (body instanceof String){
return mapper.writeValueAsString(Result.success(body));}
return Result.success(body);}
}为什么会有这样的错误呢 SpringMVC默认会注册⼀些⾃带的 HttpMessageConverter (从先后顺序排列分别为 ByteArrayHttpMessageConverter , StringHttpMessageConverter , SourceHttpMessageConverter , SourceHttpMessageConverter , AllEncompassingFormHttpMessageConverter ) AllEncompassingFormHttpMessageConverter 会根据项⽬依赖情况 添加对应的 HttpMessageConverter 在依赖中引⼊jackson包后容器会把 MappingJackson2HttpMessageConverter ⾃动注册到 messageConverters 链的末尾. Spring会根据返回的数据类型, 从 messageConverters 链选择合适的 HttpMessageConverter . 当返回的数据是⾮字符串时, 使⽤的 MappingJackson2HttpMessageConverter 写⼊返回对象. 当返回的数据是字符串时 StringHttpMessageConverter 会先被遍历到这时会认为 StringHttpMessageConverter 可以使⽤ 在 ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage) 的处理中, 调⽤⽗类的write⽅法 由于 StringHttpMessageConverter 重写了addDefaultHeaders⽅法, 所以会执⾏⼦类的⽅法 然⽽⼦类 StringHttpMessageConverter 的addDefaultHeaders⽅法定义接收参数为String, 此 时t为Result类型, 所以出现类型不匹配Result cannot be cast to java.lang.String的异常 最终 为什么要统一 1. ⽅便前端程序员更好的接收和解析后端数据接⼝返回的数据 2. 降低前端程序员和后端程序员的沟通成本, 按照某个格式实现就可以了, 因为所有接⼝都是这样返回 的. 3. 有利于项⽬统⼀数据的维护和修改. 4. 有利于后端技术部⻔的统⼀规范的标准制定, 不会出现稀奇古怪的返回内容. 统一功能来实现捕捉到异常。 Spring的代码在书写统一的过程中不按照顺序。 捕捉异常的时候看他报什么异常最贴近哪个那么就是哪个 不加ResponseBody -她就会把下面那个异常当成一条数据 package com.example.demo.config;import com.example.demo.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;Slf4j
ResponseBody
ControllerAdvice
public class ErrorHandler {ExceptionHandlerpublic Result exception(Exception e){log.error(发生异常e{},e);return Result.fail(内部错误);}ExceptionHandlerpublic Result exception(NullPointerException e){log.info(发生异常);return Result.fail(NullPointerException异常请联系管理员);}ExceptionHandlerpublic Result exception(ArithmeticException e){log.info(发生异常);return Result.fail(ArithmeticException 异常请联系管理员);}}Spring容器最开始启动时会进行初始化的工作其中会对异常进行处理当异常项有多个匹配的时候Spring会对其顺序依次排找出最符合的报异常。
ControllerAdvice源码分析 述源码可以看出 ControllerAdvice 派⽣于 Component 组件, 这也就是为什么没有五 ⼤注解, ControllerAdvice 就⽣效的原因 当Controller抛出异常时 DispatcherServlet 通过
ExceptionHandlerExceptionResolver 来解析异常⽽
ExceptionHandlerExceptionResolver ⼜通过 ExceptionHandlerMethodResolver 来解析异常 ExceptionHandlerMethodResolver 最终解析异常找到适⽤的ExceptionHandler标注