zuul网关
继承zuulFilter并实现四个方法,filterType、filterOrder、shouldFilter、run
- filterType():过滤器执行类型。有以下四种类型pre、route、post、error
pre:请求在路由之前调用
route:在路由请求时调用
post:在route和error过滤器之后调用
error:处理请求发生错误时调用 - filterOrder():过滤器执行顺序,数字越小,优先级越高
- shouldFilter():是否执行该过滤器,此处为true,则会执行run方法
- run():过滤器具体执行逻辑
//网关 前置过滤器
//pre:在请求被网关路由之前调用,可利用该过滤器实现身份认证,在集群中选择服务、记录调试信息
public class DateGateWayPreFilter extends ZuulFilter{
//指定过滤器类型为pre
@Override
public String filterType(){ return PRE_TYPE;}
//过滤器执行顺序,数字越小,优先级越高
@Override
public int filterOrder(){return 1;}
}
//返回一个boolean,判断该过滤器是否需要执行,true执行,false不执行
@Override
public boolean shouldFilter(){
//在此处可以设置某些url,跳过token等验证,直接放行
RequestContext rctx = RequestContext.getCurrentContext();
HttpServletRequest request=rctx.getRequest();
// /server/serverA为微服务A的统一路由地址
if("/server/serverA/power/login".equalsIgnoreCase(request.getRequestURI())){
log.info("登录请求不做拦截");
return false;
}
if(StringUtils.isNotEmpty( request.getRequestURI())&& request.getRequestURI().startsWith("/server/serverA/power/external/interfaces")){
log.info("暴露给外围系统的对接接口路径不做拦截");
return false;
}
return true;
}
// 过滤器的具体业务逻辑
@Override
public Object run(){
//登录逻辑的校验
// 获取Zuul请求的上下文对象
RequestContext rctx = RequestContext.getCurrentContext();
//从上下文中获取request对象
HttpServletRequest request=rctx.getRequest();
//从请求中获取token,请求头或者请求体中
String token="";
Cookie[] cookies=request.getCookies();
for(Cookie co:cookies){
if("token".equals(co.getName())){
token=co.getValue();
}
}
//如果token为空,则校验不通过,直接返回给前端异常
if(token==null||"".equals(token.trim())){
rctx.setSendZuulResponse(false);
rctx.setResponseStatusCode("401");
rctx.setResponseBody("token is Invalid ");
}
return null;
}
}
微服务
除了在网关中放行外,对应的服务中也需要对相关接口不拦截
实现WebMvcConfigurer接口,重写addCorsMappings()方法和addInterceptors()方法【配置拦截器】
实现HandlerInterceptor接口或者继承HandlerInterceptorAdapter,重写preHandle()方法【自定义拦截器】
@Configuration
public class LoginInterceptorConfig implements WebMvcConfigurer {
@Bean
public LoginInterceptor getLoginInterceptor(){
return new LoginInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册自定义的拦截器
InterceptorRegistration registration=registry.addInterceptor(getLoginInterceptor());
//添加需要拦截的方法
registration.addPathPatterns("/**");
//不拦截的方法
registration.excludePathPatterns("/power/login");
registration.excludePathPatterns("/power/external/interfaces/**");
}
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// 进行登录验证逻辑处理
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) throws Exception {
//后置处理
}
顺便理一下:
Handler和Interceptor的关系
Handler和Interceptor在spring的框架中都属于拦截器,但是作用和场景有所差异。
Handler是springMVC框架的核心组件,负责处理请求并返回响应结果。Handler可以理解为controller,处理前端传过来的数据并返回结果,实现具体的业务逻辑处理;而HandlerInterceptor是在Handler处理请求之前或者之后执行的拦截器,可以对请求做一个预处理或者对响应结果做一个统一处理,可以实现日志记录和权限验证等功能
Interceptor是Spring框架提供的一种拦截机制,它可以在请求的处理过程中进行预处理和后处理。Interceptor可以在请求到达Handler之前(preHandle)、在Handler执行后返回结果之前(postHandle)、以及在响应返回给客户端之后(afterCompletion)进行拦截操作
HandlerInterceptor 和 WebMvcConfigurer的关系
HandlerInterceptor是Spring MVC框架提供的拦截器,用于在请求处理的前后执行一些自定义的逻辑。它可以在请求被处理之前和之后对请求进行拦截和处理,例如日志记录、身份认证、权限校验等。HandlerInterceptor 可以拦截所有的请求,也可以只拦截某些特定的请求。
WebMvcConfigurer是Spring MVC框架提供的用于定制化WebMvc配置的接口,它可以配置拦截器、消息转换器、视图解析器、静态资源等,以及添加自定义的HandlerMapping和HandlerAdapter等。通过实现WebMvcConfigurer接口,可以对Spring MVC框架进行定制化配置,以满足应用程序的特定需求。
一般来说,我们可以通过实现HandlerInterceptor接口来拦截请求并处理请求的前后逻辑,通过实现WebMvcConfigurer接口来对Spring MVC框架进行定制化配置。同时,我们可以在WebMvcConfigurer中注册自定义的HandlerInterceptor。