SpringCloud 微服务 (十四) 服务网关 Zuul 过滤器(Pre&Post)

Easter79
• 阅读 450

上篇学习了zuul路由,这边继续学习,粗糙的记录zuul过滤器的用法

现在对请求url做个约定,在请求url上没有带参数key=123的url全部过滤掉

①localhost:7000/product/list?key=1234         ---不过滤

②localhost:7000/product/list                        ---过滤,不执行

完成以上功能,在gateway服务中,代码如下 : 

package com.cloud.gateway.filters;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 常量类
 * 过滤器状态 FilterConstants
 * 请求状态 HttpStatus
 * 引用其中的属性值即可,无需自己写
 */
@Component
public class PreFilter extends ZuulFilter {
    /**
     * filter类型
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * filter执行顺序,值越小优先级越高
     * 官方推荐使用x-1方式优先排序
     * @return
     */
    @Override
    public int filterOrder() {
        return PRE_DECORATION_FILTER_ORDER - 1;
    }

    /**
     * filter 开启关闭
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 实现filter逻辑
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletRequest request =requestContext.getRequest();
        String key=request.getParameter("key");

        //如果不存在,则设置没有权限不通过,状态为401
        if (StringUtils.isEmpty(key)){
            requestContext.setSendZuulResponse(false);
            requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
        }
        return null;
    }
}

浏览器访问成功则返回list列表,失败则返回错误页面,错误码:401

再来实现一个post过滤器,在得到结果之后,实现在post filter阶段,返回response的,给header头部加点信息,代码如下: 

package com.cloud.gateway.filters;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.POST_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SEND_RESPONSE_FILTER_ORDER;

/**
 * 常量类
 * 过滤器状态 FilterConstants
 * 请求状态 HttpStatus
 * 引用其中的属性值即可,无需自己写
 */
@Component
public class PostFilter extends ZuulFilter {
    /**
     * filter类型
     *
     * @return
     */
    @Override
    public String filterType() {
        return POST_TYPE;
    }

    /**
     * filter执行顺序,值越小优先级越高
     * 官方推荐使用x-1方式优先排序
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return SEND_RESPONSE_FILTER_ORDER - 1;
    }

    /**
     * filter 开启关闭
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 实现filter逻辑
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        HttpServletResponse response = requestContext.getResponse();
        response.setHeader("POST-UUID", UUID.randomUUID().toString());
        return null;
    }
}

浏览器控制台 请求信息 : 

SpringCloud 微服务 (十四) 服务网关 Zuul 过滤器(Pre&Post)

写了两次, 套路也都摸清了,能写的地方也就这么几个点,后面再做 限流 操作,结合上面学的,限流做在请求filter最靠前的地方,比鉴权pre前执行,不然流量都进去了,这里需要一个算法---令牌桶算法,这个算法很多地方已经实现了,拿来用即可,意思是以一定速率将令牌放入桶中,桶中的令牌满了,就不会再放进去了,外部的请求进入,请求将获得桶中的令牌,得令牌者可通行,没有令牌请求将被拒绝

下面代码实现 : 

package com.cloud.gateway.filters;

import com.cloud.gateway.exceptions.RateLimiterException;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;

/**
 * 限流
 */
@Component
public class RateLimiterFilter extends ZuulFilter {

    //create 每秒放入100个令牌
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(100);

    /**
     * filter类型
     *
     * @return
     */
    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * filter执行顺序,值越小优先级越高
     * 官方推荐使用x-1方式优先排序
     * 选择最高优先级SERVLET_DETECTION_FILTER_ORDER,并-1
     *
     * @return
     */
    @Override
    public int filterOrder() {
        return SERVLET_DETECTION_FILTER_ORDER - 1;
    }

    /**
     * filter 开启关闭
     *
     * @return
     */
    @Override
    public boolean shouldFilter() {
        return true;
    }

    /**
     * 实现filter逻辑
     *
     * @return
     * @throws ZuulException
     */
    @Override
    public Object run() throws ZuulException {
        //判断--获取通行令牌-->如果没有令牌不等于之前的没有权限401,可以抛出自定义异常或者其他处理
        if (!RATE_LIMITER.tryAcquire()) {
            throw new RateLimiterException();
        }

        return null;
    }
}

自定义异常: 

package com.cloud.gateway.exceptions;

public class RateLimiterException extends RuntimeException {
}

以上是过滤器的简单示例

还有一个Zuul关于鉴权的使用,涉及新建user服务,也会用到docker、redis,刚刚入手mac,上面什么都没有,装好了再继续下面的学习实践

---------------------------------------------------------

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Nepxion Discovery 5.5.0 发布
!(https://oscimg.oschina.net/oscnet/f81c043194ef4732880459d00c1a720e.png)发布日志功能更新:增加基于Opentracing调用链的支持,目前支持UberJaeger,实现在SpringCloudGateway、Zuul和服务上的灰度
Easter79 Easter79
2年前
SpringCloud之zuul搭建
一、zuul简介Zuul的主要功能是路由和过滤器。路由功能是微服务的一部分,比如/api/user映射到user服务,/api/shop映射到shop服务。zuul实现了负载均衡。zuul有以下功能:AuthenticationInsightsStressTestingCanaryTesting
Easter79 Easter79
2年前
SpringCloud微服务(05):Zuul组件,实现路由网关控制
一、Zuul组件简介1、基础概念Zuul网关主要提供动态路由,监控,弹性,安全管控等功能。在分布式的微服务系统中,系统被拆为了多个微服务模块,通过zuul网关对用户的请求进行路由,转发到具体的后微服务模块中。2、Zuul的作用1)按照不同策略,将请求转发到不同的服务上去;
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Easter79 Easter79
2年前
SpringCloud 微服务 (十三) 服务网关 Zuul 路由
壹本篇延续上篇Zuul基础学习,做一个实践测试在之前学习的篇章中,一直积累学习,所以这边已经存在注册中心,product服务,order服务,config配置中心等等服务,每次写demo,注册中心和配置中心都是一直先启动,本次学习Zuul也不例外贰新建一个服务,第一步利用IDEA创建!(https://oscimg.osch
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k