SpringCloud-網關ZUUL

SpringCloud-網關ZUUL

項目結構

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

父工程(每一個服務都是一個子工程)

  1. pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.xiaoge.demo</groupId>
        <artifactId>zuul-demo</artifactId>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>user-service</module>
            <module>consumer-demo</module>
            <module>eureka-server</module>
            <module>gateway</module>
        </modules>
        <packaging>pom</packaging>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.4.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring-cloud.version>Finchley.SR1</spring-cloud.version>
            <mapper.starter.version>2.0.3</mapper.starter.version>
            <mysql.version>5.1.32</mysql.version>
        </properties>
    
        <dependencyManagement> <!-- 所有子工程, 必須引下面的依賴纔會有 -->
            <dependencies>
                <!-- spring cloud 引用了它, 以後cloud依賴版本就不用寫了 -->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring-cloud.version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
    
                <!-- 通用Mapper啓動器 -->
                <dependency>
                    <groupId>tk.mybatis</groupId>
                    <artifactId>mapper-spring-boot-starter</artifactId>
                    <version>${mapper.starter.version}</version>
                </dependency>
    
                <!-- mysql驅動 -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>
    
            </dependencies>
        </dependencyManagement>
    
        <dependencies> <!-- 因爲不會再dependencyManagement標籤裏, 所以所有的子工程都可以用 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

