天天看点

springcloud之Zuul初识篇—过滤器细节

1、过滤器校验禁止向业务服务请求

@Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        Boolean flag = true;
        //设置不在向下执行请求
        requestContext.setSendZuulResponse(false);
        requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
        //返回给客户端的信息
        requestContext.setResponseBody("未获取到令牌请重试!");
        return null;
    }
           

PS: 在pre类型或route中filterOrder的<=9时,设置requestContext.setSendZuulResponse(false);网关不会调用业务服务。

2、某过滤器设置setSendZuulResponse(false)后,后续自定义过滤器不在执行业务逻辑。

//第一个过滤器 
public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        Boolean flag = true;
        //设置标记,告诉下一个过滤器是否要执行业务逻辑
        requestContext.set("f",flag);
        requestContext.setSendZuulResponse(false);
        requestContext.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());
        requestContext.setResponseBody("未获取到令牌请重试!");
        return null;
    }
-----------------------------------------------
//第二个过滤器
    @Override
    public boolean shouldFilter() {
        RequestContext requestContext = getCurrentContext();
        //获取上一个过滤器赋值的标记,判断是否需要执行当前过滤器的业务逻辑
        boolean flag = (Boolean) requestContext.get("f");
        if(!flag){
            return flag;
        }
        return flag;
    }
           

PS:通过业务代码中设计标记动态控制过滤器是否执行

3、请求业务服务时添加参数

@Override
    public Object run() throws ZuulException {
        try {
            RequestContext requestContext = RequestContext.getCurrentContext();
            InputStream in = (InputStream) requestContext.get("requestEntity");
            if(null==in){
                in =requestContext.getRequest().getInputStream();
            }
            //原有信息从流中拿出来转化成字符串
            String body = StreamUtils.copyToString(in,Charset.forName("utf-8"));
            //这里转化成json,在json中添加信息(如:用户名称、id等)
            JSONObject jsonObject =  JSONObject.parseObject(body);
            jsonObject.put("uesrName","Niki");
            body = jsonObject.toJSONString();
            //将调整后的信息转成流赋给request
            byte[] bytes = body.getBytes("utf-8");
            requestContext.setRequest(new HttpServletRequestWrapper(RequestContext.getCurrentContext().getRequest()) {
                @Override
                public ServletInputStream getInputStream() throws IOException {
                    return new ServletInputStreamWrapper(bytes);
                }

                @Override
                public int getContentLength() {
                    return bytes.length;
                }

                @Override
                public long getContentLengthLong() {
                    return bytes.length;
                }
            });
        }catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }
           
springcloud之Zuul初识篇—过滤器细节

4、返回客户端时添加参数(如:一次性的token令牌)

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.nio.charset.Charset;
import java.util.UUID;


@Component
public class PostFristFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 2;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        try {
            HttpServletResponse servletResponse = requestContext.getResponse();
            //给返回的请求头添加信息
            servletResponse.addHeader("X-Foo",UUID.randomUUID().toString());
            String body =  StreamUtils.copyToString(requestContext.getResponseDataStream(),Charset.forName("utf-8"));
            /*JSONObject jsonObject =  JSONObject.parseObject(body);
            jsonObject.put("token","12345");*/
            body= body+"  添加postFilter信息";
            //两种方式都可以返回
            //requestContext.setResponseBody(body);
            requestContext.setResponseDataStream(new ByteArrayInputStream(body.getBytes("UTF-8")));
        }catch (Exception e){
            throw  new ZuulException(e.getMessage(),500,e.toString());
        }

        return null;
    }
}
           
springcloud之Zuul初识篇—过滤器细节