网关Zuul——url请求流转路径
在springcloud的网关组件zuul中,网关本身能够接收url请求,那么请求在网关zuul组件中是怎么流转的呢?
从前面的文章可以看出,当外部请求传递到网关(Zuul)时,请求会传递到ZuulController类中
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { ModelAndView var3; try { var3 = super.handleRequestInternal(request, response); } finally { RequestContext.getCurrentContext().unset(); } return var3; }
这里可以看出,外部请求会进入ZuulController类中,交由handleRequest方法处理,而该方法实际调用其父类的handleRequestInternal方法
查看ZuulController的父类ServletWrappingController
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { Assert.state(this.servletInstance != null, "No Servlet instance"); this.servletInstance.service(request, response); return null; }
在ServletWrappingController类的handleRequestInternal方法中,请求是由ZuulServlet的service方法处理
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { try { this.init((HttpServletRequest)servletRequest, (HttpServletResponse)servletResponse); RequestContext context = RequestContext.getCurrentContext(); context.setZuulEngineRan(); try { this.preRoute(); } catch (ZuulException var12) { this.error(var12); this.postRoute(); return; } try { this.route(); } catch (ZuulException var13) { this.error(var13); this.postRoute(); return; } try { this.postRoute(); } catch (ZuulException var11) { this.error(var11); } } catch (Throwable var14) { this.error(new ZuulException(var14, 500, "UNHANDLED_EXCEPTION_" + var14.getClass().getName())); } finally { RequestContext.getCurrentContext().unset(); } } //处理http请求 void init(HttpServletRequest servletRequest, HttpServletResponse servletResponse) { this.zuulRunner.init(servletRequest, servletResponse); }
从上述代码可以看出,http请求会传递到ZuulRunner类中进行处理
查看ZuulRunner中的处理方式
public void init(HttpServletRequest servletRequest, HttpServletResponse servletResponse) { RequestContext ctx = RequestContext.getCurrentContext(); if (this.bufferRequests) { ctx.setRequest(new HttpServletRequestWrapper(servletRequest)); } else { ctx.setRequest(servletRequest); } ctx.setResponse(new HttpServletResponseWrapper(servletResponse)); }
查看上述代码,可以看出请求最后被存放在RequestContext类中,而RequestContext是一个静态单例的,所以在程序的任何位置都可以通过获取RequestContext的实例来获取到http请求信息。而这也就是过滤器用以进行请求过滤的基础。
总结:
http请求的流转路径:
ZuulController的handleRequest方法——>ServletWrappingController的handleRequestInternal方法——>ZuulServlet的service方法——>ZuulServlet的init方法——>
ZuulRunner的init方法——>RequestContext的实例中