Routing and Filtering

通过此教程,你将使用Netflix Zuul边缘服务库来路由和过滤到一个微服务应用的请求。

This guide walks you through the process of routing and filtering requests to a microservice application using the Netflix Zuul edge service library.


What you’ll build

你将编写一个简单的微服务应用,并使用Netflix Zuul构建一个反向代理应用来转发请求到这个服务应用。以及如何使用Zuul通过代理服务来过滤请求。

You’ll write a simple microservice application and then build a reverse proxy application that uses Netflix Zuul to forward requests to the service application. You’ll also see how to use Zuul to filter requests made through the proxy service.


What you’ll need


How to complete this guide


Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.


To start from scratch, move on to Build with Gradle.


To skip the basics, do the following:

  • 下载并解压此教程的源码仓库,或者使用Git进行clone:git clone https://github.com/spring-guides/gs-routing-and-filtering.git
  • 进入gs-routing-and-filtering/initial目录
  • 跳至构建一个微服务.
  • Download and unzip the source repository for this guide, or clone it using Git: git clone https://github.com/spring-guides/gs-routing-and-filtering.git
  • cd into gs-routing-and-filtering/initial
  • Jump ahead to Set up a microservice.


When you’re finished, you can check your results against the code in gs-routing-and-filtering/complete.


Set up a microservice


The Book service will be super-simple. Edit BookApplication.java to look like this:


package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

public class BookApplication {

