欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Zuul實(shí)現(xiàn)動(dòng)態(tài)路由與權(quán)限過(guò)濾器方式

 更新時(shí)間:2025年07月17日 10:10:15   作者:小凱  
文章介紹如何通過(guò)Zuul實(shí)現(xiàn)動(dòng)態(tài)路由與權(quán)限驗(yàn)證,利用自定義過(guò)濾器和配置刷新機(jī)制,提升系統(tǒng)靈活性與安全性,確保接口訪問(wèn)可控且無(wú)需重啟

前言介紹

在實(shí)際的業(yè)務(wù)開(kāi)發(fā)中不只是將路由配置放到文件中,而是需要進(jìn)行動(dòng)態(tài)管理并且可以在變化時(shí)不用重啟系統(tǒng)就可以更新。與此同時(shí)還需要在接口訪問(wèn)的時(shí)候,可以增加一些權(quán)限驗(yàn)證以防止惡意訪問(wèn)。

1.Filter過(guò)濾器,通過(guò)繼承實(shí)現(xiàn)對(duì)應(yīng)方法可以進(jìn)行控制過(guò)濾;

  • PRE:這種過(guò)濾器在請(qǐng)求被路由之前調(diào)用。我們可利用這種過(guò)濾器實(shí)現(xiàn)身份驗(yàn)證、在集群中選擇請(qǐng)求的微服務(wù)、記錄調(diào)試信息等。
  • ROUTING:這種過(guò)濾器將請(qǐng)求路由到微服務(wù)。這種過(guò)濾器用于構(gòu)建發(fā)送給微服務(wù)的請(qǐng)求,并使用 Apache HttpClient 或 Netfilx Ribbon 請(qǐng)求微服務(wù)。
  • POST:這種過(guò)濾器在路由到微服務(wù)以后執(zhí)行。這種過(guò)濾器可用來(lái)為響應(yīng)添加標(biāo)準(zhǔn)的 HTTP Header、收集統(tǒng)計(jì)信息和指標(biāo)、將響應(yīng)從微服務(wù)發(fā)送給客戶(hù)端等。
  • ERROR:在其他階段發(fā)生錯(cuò)誤時(shí)執(zhí)行該過(guò)濾器。 除了默認(rèn)的過(guò)濾器類(lèi)型,Zuul 還允許我們創(chuàng)建自定義的過(guò)濾器類(lèi)型。例如,我們可以定制一種 STATIC 類(lèi)型的過(guò)濾器,直接在 Zuul 中生成響應(yīng),而不將請(qǐng)求轉(zhuǎn)發(fā)到后端的微服務(wù)。

2.自定義路由,同構(gòu)實(shí)現(xiàn)SimpleRouteLocator和RefreshableRouteLocator自動(dòng)刷新

  • protected Map<String, ZuulRoute> locateRoutes():此方法是加載路由配置的,父類(lèi)中是獲取properties中的路由配置,可以通過(guò)擴(kuò)展此方法,達(dá)到動(dòng)態(tài)獲取配置的目的
  • public Route getMatchingRoute(String path):此方法是根據(jù)訪問(wèn)路徑,獲取匹配的路由配置,父類(lèi)中已經(jīng)匹配到路由,可以通過(guò)路由id查找自定義配置的路由規(guī)則,以達(dá)到根據(jù)自定義規(guī)則動(dòng)態(tài)分流的效果

環(huán)境準(zhǔn)備

  • 1.jdk 1.8、idea2018、Maven3
  • 2.Spring Boot 2.0.6.RELEASE
  • 3.Spring Cloud Finchley.SR2

代碼示例

itstack-demo-springcloud-08
├── itstack-demo-springcloud-eureka-client
│   └── src
│       └── main
│           ├── java
│           │   └── org.itstack.demo
│           │        ├── web
│           │        │   └── EurekaClientController.java
│           │        └── EurekaClientApplication.java
│           └── resources   
│               └── application.yml
├── itstack-demo-springcloud-eureka-server
│   └── src
│       └── main
│           ├── java
│           │   └── org.itstack.demo
│           │        └── EurekaServerApplication.java
│           └── resources   
│               └── application.yml
├── itstack-demo-springcloud-hystrix-feign
│   └── src
│       └── main
│           ├── java
│           │   └── org.itstack.demo
│           │        ├── service
│           │        │   ├── hystrix
│           │        │   │   └── FeignServiceHystrix.java
│           │        │   └── FeignService.java
│           │        ├── web
│           │        │   └── FeignController.java
│           │        └── FeignApplication.java
│           └── resources   
│               └── application.yml
├── itstack-demo-springcloud-hystrix-ribbon
│   └── src
│       └── main
│           ├── java
│           │   └── org.itstack.demo
│           │        ├── service
│           │        │   └── RibbonService.java
│           │        ├── web
│           │        │   └── RibbonController.java      
│           │        └── RibbonApplication.java
│           └── resources   
│               └── application.yml
└── itstack-demo-springcloud-zuul
    └── src
        └── main
            ├── java
            │   └── org.itstack.demo   
            │        ├── config
            │        │   └── ZuulConfig.java
            │        ├── filter
            │        │   └── TokenFilter.java
            │        ├── router
            │        │   └── RouteLocator.java
            │        ├── service
            │        │   └── RefreshRouteService.java
            │        └── ZuulApplication.java
            └── resources   
                └── application.yml

