Zuul是Netflix出品的一個基於JVM路由和服務端的負載均衡器.
Zuul功能:
Zuul的規則引擎允許通過任何JVM語言來編寫規則和過濾器, 支持基於Java和Groovy的構建。
配置屬性zuul.max.host.connections 已經被兩個新的配置屬性替代, zuul.host.maxTotalConnections (總連接數)和zuul.host.maxPerRouteConnections,(每個路由連接數) 默認值分別是200和20.
一. 為什麼要用到這個
在基於springcloud 構建的微服務系統中,通常使用網關zuul來進行一些用戶驗證等過濾的操作,比如用戶在header 或者url 參數中存放了token ,網關層需要用該token 查出用戶的userId ,並存放於request 中,以便後續微服務可以直接使用而避免再去用token 查詢。
二.基礎知識
在zuul 中最大的用法的除了路由之外,就是過濾器了,自定義過濾器需實現接口ZuulFilter ,在run() 方法中,可以用
RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest();
獲取到request,但是在request 中只有getParameter() 而沒有setParameter() 方法,所以直接修改url 參數不可行,另外在reqeust 中可以雖然可以使用setAttribute() ,但是可能由於作用域的不同,在這裡設置的attribute 在後續的微服務中是獲取不到的,因此必須考慮另外的方式。
三.具體做法
最後確定的可行的方法是,用
ctx.setRequest(new HttpServletRequestWrapper(request) {})的方式,重新構造上下文中的request ,代碼如下:
import javax.servlet.http.HttpServletRequestWrapper; // 在json參數中添加userId try { InputStream in = ctx.getRequest().getInputStream(); String body = StreamUtils.copyToString(in, Charset.forName("UTF-8")); System.out.println("body:" + body); JSONObject json = JSONObject.fromObject(body); json.put("userId", userId); String newBody = json.toString(); System.out.println("newBody:" + newBody); final byte[] reqBodyBytes = newBody.getBytes(); ctx.setRequest(new HttpServletRequestWrapper(request){ @Override public ServletInputStream getInputStream() throws IOException { return new ServletInputStreamWrapper(reqBodyBytes); } @Override public int getContentLength() { return reqBodyBytes.length; } @Override public long getContentLengthLong() { return reqBodyBytes.length; } }); } catch (IOException e) { e.printStackTrace(); }思路就是,獲取請求的輸入流,並重寫,即重寫json參數。
在後續的微服務的controller 中,可以用形似
@RequestBody Map<String,Object> body ======= body.get("userId");這樣的方式,去獲取在zuulFilter 傳入的userId
四.一些嘗試
在重寫HttpServletRequestWrapper 的時候,我嘗試過重寫getParameterNames()和getParameterMap()方法,希望重寫url 參數,但是並沒有生效。
總結
以上所述是小編給大家介紹的springcloud 中zuul 修改請求參數信息的方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!