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?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,即可出現以下介面:
這裡寫圖片描述