itstack-demo-springcloud-zuul & 動(dòng)態(tài)路由與權(quán)限過(guò)濾

  • 1.通過(guò)RouteLocator實(shí)現(xiàn)自己的動(dòng)態(tài)路由配置,其實(shí)就是把配置文件內(nèi)容轉(zhuǎn)移到這里用代碼類(lèi)實(shí)現(xiàn),并且可以根據(jù)需要修改為從數(shù)據(jù)庫(kù)里獲取。
  • 2.TokenFilter提供了權(quán)限驗(yàn)證功能,當(dāng)用戶(hù)訪問(wèn)時(shí)候會(huì)帶上token否則攔截
  • 3.此外還提供了自動(dòng)刷新的接口,用于外部調(diào)用刷新配置
  • 4.最后我們需要修改application配置,zuul中還需要排除不做路由的接口[刷新權(quán)限接口]

config/ZuulConfig.java & 路由配置類(lèi)

@Configuration
public class ZuulConfig {

    @Autowired
    private ZuulProperties zuulProperties;
    @Autowired
    private ServerProperties server;

    @Bean
    public RouteLocator routeLocator() {
        return new RouteLocator(this.server.getServlet().getPath(), this.zuulProperties);
    }

}

filter/TokenFilter.java & 權(quán)限校驗(yàn)類(lèi)

public class TokenFilter extends ZuulFilter {

    /**
     * 過(guò)濾器的類(lèi)型,它決定過(guò)濾器在請(qǐng)求的哪個(gè)生命周期中執(zhí)行。
     * FilterConstants.PRE_TYPE:代表會(huì)在請(qǐng)求被路由之前執(zhí)行。
     * PRE、ROUTING、POST、ERROR
     */
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    /**
     * filter執(zhí)行順序,通過(guò)數(shù)字指定。[數(shù)字越大,優(yōu)先級(jí)越低]
     */
    public int filterOrder() {
        return 0;
    }

    /**
     * 判斷該過(guò)濾器是否需要被執(zhí)行。這里我們直接返回了true,因此該過(guò)濾器對(duì)所有請(qǐng)求都會(huì)生效。
     * 實(shí)際運(yùn)用中我們可以利用該函數(shù)來(lái)指定過(guò)濾器的有效范圍。
     */
    public boolean shouldFilter() {
        return true;
    }

    /*
     * 具體執(zhí)行邏輯
     */
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        String token = request.getParameter("token");
        if (token == null || token.isEmpty()) {
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            ctx.setResponseBody("refuse! token is empty");
        }
        return null;
    }

}

router/RouteLocator.java & 路由類(lèi)

public class RouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

    private ZuulProperties properties;

    public RouteLocator(String servletPath, ZuulProperties properties) {
        super(servletPath, properties);
        this.properties = properties;
    }

    @Override
    public void refresh() {
        doRefresh();
    }

    @Override
    protected Map<String, ZuulRoute> locateRoutes() {
        LinkedHashMap<String, ZuulRoute> routesMap = new LinkedHashMap<String, ZuulRoute>();
        //從application.properties中加載路由信息
        routesMap.putAll(super.locateRoutes());
        //從db中加載路由信息
        routesMap.putAll(routesConfigGroup());
        //優(yōu)化一下配置
        LinkedHashMap<String, ZuulRoute> values = new LinkedHashMap<>();
        for (Map.Entry<String, ZuulRoute> entry : routesMap.entrySet()) {
            String path = entry.getKey();
            // Prepend with slash if not already present.
            if (!path.startsWith("/")) {
                path = "/" + path;
            }
            if (StringUtils.hasText(this.properties.getPrefix())) {
                path = this.properties.getPrefix() + path;
                if (!path.startsWith("/")) {
                    path = "/" + path;
                }
            }
            values.put(path, entry.getValue());
        }
        return values;
    }

    /**
     * 路由配置組,可以從數(shù)據(jù)庫(kù)中讀取
     * 基本配置與寫(xiě)在文件中配置類(lèi)似,如下;
     * #  routes:
     * #    api-a:
     * #      path: /route-a/**
     * #      serviceId: itstack-demo-springcloud-feign
     * #    api-b:
     * #      path: /route-b/**
     * #      serviceId: itstack-demo-springcloud-ribbon
     * @return 配置組內(nèi)容
     */
    private Map<String, ZuulRoute> routesConfigGroup() {
        Map<String, ZuulRoute> routes = new LinkedHashMap<>();

        ZuulRoute zuulRoute = new ZuulRoute();
        zuulRoute.setId("route-a");
        zuulRoute.setPath("/route-a/**");
        zuulRoute.setServiceId("itstack-demo-springcloud-feign");
        // 如果使用了注冊(cè)中心,那么可以根據(jù)serviceId進(jìn)行訪問(wèn)。
        // zuulRoute.setUrl("http://localhost:9001");
        zuulRoute.setRetryable(false);
        zuulRoute.setStripPrefix(true);
        zuulRoute.setSensitiveHeaders(new HashSet<>());

        routes.put(zuulRoute.getPath(), zuulRoute);

        return routes;
    }

}

service/RefreshRouteService.java & 路由刷新服務(wù)

@Service
public class RefreshRouteService {

    @Autowired
    private ApplicationEventPublisher publisher;

    @Autowired
    private RouteLocator routeLocator;

    public void refreshRoute() {
        RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(routeLocator);
        publisher.publishEvent(routesRefreshedEvent);
    }

}

ZuulApplication.java & 啟動(dòng)服務(wù)注意注解,另外提供了服務(wù)接口

@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
@EnableDiscoveryClient
@RestController
public class ZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }

    @Bean
    public TokenFilter tokenFilter() {
        return new TokenFilter();
    }

    @Autowired
    private RefreshRouteService refreshRouteService;
    @Autowired
    private ZuulHandlerMapping zuulHandlerMapping;

    @RequestMapping("api/refresh")
    public String refresh(){
        refreshRouteService.refreshRoute();
        return "success";
    }

    @RequestMapping("api/queryRouteInfo")
    @ResponseBody
    public Map<String, Object> queryRouteInfo(){
        return zuulHandlerMapping.getHandlerMap();
    }

}

application.yml & 配置文件修改,路由過(guò)濾

server:
  port: 10001

spring:
  application:
    name: itstack-demo-ddd-zuul

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:7397/eureka/