consumer-demo服務

  1. 配置文件

    1. pom.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>zuul-demo</artifactId>
              <groupId>com.xiaoge.demo</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>consumer-demo</artifactId>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
      
              <!-- 引入eureka客戶端依賴 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
              </dependency>
      
              <!-- 導入hystrix依賴 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
              </dependency>
      
              <!-- 引入feign依賴 裏面自帶hystrix熔斷器基本依賴(所以我這裏還是需要導入hystrix-SpringCloud相關的依賴)和ribbon負載均衡依賴 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-openfeign</artifactId>
              </dependency>
      
          </dependencies>
      
      </project>
      
    2. application.yml

      server:
        port: 8088
      spring:
        # 在eureka中註冊的服務名稱
        application:
          name: consumer-service
      
      # 註冊方
      # eureka配置 因爲它要去註冊中心註冊, 所以要配置
      eureka:
        client:
          service-url:
            defaultZone: http://127.0.0.1:10086/eureka, http://127.0.0.1:10087/eureka # 配置所有的eureka地址, 防止其中一個eureka掛掉
          registry-fetch-interval-seconds: 3 # 設置拉取服務列表的週期 爲3秒
          fetch-registry: true # 默認爲true 拉取列表, 改爲false 不拉取
        instance:
          prefer-ip-address: true # 我希望使用ip地址
          ip-address: 127.0.0.1 # 設置ip地址
      
      # 開啓feign裏面的hystrix
      feign:
        hystrix:
          enabled: true
      
      # feign裏面的ribbon配置
      ribbon:
        # 連接超時時長 500毫秒, 500毫秒沒建立連接, 拋出異常
        ConnectionTimeOut: 500
        # 讀取超時時長 2秒, 2秒沒有讀取到數據, 拋出異常
        ReadTimeOut: 2000
      
      # 設置 hystrix默認指令
      hystrix:
        command:
          default:
            execution:
              isolation:
                thread:
                  timeoutInMilliseconds: 3000  # 設置全局方法 的 超時 時間 爲 3秒  超過  3秒  執行錯誤方法
      
  2. 啓動類

    1. ConsumerApplication

      package com.xiaoge;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.cloud.client.SpringCloudApplication;
      import org.springframework.cloud.openfeign.EnableFeignClients;
      
      /**
       * @program: cloud-demo
       * @description: 服務調用方
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:04
       **/
      // @EnableCircuitBreaker // hystrix註解
      // @EnableDiscoveryClient // 它也是客戶端, 它捷能兼容eureka 又能consul、zookeeper等等, 更通用, 更廣泛
      // @SpringBootApplication
      
      @EnableFeignClients  // feign註解-開啓feign功能
      @SpringCloudApplication // 它的功能就是上面三個註解的功能
      public class ConsumerApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(ConsumerApplication.class);
          }
      
      }
      
  3. 實體類

    1. User

      package com.xiaoge.Consumer.pojo;
      
      import lombok.Data;
      
      import java.io.Serializable;
      import java.util.Date;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:06
       **/
      @Data
      public class User implements Serializable {
          // 主鍵
          private Long id;
      
          // 用戶名
          private String username;
      
          // 密碼
          private String password;
      
          // 姓名
          private String name;
      
          // 年齡
          private Integer age;
      
          // 性別,1男性,2女性
          private Integer sex;
      
          // 出生日期
          private Date birthday;
      
          // 創建時間
          private Date created;
      
          // 更新時間
          private Date updated;
      
          // 備註
          private String note;
      
      }
      
  4. Feign客戶端

    1. UserClient接口

      package com.xiaoge.Consumer.client;
      
      import com.xiaoge.Consumer.pojo.User;
      import org.springframework.cloud.openfeign.FeignClient;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      
      /**
       * @program: feign_demo
       * @description: 告訴feign 請求服務 請求方式 請求路徑 請求參數 返回結果
       * @author: Mr.Xiao
       * @create: 2020-05-18 20:43
       **/
      @FeignClient(value = "user-service", fallback = UserClientFallback.class) // 告訴feign服務名稱, 告訴feign方法異常要執行的類
      public interface UserClient {
      
          @GetMapping("user/{id}")
          User queryById(@PathVariable("id") Long id);
      
      }
      
    2. UserClientFallback實現類

      package com.xiaoge.Consumer.client;
      
      import com.xiaoge.Consumer.pojo.User;
      import org.springframework.stereotype.Component;
      
      /**
       * @program: feign_demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-18 21:07
       **/
      @Component
      public class UserClientFallback implements UserClient {
      
          /**
           * 寫熔斷的業務邏輯
           * @param id
           * @return
           */
          @Override
          public User queryById(Long id) {
              User user = new User();
              user.setUsername("未知用戶!");
              return user;
          }
      }
      
      
  5. 表現層

    1. ConsumerController

      package com.xiaoge.Consumer.controller;
      
      import com.xiaoge.Consumer.client.UserClient;
      import com.xiaoge.Consumer.pojo.User;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      
      /**
       * @program: cloud-demo
       * @description: 動態拉取服務列表
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:08
       **/
      @RestController
      @RequestMapping("/consumer")
      public class ConsumerController {
      
          @Autowired
          private UserClient userClient;
      
          @GetMapping("/{id}")
          public User queryById(@PathVariable("id") Long id){
              // 1. 引入feign依賴
      
              // 2. 在啓動器上加上feign註解 @EnableFeignClients
      
              // 3. 編寫UserClient接口, 用spring mvc的註解方式告訴feign 請求服務 請求方式 請求路徑 請求參數 返回結果
      
              // 4. 調用
              return userClient.queryById(id);
          }
      
      }
      

eureka-server服務

  1. 配置文件

    1. pom.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>zuul-demo</artifactId>
              <groupId>com.xiaoge.demo</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>eureka-server</artifactId>
      
          <dependencies>
              <!-- springcloud 註冊中心 eureka -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
              </dependency>
          </dependencies>
      
      </project>
      
    2. application.yml

      # 這是eureka的默認端口號
      server:
        port: 10086
      
      # 配置eureka服務名稱
      spring:
        application:
          name: eureka-server
      
      # 註冊方
      # 告訴eureka要註冊的地址在哪裏 (這樣eureka就不會報一個com.sun.jersey.api.client.ClientHandlerException異常)
      eureka:
        client:
          service-url:
            defaultZone: http://127.0.0.1:10086/eureka # 配置所有的eureka地址, 防止其中一個eureka掛掉
          register-with-eureka: false  # 默認爲true 註冊自己, 改爲false 不 註冊自己
        instance:
          prefer-ip-address: true # 我希望使用ip地址
          ip-address: 127.0.0.1 # 設置ip地址
        server:
          eviction-interval-timer-in-ms: 60000 # 設置eureka失效剔除時長, 每隔60秒失效剔除一次, 失效剔除掛掉的eureka
      
  2. 啓動類

    1. EurekaServer

      package com.xiaoge;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
      
      /**
       * @program: cloud-demo
       * @description: EurekaServer端
       * @author: Mr.Xiao
       * @create: 2020-05-04 16:34
       **/
      @EnableEurekaServer // 啓動Eureka服務
      @SpringBootApplication
      public class EurekaServer {
      
          public static void main(String[] args) {
              SpringApplication.run(EurekaServer.class);
          }
      
      }
      