  @RequestMapping(value = "/available")
  public String available() {
    return "Spring in Action";

  @RequestMapping(value = "/checked-out")
  public String checkedOut() {
    return "Spring Boot in Action";

  public static void main(String[] args) {
    SpringApplication.run(BookApplication.class, args);


The BookApplication class is now a REST controller. @RestController marks the class as a controller class, and also ensures that return values from @RequestMapping methods in this class will be automatically converted appropriately and written directly to the HTTP response.


Speaking of @RequestMapping methods, we’ve added two: available() and checkedOut(). They handle requests to the paths /available and /checked-out, each simply returning the String name of a book.


Set the application name (book) in src/main/resources/application.properties.





We’re also setting server.port here so that it won’t conflict with our edge service when we get both services up and running locally.


Create an edge service

Spring Cloud Netflix包含了内嵌的Zuul代理,可通过@EnableZuulProxy注解启用。这样做会将网关服务转变为一个反向代理,转发到其他服务的相关调用,例如此例的Book服务。

Spring Cloud Netflix includes an embedded Zuul proxy, which we can enable with the @EnableZuulProxy annotation. This will turn the Gateway application into a reverse proxy that forwards relevant calls to other services—such as our Book service.


Open the Gateway application’s GatewayApplication class and add the annotation, like so:


package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

public class GatewayApplication {

  public static void main(String[] args) {
    SpringApplication.run(GatewayApplication.class, args);



To forward requests from the Gateway application, we need to tell Zuul the routes that it should watch and the services to which to forward requests to those routes. We specify routes using properties under zuul.routes. Each of our microservices can have an entry under zuul.routes.NAME, where NAME is the application name (as stored in the spring.application.name property).


Add the application.properties file to a new directory, src/main/resources, in the Gateway application. It should look like this:





Spring Cloud Zuul将根据应用名称自动设置路径。例如我们设置了zuul.routes.books.url,Zuul将自动代理/books的请求到此URL上。

Spring Cloud Zuul will automatically set the path to the application name. In this sample because we set zuul.routes.books.url, so Zuul will proxy requests to /books to this URL.

注意倒数第二个属性:Spring Cloud Netflix Zuul使用了Netflix的Ribbon来执行客户端的负载均衡,默认Ribbon将使用Netflix Eureka做服务发现。在此例中,我们省掉了服务发现,所以设置ribbon.eureka.enabledfalse。因为Ribbon无法使用Eureka查找服务,我们必须为Book服务指定一个url

Notice the second-to-last property in our file: Spring Cloud Netflix Zuul uses Netflix’s Ribbon to perform client-side load balancing, and by default, Ribbon would use Netflix Eureka for service discovery. For this simple example, we’re skipping service discovery, so we’ve set ribbon.eureka.enabled to false. Since Ribbon now can’t use Eureka to look up services, we must specify a url for the Book service.


Add a filter


Now let’s see how we can filter requests through our proxy service. Zuul has four standard filter types:

  • pre过滤器在请求被路由前执行,
  • route过滤器是正在路由此请求的时候被处理,
  • post过滤器在请求被路由后执行,
  • error过滤器是在处理请求时发生错误时被执行。
  • pre filters are executed before the request is routed,
  • route filters can handle the actual routing of the request,
  • post filters are executed after the request has been routed, and
  • error filters execute if an error occurs in the course of handling the request.

我们将写一个pre过滤器。任何继承了com.netflix.zuul.ZuulFilter@Bean都会被Spring Cloud Netflix识别为一个过滤器,且在应用上下文中可用。新建一个文件夹src/main/java/hello/filters/pre,在其中创建过滤器文件SimpleFilter.java

We’re going to write a pre filter. Spring Cloud Netflix picks up, as a filter, any @Bean which extends com.netflix.zuul.ZuulFilter and is available in the application context. Create a new directory, src/main/java/hello/filters/pre, and within it, create the filter file, SimpleFilter.java:


package hello.filters.pre;

import javax.servlet.http.HttpServletRequest;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.ZuulFilter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleFilter extends ZuulFilter {

  private static Logger log = LoggerFactory.getLogger(SimpleFilter.class);

  public String filterType() {
    return "pre";

  public int filterOrder() {
    return 1;

  public boolean shouldFilter() {
    return true;

  public Object run() {
    RequestContext ctx = RequestContext.getCurrentContext();
    HttpServletRequest request = ctx.getRequest();

    log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));

    return null;



Filter classes implement four methods:

  • filterType()返回一个表示过滤器类型的字符串String,在此例中是pre,或者对于路由过滤器来说则返回route
  • filterOrder()表示过滤器相对于其他过滤器被执行的顺序。
  • shouldFilter()包含决定此过滤器是否被执行的逻辑(此例中过滤器总会被执行)。
  • run()包含过滤器的功能。
  • filterType() returns a String that stands for the type of the filter—in this case, pre, or it could be route for a routing filter.
  • filterOrder() gives the order in which this filter will be executed, relative to other filters.
  • shouldFilter() contains the logic that determines when to execute this filter (this particular filter will always be executed).
  • run() contains the functionality of the filter.


Zuul filters store request and state information in (and share it by means of) the RequestContext. We’re using that to get at the HttpServletRequest, and then we log the HTTP method and URL of the request before it is sent on its way.


The GatewayApplication class is annotated with @SpringBootApplication, which is equivalent to (among others) the @Configuration annotation that tells Spring to look in a given class for @Bean definitions. Add one for our SimpleFilter here:


package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import hello.filters.pre.SimpleFilter;

public class GatewayApplication {

  public static void main(String[] args) {
    SpringApplication.run(GatewayApplication.class, args);

  public SimpleFilter simpleFilter() {
    return new SimpleFilter();



Trying it out


Make sure that both applications are running. In a browser, visit one of the Book application’s endpoints via the Gateway application. If you’ve used the configuration shown in this guide, you can access the Book service directly at localhost:8090 and via the Gateway service at localhost:8080/books.


Visit one of the Book service endpoints, as localhost:8080/books/available, and you should see your request’s method logged by the Gateway application before it’s handed on to the Book application:

2016-01-19 16:51:14.672  INFO 58807 --- [nio-8080-exec-6] hello.filters.pre.SimpleFilter           : GET request to http://localhost:8080/books/available
2016-01-19 16:51:14.672  INFO 58807 --- [nio-8080-exec-6] o.s.c.n.zuul.filters.ProxyRouteLocator   : Finding route for path: /books/available




Congratulations! You’ve just used Spring to develop an edge service application that can proxy and filter requests for your microservices.