# 動(dòng)態(tài)路由,以下配置注釋?zhuān)?
# http://localhost:10001/route-a/api/queryUserInfo?userId=111
# http://localhost:10001/route-b/api/queryUserInfo?userId=111
zuul:
   ignoredPatterns: /api/**
#  routes:
#    api-a:
#      path: /route-a/**
#      serviceId: itstack-demo-springcloud-feign
#    api-b:
#      path: /route-b/**
#      serviceId: itstack-demo-springcloud-ribbon

測(cè)試驗(yàn)證

1.分別啟動(dòng)如下服務(wù);

  • itstack-demo-springcloud-eureka-server 服務(wù)注冊(cè)與發(fā)現(xiàn)
  • itstack-demo-springcloud-eureka-client 接口提供方
  • itstack-demo-springcloud-hystrix-feign 調(diào)用端
  • itstack-demo-springcloud-hystrix-ribbon 調(diào)用端
  • itstack-demo-springcloud-zuul 路由服務(wù)

2.可測(cè)試接口列表;

  • 路由服務(wù):http://localhost:10001/route-a/api/queryUserInfo?userId=111&token=111

Hello | 111 >: from eureka client port: 8001 From Feign

  • 刷新配置:http://localhost:10001/api/refresh
  • 內(nèi)容配置:http://localhost:10001/api/queryRouteInfo

綜上總結(jié)

路由服務(wù)可以方便的幫我們控制業(yè)務(wù)類(lèi)型的區(qū)分訪問(wèn),同時(shí)自動(dòng)刷新可以更加方便的使用網(wǎng)關(guān)路由

權(quán)限驗(yàn)證是幾乎不可少的在實(shí)際開(kāi)發(fā)過(guò)程中會(huì)經(jīng)常用到,所有的接口必須是安全可靠的,保證數(shù)據(jù)不泄露

另外還可以考慮從入?yún)⒌挠脩?hù)身份進(jìn)行路由,這樣可以把數(shù)據(jù)庫(kù)路由提前,讓不同用戶(hù)組直接訪問(wèn)到不同的數(shù)據(jù)庫(kù)組

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring Boot集成MyBatis訪問(wèn)數(shù)據(jù)庫(kù)的方法

    Spring Boot集成MyBatis訪問(wèn)數(shù)據(jù)庫(kù)的方法

    這篇文章主要介紹了Spring Boot集成MyBatis訪問(wèn)數(shù)據(jù)庫(kù)的方法,需要的朋友可以參考下
    2017-04-04
  • kafka運(yùn)維consumer-groups.sh消費(fèi)者組管理

    kafka運(yùn)維consumer-groups.sh消費(fèi)者組管理

    這篇文章主要為大家介紹了kafka運(yùn)維consumer-groups.sh消費(fèi)者組管理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11
  • 聊聊mybatis sql的括號(hào)問(wèn)題

    聊聊mybatis sql的括號(hào)問(wèn)題

    這篇文章主要介紹了mybatis sql的括號(hào)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • MyBatis中resultType屬性的使用

    MyBatis中resultType屬性的使用

    這篇文章主要介紹了MyBatis中resultType屬性的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • Java這個(gè)名字的來(lái)歷與優(yōu)勢(shì)

    Java這個(gè)名字的來(lái)歷與優(yōu)勢(shì)

    Java是Sun公司開(kāi)發(fā)的一種編程語(yǔ)言,Sun公司最初的方向是讓Java來(lái)開(kāi)發(fā)一些電器裝置程序,Java名字的由來(lái),實(shí)際上是一個(gè)有趣的故事。
    2014-10-10
  • Java集合之Set、HashSet、LinkedHashSet和TreeSet深度解析

    Java集合之Set、HashSet、LinkedHashSet和TreeSet深度解析

    這篇文章主要介紹了Java集合之Set、HashSet、LinkedHashSet和TreeSet深度解析,List是有序集合的根接口,Set是無(wú)序集合的根接口,無(wú)序也就意味著元素不重復(fù),更嚴(yán)格地說(shuō),Set集合不包含一對(duì)元素e1和e2 ,使得e1.equals(e2) ,并且最多一個(gè)空元素,需要的朋友可以參考下
    2023-09-09
  • 三道java新手入門(mén)面試題,通往自由的道路--多線程

    三道java新手入門(mén)面試題,通往自由的道路--多線程

    這篇文章主要為大家分享了最有價(jià)值的3道多線程面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,對(duì)hashCode方法的設(shè)計(jì)、垃圾收集的堆和代進(jìn)行剖析,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java解決刪除字符使頻率相同問(wèn)題

    Java解決刪除字符使頻率相同問(wèn)題

    給你一個(gè)下標(biāo)從0開(kāi)始的字符串 word ,字符串只包含小寫(xiě)英文字母,你需要選擇一個(gè)下標(biāo)并刪除下標(biāo)處的字符,使得word中剩余每個(gè)字母出現(xiàn)頻率相同,本文給大家介紹了Java解決刪除字符使頻率相同問(wèn)題,需要的朋友可以參考下
    2024-02-02
  • Java實(shí)現(xiàn)序列化與反序列化的簡(jiǎn)單示例

    Java實(shí)現(xiàn)序列化與反序列化的簡(jiǎn)單示例

    序列化與反序列化是指Java對(duì)象與字節(jié)序列的相互轉(zhuǎn)換,一般在保存或傳輸字節(jié)序列的時(shí)候會(huì)用到,下面有兩個(gè)Java實(shí)現(xiàn)序列化與反序列化的簡(jiǎn)單示例,不過(guò)還是先來(lái)看看序列和反序列化的具體概念:
    2016-05-05
  • 詳細(xì)全面解析Java泛型

    詳細(xì)全面解析Java泛型

    這篇文章主要介紹了詳細(xì)全面解析Java泛型,java泛型主要提高了Java 程序的類(lèi)型安全,通過(guò)知道使用泛型定義的變量的類(lèi)型限制,編譯器可以驗(yàn)證類(lèi)型假設(shè),消除源代碼中的許多強(qiáng)制類(lèi)型轉(zhuǎn)換等多個(gè)有點(diǎn),下面我們進(jìn)入文章了解更多的詳細(xì)內(nèi)容吧
    2022-02-02

最新評(píng)論