zoukankan      html  css  js  c++  java
  • SpringCloud之Zuul 自定义filter

    实现过滤器很简单,只需要继承ZuulFilter,并实现ZuulFilter中的抽象方法。

    filterType():定义过滤器的类型,它有4种类型,分别是pre、post、routing和error
    filterOrder():过滤顺序,它是一个Int类型的值,值越小,越早执行该过滤器
    shouldFilter():表示该过滤器是否过滤逻辑,如果为true,则执行run方法,如果为false,则不执行run方法
    Object run():写具体的过滤逻辑

    注意重要说明,有些版本在转发post时,文件上传无法转法。只要升级下版本就可以了。

    本示中使用的是 springcloud    Edgware.RELEASE 对应springboot1.5.9

    Spring Boot Spring Cloud
    1.2.x Angel版本
    1.3.x  Brixton版本
    1.4.xstripes Camden版本
    1.5.x  Dalston版本、Edgware版本
    2.0.x Finchley版本
    2.1.x   Greenwich.SR2

     

    示例

    1.pom中引用

    <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.company</groupId>
        <artifactId>zuuldemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <name>zuuldemo</name>
        <url>http://maven.apache.org</url>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
        <parent>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-parent</artifactId>
            <version>Edgware.RELEASE</version>
            <relativePath></relativePath>
        </parent>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-zuul</artifactId>
            </dependency>
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.58</version>
            </dependency>
        </dependencies>
    </project>

    2.springcloud项目

    2.1 src/main/resources/application.yml

    server:
       port: 80
    spring:
       application:
          name: api-geteway
       http:
          multipart:
             enabled: true # 使用http multipart上传处理
             file-size-threshold: 1MB # 当上传文件达到1MB的时候进行磁盘写入
             max-request-size: 10MB # 设置最大的请求文件的大小
             max-file-size: 10MB # 设置单个文件的最大长度
    zuul:
       routes:
          weixin:
             path: /mypath/**
             url: https://www.baidu.com

    2.2 App.java

    package com.company.zuuldemo;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    import org.springframework.context.annotation.Bean;
    
    import com.company.zuuldemo.filter.MyFilter;
    
    /**
     * Hello world!
     *
     */
    @EnableZuulProxy
    @SpringBootApplication
    public class ZuulApp {
    
        //使用filter
        @Bean
        public MyFilter myFilter() {
            return new MyFilter();
        }
    
    //    @Bean
    //    public FirstFilter firstFilter() {
    //        return new FirstFilter();
    //    }
    //
    //    @Bean
    //    public SecondFilter secondFilter() {
    //        return new SecondFilter();
    //    }
    
        public static void main(String[] args) {
            // System.out.println( "Hello World!" );
            SpringApplication.run(ZuulApp.class);
        }
    }

    2.3 MyFilter.java

     

    package com.company.zuuldemo.filter;
    
    import java.util.Arrays;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    
    public class MyFilter extends ZuulFilter {
    
        final static Logger logger = LoggerFactory.getLogger(FirstFilter.class);
    
        // 这里可以依据url规则判断是否需要进行过滤 true需要过滤进入run方法 ,false直接忽略
        public boolean shouldFilter() {
            RequestContext ctx = RequestContext.getCurrentContext();
            logger.info(ctx.getRequest().getRequestURI() + " get request path info");
            String url = ctx.getRequest().getRequestURI().toLowerCase();
    
            // 这里判断url逻辑
            if (url.startsWith("/login")) {
                return false;
            }
    
            return true;
        }
    
        public Object run() {
    
            RequestContext ctx = RequestContext.getCurrentContext();
    
            // 通过其它业务生成token
            String access_token = "user_name_token";
    
            // 使用1 :向request的header中增加参数access_token
            ctx.addZuulRequestHeader("access_token", access_token);
    
            // 使用2:向request的url里增加参数,示例增加 access_token
            Map<String, List<String>> requestQueryParams = ctx.getRequestQueryParams();
            if (requestQueryParams == null) {
                requestQueryParams = new HashMap<>();
            }
    
            requestQueryParams.put("access_token", Arrays.asList(access_token));
    
            ctx.setRequestQueryParams(requestQueryParams);
    
            //使用3 ::判断是否登录,如果未登录直接返回404
            if (access_token == null || access_token.trim().length() == 0) {
                //过滤该请求,不对其进行路由(直接输入返回)
                ctx.setSendZuulResponse(false);
                //返回错误码
                ctx.setResponseStatusCode(401);
                // 返回错误内容
                ctx.setResponseBody("{"result":"access_token is not correct!"}");
                
                //让下一个Filter看到上一个Filter的状态用于过滤器间的协调
                ctx.set("my_filter_is_success", false);
                return null; 
            }
    
            // 对该请求进行路由(默认就是true)
            //ctx.setSendZuulResponse(true);
            //ctx.setResponseStatusCode(200);
            //让下一个Filter看到上一个Filter的状态用于过滤器间的协调
            ctx.set("my_filter_is_success", false);
    
            return null; //直接返回null即可
        }
    
        @Override
        public String filterType() {
            // 前置过滤器
            //pre:可以在请求被路由之前调用
            //route:在路由请求时候被调用
            //post:在route和error过滤器之后被调用
            //error:处理请求时发生错误时被调用
            return "pre";
        }
    
        @Override
        public int filterOrder() {
            //优先级为0,数字越大,优先级越低  
            return 0;
        }
    }
  • 相关阅读:
    Leetcode 191.位1的个数 By Python
    反向传播的推导
    Leetcode 268.缺失数字 By Python
    Leetcode 326.3的幂 By Python
    Leetcode 28.实现strStr() By Python
    Leetcode 7.反转整数 By Python
    Leetcode 125.验证回文串 By Python
    Leetcode 1.两数之和 By Python
    Hdoj 1008.Elevator 题解
    TZOJ 车辆拥挤相互往里走
  • 原文地址:https://www.cnblogs.com/liuxm2017/p/11947629.html
Copyright © 2011-2022 走看看