user-service服務

  1. 配置文件

    1. pom.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>zuul-demo</artifactId>
              <groupId>com.xiaoge.demo</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>user-service</artifactId>
      
          <dependencies>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              </dependency>
      
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>8.0.13</version>
              </dependency>
      
              <dependency>
                  <groupId>tk.mybatis</groupId>
                  <artifactId>mapper-spring-boot-starter</artifactId>
              </dependency>
      
              <!-- 引入eureka(註冊中心)-客戶端 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
              </dependency>
          </dependencies>
      
      </project>
      
    2. application.yml

      server:
        port: 9090
      spring:
        # 在eureka中註冊的服務名稱
        application:
          name: user-service
        # 數據庫連接信息配置
        datasource:
          url: jdbc:mysql://localhost:3306/yun6
          username: root
          password: 123456
          hikari:
            maximum-pool-size: 20
            minimum-idle: 10
      # 別名包
      mybatis:
        type-aliases-package: com.xiaoge.user.pojo
      
      # 註冊方
      # eureka配置 因爲它要去註冊中心註冊, 所以要配置
      eureka:
        client:
          service-url:
            defaultZone: http://127.0.0.1:10086/eureka, http://127.0.0.1:10087/eureka # 配置所有的eureka地址, 防止其中一個eureka掛掉
        instance:
          prefer-ip-address: true # 我希望使用ip地址
          ip-address: 127.0.0.1 # 設置ip地址
          lease-renewal-interval-in-seconds: 30 # 每隔30秒發一次心跳
          lease-expiration-duration-in-seconds: 90 # 每隔30秒發一次心跳, 如果隔了90秒都沒發, 那就證明掛了
      
  2. 啓動類

    1. UserApplication

      package com.xiaoge;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
      import tk.mybatis.spring.annotation.MapperScan;
      
      /**
       * @program: cloud-demo
       * @description: 服務的提供方
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:43
       **/
      @EnableDiscoveryClient // 它也是客戶端, 它捷能兼容eureka 又能consul、zookeeper等等, 更通用, 更廣泛
      @SpringBootApplication
      @MapperScan("com.xiaoge.user.mapper")
      public class UserApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(UserApplication.class);
          }
      
      }
      
  3. 實體類

    1. User

      package com.xiaoge.user.pojo;
      
      import lombok.Data;
      import tk.mybatis.mapper.annotation.KeySql;
      
      import javax.persistence.Id;
      import javax.persistence.Table;
      import java.io.Serializable;
      import java.util.Date;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:46
       **/
      @Table(name = "tb_user")
      @Data
      public class User implements Serializable {
      
          @Id
          @KeySql(useGeneratedKeys = true) // id自動增長
          private Long id;
      
          // 用戶名
          private String username;
      
          // 密碼
          private String password;
      
          // 姓名
          private String name;
      
          // 年齡
          private Integer age;
      
          // 性別,1男性,2女性
          private Integer sex;
      
          // 出生日期
          private Date birthday;
      
          // 創建時間
          private Date created;
      
          // 更新時間
          private Date updated;
      
          // 備註
          private String note;
      
      }
      
  4. 表現層

    1. UserController

      package com.xiaoge.user.controller;
      
      import com.xiaoge.user.pojo.User;
      import com.xiaoge.user.service.UserService;
      import org.apache.tomcat.jni.Time;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:51
       **/
      @RestController
      @RequestMapping("/user")
      public class UserController {
      
          @Autowired
          private UserService userService;
      
          @GetMapping("/{id}")
          public User queryById(@PathVariable("id") Long id) {
              User user = userService.queryById(id);
              return user;
          }
      
      }
      
  5. 業務層

    1. UserService接口

      package com.xiaoge.user.service;
      
      import com.xiaoge.user.pojo.User;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:50
       **/
      public interface UserService {
      
          public User queryById(Long id);
      
      }
      
    2. UserServiceImpl實體類

      package com.xiaoge.user.service.impl;
      
      import com.xiaoge.user.mapper.UserMapper;
      import com.xiaoge.user.pojo.User;
      import com.xiaoge.user.service.UserService;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:51
       **/
      @Service
      public class UserServiceImpl implements UserService {
      
          @Autowired
          private UserMapper userMapper;
      
          @Override
          public User queryById(Long id) {
              return userMapper.selectByPrimaryKey(id);
          }
      }
      
  6. Mapper

    1. UserMapper

      package com.xiaoge.user.mapper;
      
      
      import com.xiaoge.user.pojo.User;
      import tk.mybatis.mapper.common.Mapper;
      
      /**
       * @program: cloud-demo
       * @description:
       * @author: Mr.Xiao
       * @create: 2020-05-04 15:49
       **/
      
      public interface UserMapper extends Mapper<User> {
      }
      

