GlobalFilter+AbstractGatewayFilterFactory实现指定路由跳过全局过滤器

编程入门 行业动态 更新时间:2024-10-22 07:41:08

GlobalFilter+AbstractGatewayFilterFactory实现指定<a href=https://www.elefans.com/category/jswz/34/1771390.html style=路由跳过全局过滤器"/>

GlobalFilter+AbstractGatewayFilterFactory实现指定路由跳过全局过滤器

GlobalFilter+AbstractGatewayFilterFactory实现指定路由跳过全局过滤器

全局过滤器GlobalFilter

具体代码如下

package com.chanjet.dsf.web.filter;import com.alibaba.fastjson.JSON;
import com.chanjet.dsf.cache.RedisUtil;
import com.chanjet.dsf.constant.AttrbuteConstant;
import com.chanjet.dsf.constant.ResultCodeEnum;
import com.chanjet.dsf.result.ResultFactory;
import com.chanjet.dsf.web.models.AuthTokenPo;
import com.chanjet.dsf.web.util.Constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.nio.charset.StandardCharsets;@Component
public class AuthFilter implements GlobalFilter, Ordered {Logger logger = LoggerFactory.getLogger(AuthFilter.class);private static final String TOKEN_PREFIX = "DSFTOKEN::";@AutowiredRedisUtil redisUtil;//    @Resource
//    RestTemplate restTemplate;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst(Constant.QUERY_PARAMS.TOKEN);logger.info("=======AuthFilter:token======" + token);
//        restTemplate.// 不判断token的过滤器,比如登录接口if (exchange.getAttribute(AttrbuteConstant.ATTRIBUTE_IGNORE_TEST_GLOBAL_FILTER) != null&& exchange.getAttribute(AttrbuteConstant.ATTRIBUTE_IGNORE_TEST_GLOBAL_FILTER).equals(true)) {return chain.filter(exchange);}if (StringUtils.isEmpty(token)) {//返回一个错误码 前端去做跳转淘宝授权登录页面 (前端处理)
//           exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
//           return exchange.getResponse().setComplete();return generateJSON(exchange, ResultFactory.getErrorResult(ResultCodeEnum.TOKEN_IS_NULL));}String rediskey = TOKEN_PREFIX + token;// 通过token取缓存try {AuthTokenPo authTokenPo = (AuthTokenPo) redisUtil.get(rediskey);//判断token过期// 校验缓存的账号信息是否为空if (authTokenPo == null) {return generateJSON(exchange, ResultFactory.getErrorResult(ResultCodeEnum.TOKEN_IS_INVALID));}} catch (Exception e) {logger.error("AuthFilter.filter 错误信息{}", e.getMessage(), e);}return chain.filter(exchange);}private <T>Mono generateJSON(ServerWebExchange exchange, T t){ServerHttpResponse response = exchange.getResponse();byte[] bits = JSON.toJSONString(t).getBytes(StandardCharsets.UTF_8);DataBuffer buffer = response.bufferFactory().wrap(bits);response.setStatusCode(HttpStatus.UNAUTHORIZED);//指定编码,否则在浏览器中会中文乱码response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");return response.writeWith(Mono.just(buffer));}@Overridepublic int getOrder() {return -900;}}

AbstractGatewayFilterFactory 局部过滤器

内部类写法,是为了指定过滤器的优先级,要优先于全局过滤器,否则
容易造成全局过滤器 拦截到指定 局部过滤器的配置内容,从而导致局
部过滤器失效

package com.chanjet.dsf.web.filter;import com.chanjet.dsf.constant.AttrbuteConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;/*** 设置忽略路由*/
@Component
public class IgnoreAuthFilter extends AbstractGatewayFilterFactory<IgnoreAuthFilter.Config> {Logger logger = LoggerFactory.getLogger(IgnoreAuthFilter.class);public IgnoreAuthFilter() {super(Config.class);logger.info("IgnoreFilter 进入 IgnoreAuthGatewayFilterFactory ");}@Overridepublic GatewayFilter apply(Config config) {logger.info("IgnoreFilter 进入  apply");/*return (exchange, chain) -> {if (!config.isIgnoreGlobalFilter()) {return chain.filter(exchange);}return chain.filter(exchange);};*///===============================注意=================================//下面的内部类写法,是为了指定过滤器的优先级,要优先于全局过滤器,否则//容易造成全局过滤器 拦截到指定 局部过滤器的配置内容。return new InnerFilter(config);}/*** 创建一个内部类,来实现2个接口,指定顺序* 这里通过Ordered指定优先级*/private class InnerFilter implements GatewayFilter, Ordered {private Config config;InnerFilter(Config config) {this.config = config;}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {/*System.out.println("  pre 自定义过滤器工厂 AAAA  " + this.getClass().getSimpleName());boolean root = true == config.isIgnoreGlobalFilter();if (root) {System.out.println("  is root ");} else {System.out.println("  is no root ");}// 在then方法里的,相当于aop中的后置通知return chain.filter(exchange).then(Mono.fromRunnable(() -> {System.out.println("  post 自定义过滤器工厂 AAAA " + this.getClass().getSimpleName());}));*/logger.info("进入innerFilter=====" + config.isIgnoreGlobalFilter());if (config.isIgnoreGlobalFilter() == true) {exchange.getAttributes().put(AttrbuteConstant.ATTRIBUTE_IGNORE_TEST_GLOBAL_FILTER, true);}return chain.filter(exchange);}@Overridepublic int getOrder() {return -1000;}}public static class Config{boolean ignoreGlobalFilter;public boolean isIgnoreGlobalFilter() {return ignoreGlobalFilter;}public void setIgnoreGlobalFilter(boolean ignoreGlobalFilter) {this.ignoreGlobalFilter = ignoreGlobalFilter;}}//这个name方法 用来在yml配置中指定对应的过滤器名称@Overridepublic String name() {return "IgnoreAuthFilter";}}

yml配置

spring:cloud:gateway:discovery:locator:enabled: truelower-case-service-id: trueroutes:- id: dsf-report-seruri: lb://dsf-report-serpredicates:- Path=/report/**- id: dsf-account-seruri: lb://dsf-account-serpredicates:- Path=/account/**,/setting/**filters:- name: IgnoreAuthFilter #本路由跳过全局过滤器args:ignoreGlobalFilter: true- id: dsf-finance-seruri: lb://dsf-finance-serpredicates:- Path=/shopTrade/**,/goods/**,/cost/**

更多推荐

GlobalFilter+AbstractGatewayFilterFactory实现指定路由跳过全局过滤器

本文发布于:2024-03-04 10:31:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1709014.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:路由   过滤器   全局   跳过   GlobalFilter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!