1. 程式人生 > >spring cloud zuul進行服務攔截

spring cloud zuul進行服務攔截

服務閘道器zuul還有個作用就是介面的安全性校驗,這個時候我們就需要通過 zuul 進行統一攔截,zuul 通過繼承過濾器 ZuulFilter 進行處理,下面請看具體用法。

新建一個類 ApiFilter 並繼承 ZuulFilter:

@Component
public class ApiFilter extends ZuulFilter {

@Override
public String filterType() {
    return "pre";
}

@Override
public int filterOrder() {
    return 0;
}

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

@Override
public Object run() {
    //這裡寫校驗程式碼
    return null;
}

}
其中:

filterType 為過濾型別,可選值有 pre(路由之前)、routing(路由之時)、post(路由之後)、error(發生錯誤時呼叫)。
filterOrdery 為過濾的順序,如果有多個過濾器,則數字越小越先執行
shouldFilter 表示是否過濾,這裡可以做邏輯判斷,true 為過濾,false 不過濾
run 為過濾器執行的具體邏輯,在這裡可以做很多事情,比如:許可權判斷、合法性校驗等。
下面,我們來做一個簡單的安全驗證:

@Override
public Object run() {
//這裡寫校驗程式碼
RequestContext context = RequestContext.getCurrentContext();
HttpServletRequest request = context.getRequest();
String token = request.getParameter(“token”);
if(!“12345”.equals(token)){
context.setSendZuulResponse(false);
context.setResponseStatusCode(401);
try {
context.getResponse().getWriter().write(“token is invalid.”);
}catch (Exception e){}
}
return null;
}
啟動 gateway,在瀏覽器輸入地址:

http://localhost:8080/api/index,可以看到以下介面:

這裡寫圖片描述

再通過瀏覽器輸入地址:http://localhost:8080/api/index?token=12345,可以看到以下介面:

這裡寫圖片描述

錯誤攔截
在一個大型系統中,服務是部署在不同的伺服器下面的,我們難免會遇到某一個服務掛掉或者請求不到的時候,如果不做任何處理,服務閘道器請求不到會丟擲500錯誤,對使用者是不友好的。

我們為了提供使用者的友好性,需要返回友好性提示,zuul 為我們提供了一個名叫 ZuulFallbackProvider 的介面,通過它我們就可以對這些請求不到的服務進行錯誤處理。

新建一個類 ApiFallbackProvider 並且實現 ZuulFallbackProvider 介面:

Component
public class ApiFallbackProvider implements ZuulFallbackProvider{

@Override
public String getRoute() {
    return "eurekaclient";
}

@Override
public ClientHttpResponse fallbackResponse() {
    return new ClientHttpResponse() {
        @Override
        public HttpStatus getStatusCode() throws IOException {
            return HttpStatus.OK;
        }

        @Override
        public int getRawStatusCode() throws IOException {
            return 200;
        }

        @Override
        public String getStatusText() throws IOException {
            return "{code:0,message:\"伺服器異常!\"}";
        }

        @Override
        public void close() {

        }

        @Override
        public InputStream getBody() throws IOException {
            return new ByteArrayInputStream(getStatusText().getBytes());
        }

        @Override
        public HttpHeaders getHeaders() {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            return headers;
        }
    };
}

其中,getRoute 方法返回要處理錯誤的服務名,fallbackResponse 方法返回錯誤的處理規則。

現在開始測試這部分程式碼,首先停掉服務提供者 eurekaclient,再重啟 gateway,請求地址:http://localhost:8080/api/index?token=12345,即可出現以下介面:

這裡寫圖片描述