• 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;
        }
    }
  • 相关阅读:
    .NET 去除一段文本中的HTML标记
    C#实现控件拖动窗口
    使用window.showModalDialog弹出窗口返回值(兼容IE、FF、chrome)
    IE浏览器报错出现stack overflow at line 0的解决办法
    用Python作GIS:原料篇
    winform 自定义控件:半透明Loading控件
    WPF 跟随鼠标动画 by wgscd
    C# 多线程 HTTP request
    VS2015 安装XAN
    C# 用QQ企业邮箱发邮件
  • 原文地址:https://www.cnblogs.com/liuxm2017/p/11947629.html
Copyright © 2020-2023  润新知