您的位置:首页 > 文旅 > 美景 > 品牌建设文案_成都专业的网站建站公司_百家号权重查询_手机端网站优化

品牌建设文案_成都专业的网站建站公司_百家号权重查询_手机端网站优化

2025/4/12 23:00:17 来源:https://blog.csdn.net/2302_80826557/article/details/146984018  浏览:    关键词:品牌建设文案_成都专业的网站建站公司_百家号权重查询_手机端网站优化
品牌建设文案_成都专业的网站建站公司_百家号权重查询_手机端网站优化

 1.拦截器

1.1什么是拦截器

 拦截器是Spring框架提供的核心功能之一,主要是用来拦截用户的请求,在用户请求指定的方法执行前后,可以根据业务需要执行实现预定的代码。

通过拦截器,开发人员就可以根据需求针对一些特殊的请求,在这个http请求成功访问到接口之前,根据实际开发需求先设定一些执行逻辑,根据这段逻辑的代码执行的接口去判断是否放行这个请求。

1.2 如何使用拦截器

使用拦截器分为两步,第一步是定义拦截器,第二步是注册配置拦截器

1.定义拦截器

首先创建一个拦截器类并实现HandlerIntercepter接口

@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("访问接口前");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("访问接口执行后");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("视图渲染完成后");}
}

1. preHandle方法是接口方法执行执行的方法,如果preHandle返回的结果是true,就对这个http请求进行放行,如果返回值为false,则就拒绝这个http请求继续访问该接口。

2.postHandle方法是访问接口执行后才执行的方法

3.afterCompletion方法是视图渲染完成后才执行的代码,但是在后端开发中很少用到。

2.注册并配置拦截器

创建一个名为WebConfig的类,并实现WebMvcConfigurer接口,重写addInterceptors,其中addpathPatterns( )括号里面的是拦截的路径,excludePathPatterns()括号里面是不拦截的路径,注意这里的路径是指url,不是指包的层次。

@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate MyInterceptor interceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(interceptor).addPathPatterns("/req/**").excludePathPatterns("/test/**");}
}

接口实现:

@Slf4j
@RequestMapping("/req")
@RestController
public class RequestController {@RequestMapping("/t1")public void t1(){log.info("接口执行");}
}

访问该接口

1.3拦截器的执行流程

没有拦截器,我们程序运行的正常顺序就是http请求直接访问到controller层实现的接口。如下图

但是,有了拦截器之后,如果此时用户访问的路径在拦截器的拦截范围之内,在调用controller层的接口前,首先会执行preHandle方法,根据该方法的结果是true还是false判断是否继续放行这个请求,如果是false,则不放行这个请求,将拒绝执行该请求,如果是true,则继续放行这个请求,接着去调用controller层的接口,controller层的接口执行完毕之后,接着再去执行postHandle和afterCompletion方法,最终将相应返回给浏览器,如下图

1.4 DispatcherServlet 源码分析(了解)

 当Tomcat启动之后,有一个核心类DispatcherServlet,DispatcherServlet类来控制程序的执行,所有的请求都会先进到DispatcherServlet,执行doDispatch方法,如果有拦截器,会先执行拦截器的preHandle方法,如果preHandle返回true,则访问controller中的方法,当controller中的方法执行完毕后,在回过来执行postHandle和afterComletion方法,并返回个DispatcherServlet,最终返回给浏览器响应数据。

而DispatcherServlet类的初始化方法是通过init()方法实现的,init()方法是在父类HttpServletBean中实现的,主要是建立WebApplicationContext容器(也称上下文),并加载配置文件中的Bean到该容器中,最后将该容器添加到ServletContext中。

 DispatcherServlet接收到请求后,执行doDispatch调度方法,在将请求转给controller层。

核心:

在doDispatch调度方法中,首先会根据请求找到与请求对应的Handler,接着就会通过适配器模式,去寻找可以处理Handler的适配器,接着在执行doDispatch方法中的applyPreHandle方法,在applyPreHandle方法中实现了获取所有的拦截器功能,就去执行拦截器的preHandle方法,紧接着去执行目标方法和拦截器的postHandle等方法。

//3. 执⾏拦截器preHandle⽅法if (!mappedHandler.applyPreHandle(processedRequest, response)) 
{return;}//4. 执⾏⽬标⽅法mv = ha.handle(processedRequest, response, 
mappedHandler.getHandler());

1.5适配器模式

适配器模式也叫做包装器模式,就是当我们希望将一个接口转换成客户期望另一个接口时,在一些情况,我们无法直接对原来的接口直接进行改造,但是为了可以让原来的接口与客户期望的接口相互兼容,我们可以通过一个适配器,让原本不兼容的接口可以变得兼容起来。

简答来说,就是目标类不能直接使用,通过一个新类包装一下,让适配器调用方使用,把两个不兼容的接口通过一定的方式让其兼容。

一般来说,适配器模式可以看做一种补偿模式,其是用来补救设计上的缺陷的,如果在设计初期就能协调规避接口不兼容的问题,就不需要使用适配器模式了。

所以适配器模式更多的应用场景主要是对正在运行的代码进行改造,并且希望可以复用原有的代码实现新功能。

2.统⼀数据返回格式

 2.1 快速使用

先创建一个类并实现ResponseBodyAdvice接口,并在类上添加一个@ControllerAdvice注解,并重写supports()方法,beforeBodyWrite方法。

设计的统一的数据返回格式 

@Data
public class Result<T> {private ResultCodeEnum code;   //-1未登录   200正常   -2后端出错private String errMsg;private T data;public static <T>Result success(T data){Result result=new Result();result.setCode(ResultCodeEnum.SUCCESS);result.setErrMsg("");result.setData(data);return result;}public static <T>Result fail(String errMsg){Result result=new Result();result.setCode(ResultCodeEnum.FAIL);result.setErrMsg(errMsg);result.setData(null);return result;}public static <T>Result unLogin(){Result result=new Result();result.setCode(ResultCodeEnum.UNLOGIN);result.setErrMsg("用户未登录");result.setData(null);return result;}
}

下面代码就可以实现所有接口按照我们设计的统一返回数据格式返回结果。

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {//true表示处理 false表示不处理return true;}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if(body instanceof String){//将String类型转为jsonreturn objectMapper.writeValueAsString(Result.success(body));}if(body instanceof Result){return body;}return Result.success(body);}
}

其中根据supports方法的返回值来判断是否执行beforeBodyWrite方法,如果是true就执行,如果是false就不执行。

需要注意的是如果原来的接口时String类型,在返回结果之前,我们需要特殊处理,将String转换为JSON格式,否则会报错。 

3.统一异常处理

3.1快速使用

统一异常处理是通过@ControllerAdvice注解和@ExceptionHandler实现,这个能帮助我们去捕获我们在写代码时,没有预料到的异常。

代码用例

@ResponseBody
@ControllerAdvice
public class ExceptionAdvice {@ExceptionHandlerpublic Result handler(Exception e){log.error("发生异常,e:",e);return Result.fail("内部发生异常,请联系管理员");}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com