天天看點

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初識篇—過濾器細節