W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
下面的大多數(shù)“如何編寫”示例都包含在示例Zuul過(guò)濾器項(xiàng)目中。在該存儲(chǔ)庫(kù)中也有一些處理請(qǐng)求或響應(yīng)正文的示例。
前置過(guò)濾器可在RequestContext
中設(shè)置數(shù)據(jù),以便在下游的過(guò)濾器中使用。主要用例是設(shè)置路由過(guò)濾器所需的信息。以下示例顯示了Zuul前置過(guò)濾器:
public class QueryParamPreFilter extends ZuulFilter { @Override public int filterOrder() { return PRE_DECORATION_FILTER_ORDER - 1; // run before PreDecoration } @Override public String filterType() { return PRE_TYPE; } @Override public boolean shouldFilter() { RequestContext ctx = RequestContext.getCurrentContext(); return !ctx.containsKey(FORWARD_TO_KEY) // a filter has already forwarded && !ctx.containsKey(SERVICE_ID_KEY); // a filter has already determined serviceId } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); HttpServletRequest request = ctx.getRequest(); if (request.getParameter("sample") != null) { // put the serviceId in `RequestContext` ctx.put(SERVICE_ID_KEY, request.getParameter("foo")); } return null; } }
前面的過(guò)濾器從sample
請(qǐng)求參數(shù)中填充SERVICE_ID_KEY
。實(shí)際上,您不應(yīng)該執(zhí)行這種直接映射。而是應(yīng)從sample
的值中查找服務(wù)ID。
現(xiàn)在已填充SERVICE_ID_KEY
,PreDecorationFilter
將不運(yùn)行,而RibbonRoutingFilter
將運(yùn)行。
如果要路由到完整URL,請(qǐng)致電
ctx.setRouteHost(url)
。
要修改路由過(guò)濾器轉(zhuǎn)發(fā)到的路徑,請(qǐng)?jiān)O(shè)置REQUEST_URI_KEY
。
路由過(guò)濾器在預(yù)過(guò)濾器之后運(yùn)行,并向其他服務(wù)發(fā)出請(qǐng)求。這里的許多工作是將請(qǐng)求和響應(yīng)數(shù)據(jù)與客戶端所需的模型相互轉(zhuǎn)換。以下示例顯示了Zuul路由過(guò)濾器:
public class OkHttpRoutingFilter extends ZuulFilter { @Autowired private ProxyRequestHelper helper; @Override public String filterType() { return ROUTE_TYPE; } @Override public int filterOrder() { return SIMPLE_HOST_ROUTING_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return RequestContext.getCurrentContext().getRouteHost() != null && RequestContext.getCurrentContext().sendZuulResponse(); } @Override public Object run() { OkHttpClient httpClient = new OkHttpClient.Builder() // customize .build(); RequestContext context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest(); String method = request.getMethod(); String uri = this.helper.buildZuulRequestURI(request); Headers.Builder headers = new Headers.Builder(); Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String name = headerNames.nextElement(); Enumeration<String> values = request.getHeaders(name); while (values.hasMoreElements()) { String value = values.nextElement(); headers.add(name, value); } } InputStream inputStream = request.getInputStream(); RequestBody requestBody = null; if (inputStream != null && HttpMethod.permitsRequestBody(method)) { MediaType mediaType = null; if (headers.get("Content-Type") != null) { mediaType = MediaType.parse(headers.get("Content-Type")); } requestBody = RequestBody.create(mediaType, StreamUtils.copyToByteArray(inputStream)); } Request.Builder builder = new Request.Builder() .headers(headers.build()) .url(uri) .method(method, requestBody); Response response = httpClient.newCall(builder.build()).execute(); LinkedMultiValueMap<String, String> responseHeaders = new LinkedMultiValueMap<>(); for (Map.Entry<String, List<String>> entry : response.headers().toMultimap().entrySet()) { responseHeaders.put(entry.getKey(), entry.getValue()); } this.helper.setResponse(response.code(), response.body().byteStream(), responseHeaders); context.setRouteHost(null); // prevent SimpleHostRoutingFilter from running return null; } }
前面的過(guò)濾器將Servlet請(qǐng)求信息轉(zhuǎn)換為OkHttp3請(qǐng)求信息,執(zhí)行HTTP請(qǐng)求,并將OkHttp3響應(yīng)信息轉(zhuǎn)換為Servlet響應(yīng)。
后置過(guò)濾器通常操縱響應(yīng)。以下過(guò)濾器將隨機(jī)UUID
添加為X-Sample
標(biāo)頭:
public class AddResponseHeaderFilter extends ZuulFilter { @Override public String filterType() { return POST_TYPE; } @Override public int filterOrder() { return SEND_RESPONSE_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext context = RequestContext.getCurrentContext(); HttpServletResponse servletResponse = context.getResponse(); servletResponse.addHeader("X-Sample", UUID.randomUUID().toString()); return null; } }
其他操作,例如轉(zhuǎn)換響應(yīng)主體,則更加復(fù)雜且計(jì)算量大。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: