How to configure SpringCloud Zuul – Routing and Filtering | SpringBoot

Netflix Zuul is a proxy solution to forward requests to microservices. In the tutorial, JavaSampleApproach will show you way to configure SpringBoot Zuul with routing & filtering.

Related articles:
Client Load Balancing with Spring Cloud Ribbon + Spring Boot
Spring Cloud Centralized Configuration


I. Technologies

– Java 1.8
– Maven 3.3.9
– Spring Tool Suite – Version 3.8.1.RELEASE
– Spring Boot: 1.5.1.RELEASE
– Spring Cloud Zuul: 1.3.0.RELEASE

II. Practice

We create 3 projects: 2 – simple MicroService Applications & 1 – Zuul Proxy Gateway.

1. Create Spring Boot MicroServices

Create 2 MicroService Web Applications.
– Add spring-boot-starter-web for each:


	org.springframework.boot
	spring-boot-starter-web

1.1 Create Student service

Student Service runs at: server.port=8081

package com.javasampleapproach.studentservice;

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;

@RestController
@SpringBootApplication
public class SpringBootStudentApplication {

	@RequestMapping(value = "/")
	public String available() {
		return "Welcome To Student Service!";
	}

	public static void main(String[] args) {
		SpringApplication.run(SpringBootStudentApplication.class, args);
	}
}
1.2 Create Lecturer service

Lecturer Service runs at: server.port=8082

package com.javasampleapproach.lecturerservice;

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;

@RestController
@SpringBootApplication
public class SpringBootLecturerApplication {
	
	@RequestMapping(value = "/")
	public String welcome() {
		return "Welcome To Lecturer Service!";
	}
	
	public static void main(String[] args) {
		SpringApplication.run(SpringBootLecturerApplication.class, args);
	}
}
2. Create Zuul Proxy Gateway
2.1 Create Spring Boot Zuul Gateway

Create a Spring Boot Zuul Gateway runs at: server.port=8080
– Add needed dependencies: spring-boot-starter-web & spring-cloud-starter-zuul


	org.springframework.boot
	spring-boot-starter-web




	org.springframework.cloud
	spring-cloud-starter-zuul
	1.3.0.RELEASE

Configure MicroServices for routing:
students at http://localhost:8081.
lecturers at http://localhost:8082

zuul.routes.students.url=http://localhost:8081
zuul.routes.lecturers.url=http://localhost:8082
ribbon.eureka.enabled=false
server.port=8080

Enable Zuul Gateway by annotation: @EnableZuulProxy

package com.javasampleapproach.zuulgateway;

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


@EnableZuulProxy
@SpringBootApplication
public class SpringBootZuulGateWayApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootZuulGateWayApplication.class, args);
	}
}
2.2 Add filters

Zuul has 4 filter types:
pre filters are executed before the request is routed.
route filters uses to route the request.
post filters are executed after the request has been routed.
error filters execute if an error occurs while handling the request.

zuul gateway

For creating a filter, just extends ZuulFilter. Need overview 4 functions:
public String filterType(): specify the type of a filter: (pre, route, post, error) by a String
public int filterOrder(): indicates the order to process this filter.
public boolean shouldFilter(): gives a condition to consider to execute the filter.
public Object run(): functionality of the filter.

In the Zuul Gateway project, we create 4 simple filters, just log info of httprequest/httpresponse while executing:

– 2 Prefilters with difference filterOrder:
PreFilter.java

package com.javasampleapproach.zuulgateway.filters;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class PreFilter extends ZuulFilter {
	private static Logger log = LoggerFactory.getLogger(PreFilter.class);

	  @Override
	  public String filterType() {
	    return "pre";
	  }

	  @Override
	  public int filterOrder() {
	    return 1;
	  }

	  @Override
	  public boolean shouldFilter() {
	    return true;
	  }

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

	    log.info("PreFilter: " + String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
	    
	    return null;
	  }
}

PreFilter2.java

package com.javasampleapproach.zuulgateway.filters;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class PreFilter2 extends ZuulFilter {
	private static Logger log = LoggerFactory.getLogger(PreFilter2.class);

	  @Override
	  public String filterType() {
	    return "pre";
	  }

	  @Override
	  public int filterOrder() {
	    return 2;
	  }

	  @Override
	  public boolean shouldFilter() {
	    return true;
	  }

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

	    log.info("PreFilter 2: " + String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
	    
	    return null;
	  }
}

– 1 route filter:
RouteFilter.java

package com.javasampleapproach.zuulgateway.filters;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class RouteFilter extends ZuulFilter {
	private static Logger log = LoggerFactory.getLogger(RouteFilter.class);

	@Override
	public String filterType() {
		return "route";
	}

	@Override
	public int filterOrder() {
		return 1;
	}

	@Override
	public boolean shouldFilter() {
		return true;
	}

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

		log.info("RouteFilter: " + String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
		
		return null;
	}
}

– 1 post filter:
PostFilter.java

package com.javasampleapproach.zuulgateway.filters;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class PostFilter extends ZuulFilter {
	private static Logger log = LoggerFactory.getLogger(PostFilter.class);

	  @Override
	  public String filterType() {
	    return "post";
	  }

	  @Override
	  public int filterOrder() {
	    return 1;
	  }

	  @Override
	  public boolean shouldFilter() {
	    return true;
	  }

	  @Override
	  public Object run() {
	    HttpServletResponse response = RequestContext.getCurrentContext().getResponse();
	    
	    log.info("PostFilter: " + String.format("response's content type is %s", response.getStatus()));
	    
	    return null;
	  }
}

– 1 error filter:
ErrorFilter.java

package com.javasampleapproach.zuulgateway.filters;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;

@Component
public class ErrorFilter extends ZuulFilter {
	private static Logger log = LoggerFactory.getLogger(PostFilter.class);

	  @Override
	  public String filterType() {
	    return "error";
	  }

	  @Override
	  public int filterOrder() {
	    return 1;
	  }

	  @Override
	  public boolean shouldFilter() {
	    return true;
	  }

	  @Override
	  public Object run() {
	    HttpServletResponse response = RequestContext.getCurrentContext().getResponse();
	    
	    log.info("ErrorFilter: " + String.format("response status is %d", response.getStatus()));
	    
	    return null;
	  }
}
3. Run & Check results

Build the projects with Spring Boot App mode.
– Make request: http://localhost:8080/students

springboot zuul gateway - students

Zuul Gateway’s Logs:

PreFilter: GET request to http://localhost:8080/students
PreFilter 2: GET request to http://localhost:8080/students
RouteFilter: GET request to http://localhost:8080/students
PostFilter: response's content type is 200

– Make request: http://localhost:8080/lecturers

springboot zuul gateway - lectures

Zuul Gateway’s Logs:

PreFilter: GET request to http://localhost:8080/lecturers
PreFilter 2: GET request to http://localhost:8080/lecturers
RouteFilter: GET request to http://localhost:8080/lecturers
PostFilter: response's content type is 200

– Shutdown Lectures Service at 8082
Make the request again: http://localhost:8080/lecturers

springboot zuul gateway - lectures - error filter

Zuul Gateway’s Logs:

PreFilter: GET request to http://localhost:8080/lecturers
PreFilter 2: GET request to http://localhost:8080/lecturers
RouteFilter: GET request to http://localhost:8080/lecturers
Error during filtering
com.netflix.zuul.exception.ZuulException: Connect to localhost:8082 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
...
ErrorFilter: response status is 500
PostFilter: response's content type is 500

III. SourceCode

1. SpringBootLecturer
2. SpringBootStudent
3. SpringBootZuulGateWay



By grokonez | April 13, 2017.

Last updated on August 10, 2017.



Related Posts


2 thoughts on “How to configure SpringCloud Zuul – Routing and Filtering | SpringBoot”

  1. Hi!
    I just added a function that upload a file into /files/
    Can you explain me how setup zuul access to access to folder on server?
    Something like myhost.com/files/file.pdf?

Got Something To Say:

Your email address will not be published. Required fields are marked *

*