Mastering RouterFunction Filters and URL Builders in Spring Boot 2.4
This tutorial demonstrates how to apply before, after, and custom filter functions to Spring WebFlux RouterFunction routes, shows a complete handler and router configuration example, and explains the use of UriComponentsBuilder for flexible URI construction in Java backend applications.
Environment: Spring Boot 2.4.12
Overview
You can filter handler functions on a router‑function builder by using before , after or filter . Similar functionality can be achieved with @ControllerAdvice , ServletFilter , or both. Filters apply to all routes built by the builder, but filters defined on nested routes do not affect top‑level routes.
<code>RouterFunction<ServerResponse> route = route()
.path("/person", b1 -> b1
.nest(accept(APPLICATION_JSON), b2 -> b2
.GET("/{id}", handler::getPerson)
.GET("", handler::listPeople)
.before(request -> ServerRequest.from(request)
// 1
.header("X-RequestHeader", "Value")
.build()))
.POST("/person", handler::createPerson))
.after((request, response) -> logResponse(response)) // 2
.build();</code>The custom before filter that adds a request header is applied only to the two GET routes.
The after filter that logs the response is applied to all routes, including nested ones.
The filter method on the router builder accepts a HandlerFilterFunction : a function that receives a ServerRequest and a HandlerFunction , and returns a ServerResponse . The handler function argument represents the next element in the chain, which may be the actual handler or another filter.
Complete Example
Handler
<code>@Component
public class PersonHandler {
public ServerResponse queryPerson(ServerRequest request) throws Exception {
System.out.println(request.headers().header("x-pack"));
return ok().body(new Person(Integer.valueOf(request.pathVariable("id")), "China"));
}
private Errors validate(Person person) {
Errors errors = new BeanPropertyBindingResult(person, "person");
validator.validate(person, errors);
if (errors.hasErrors()) {
return errors;
}
return null;
}
}</code>Router Configuration
<code>@Configuration
public class PersonHandlerConfiguration {
@Resource
private PersonHandler ph;
@Bean
public RouterFunction<ServerResponse> nestPerson2() {
return route()
.path("/persons2", b1 -> b1
.nest(accept(MediaType.APPLICATION_JSON), b2 -> b2
.GET("/{id}", accept(MediaType.APPLICATION_JSON), ph::queryPerson)
.before(request -> ServerRequest.from(request).header("x-pack", "123123").build()))
.POST("/save", ph::save))
.after((request, response) -> {
System.out.println("after execution..." + response.statusCode());
return response;
})
.filter((request, next) -> {
if (request.pathVariable("id").equals("100")) {
return ServerResponse.ok().body("参数错误");
} else {
return next.handle(request);
}
})
.build();
}
}</code>POJO
<code>public class Person {
private Integer id;
@NotEmpty(message = "姓名必须填写")
private String name;
}</code>URL Handling Component
The URL component can be used in both Spring MVC and Spring WebFlux.
UriComponentsBuilder helps build a URI from a template with variables:
<code>UriComponents uriComponents = UriComponentsBuilder
.fromUriString("https://pack.com/lovers/{lover}") // 1
.queryParam("q", "{q}") // 2
.encode() // 3
.build(); // 4
URI uri = uriComponents.expand("lover", "hcw").toUri(); // 5</code>Use the static factory method with a URI template.
Add or replace URI components.
Encode the URI template and variables.
Build a UriComponents instance.
Expand variables and obtain the final URI .
Result:
<code>https://pack.com/lovers/lover?q=hcw</code>The same logic can be chained with buildAndExpand for brevity:
<code>URI uri = UriComponentsBuilder
.fromUriString("https://pack.com/lovers/{lover}")
.queryParam("q", "{q}")
.encode()
.buildAndExpand("lover", "hcw")
.toUri();</code>You can also shorten the call by directly building the URI (which performs encoding):
<code>URI uri = UriComponentsBuilder
.fromUriString("https://pack.com/lovers/{lover}")
.queryParam("q", "{q}")
.build("lover", "hcw");</code>Or by using the full URI template in a single step:
<code>URI uri = UriComponentsBuilder
.fromUriString("https://pack.com/lovers/{lover}")
.build("lover", "hcw");</code>Done!
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.