gateway網關

  1. 配置文件

    1. pom.xml

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <parent>
              <artifactId>zuul-demo</artifactId>
              <groupId>com.xiaoge.demo</groupId>
              <version>1.0-SNAPSHOT</version>
          </parent>
          <modelVersion>4.0.0</modelVersion>
      
          <artifactId>gateway</artifactId>
      
          <dependencies>
      
              <!-- 引入eureka依賴 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
              </dependency>
      
              <!-- 引入zuul依賴 -->
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
              </dependency>
          </dependencies>
      
      
      </project>
      
    2. application.yml

      server:
        port: 10010
      spring:
        # 在eureka中註冊的服務名稱
        application:
          name: gateway
      
      # 從eureka中拉取服務列表
      eureka:
        client:
          service-url:
            defaultZone: http://127.0.0.1:10086/eureka
      
      # 配置路由規則
      # zuul:
      #   routes:
      #     user-service: # 是個map結構, 鍵是個字符串可以隨便寫, 不重複就行, 所以我這裏寫了個hehe, 值是路由規則
      #       path: /user-server/** # 路由規則
      #       serviceId: user-service  # 應用id
      # 當用戶請求到達, 首先匹配路徑, 匹配成功轉發到user-service服務,
      # 底層調用eureka拉去服務列表, 然後利用負載均衡算法, 動態從裏面獲取一個地址
      
      
      # 簡化寫法
      # zuul:
      #   routes:
      #     user-service: /user-service/** # key是服務的id, value是這個服務的映射路徑
      
      
      
      # 重點: 但是zuul 默認是把每一個微服務都是這樣配置的, 你不配置, 默認這樣的路徑, 也是可以訪問到每一個微服務的(但是這樣每一個微服務都對外暴露了)
      
      # zuul:
      #   routes:
      #     user-service:
      #       path: /user/** # 服務映射路徑
      #       serviceId: user-service # 服務名稱
      #       strip-prefix: false # 忽略前綴, 默認爲true 忽略前綴以後就不用寫重複的了 列(/user/9, 不忽略, 你訪問要/user/user/9, 忽略, user/9)
        # 配置忽略的服務(不對外暴露的服務) 是一個集合, 可以把不想暴露的微服務都這樣配置下去
      #   ignored-services:
      #     - consumer-service # consumer-service不對外暴露
      
      
      zuul:
        prefix: /api # 配置全局前綴, 訪問時必須攜帶前綴
        routes:
          user-service:
            path: /user/** # 服務映射路徑
            serviceId: user-service # 服務名稱
            strip-prefix: false
        # 配置忽略的服務(不對外暴露的服務) 是一個集合, 可以把不想暴露的微服務都這樣配置下去
        ignored-services:
          - consumer-service # consumer-service不對外暴露
      
      # 設置熔斷超時時間, 訪問時超過6秒沒反應, 直接報錯
      hystrix:
        command:
          default:
            execution:
              isolation:
                thread:
                  timeoutInMilliseconds: 6000
      
      
      ribbon:
        # 請求連接的超時時間
        ConnectTimeout: 500
        # 讀取超時時長
        ReadTimeout: 2000
        # 設置從新訪問次數爲0, 這樣連接不上時, 不會重新發起連接(不重試)
        MaxAutoRetriesNextServer: 0
      
      
      # 注意: ribbon的超時時長, 真實值(read + connect) * 2, 必須小於hystrix時長.
      
      # 源碼: 計算公式  ribbonTimeout = (ribbonReadTimeout + ribbonConnectTimeout) * (maxAutoRetries + 1) * (maxAutoRetriesNextServer + 1);
      
  2. 啓動類

    1. GatewayApplication

      package com.xiaoge;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
      
      /**
       * @Author: 瀟哥
       * @DateTime: 2020/5/19 下午8:58
       * @Description: zuul啓動器
       */
      @EnableZuulProxy // 引入zuul註解
      @SpringBootApplication
      public class GatewayApplication {
      
          public static void main(String[] args) {
              SpringApplication.run(GatewayApplication.class);
          }
      
      }
      
  3. 自定義過濾器

    1. LoginFilter

      package com.xiaoge.filter;
      
      import com.netflix.zuul.ZuulFilter;
      import com.netflix.zuul.context.RequestContext;
      import com.netflix.zuul.exception.ZuulException;
      import org.apache.commons.lang.StringUtils;
      import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
      import org.springframework.http.HttpStatus;
      import org.springframework.stereotype.Component;
      
      import javax.servlet.http.HttpServletRequest;
      
      /**
       * @Author: 瀟哥
       * @DateTime: 2020/5/21 下午8:22
       * @Description: 自定義過濾器
       */
      @Component
      public class LoginFilter extends ZuulFilter {
          /**
           * 過濾器類型
           * pre: 請求在被路由之前執行
           * routing: 在路由請求時調用
           * post: 在routing和error過濾器之後調用
           * error: 處理請求時發生錯誤調用
           * @return
           */
          @Override
          public String filterType() {
              return FilterConstants.PRE_TYPE; // 設置爲前置 pre 這是個常量
          }
      
          /**
           * 過濾器順序
           * 通過返回的int值來定義過濾器的執行順序, 數字越小優先級越高
           * @return
           */
          @Override
          public int filterOrder() {
              return FilterConstants.PRE_DECORATION_FILTER_ORDER - 1; // 請求參數處理完, 然後攔截
          }
      
          /**
           * 要不要過濾
           * 返回一個boolean值, 判斷該過濾器是否需要執行. 返回true執行, 返回false不執行.
           * @return
           */
          @Override
          public boolean shouldFilter() {
              return true;
          }
      
          /**
           * 過濾邏輯
           * 過濾器的具體業務邏輯
           * @return
           * @throws ZuulException
           */
          @Override
          public Object run() throws ZuulException {
      
              // 獲取請求上下文
              RequestContext ctx = RequestContext.getCurrentContext();
      
              // 獲取request
              HttpServletRequest request = ctx.getRequest();
      
              // 獲取請求參數access-token
              String token = request.getParameter("access-token");
      
              // 判斷是否存在
              if (StringUtils.isBlank(token)) {
                  // 不存在, 未登入, 則攔截
                  ctx.setSendZuulResponse(false); // 爲true放行, 爲false攔截, 默認爲true
                  ctx.setResponseStatusCode(HttpStatus.FORBIDDEN.value()); // 狀態碼, 設置爲403
              }
      
              return null;
          }
      }
      
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章