diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctionBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctionBuilder.java index 20e1c0a4be4..aa751f490e1 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctionBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctionBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import org.springframework.core.io.Resource; @@ -241,9 +242,10 @@ class RouterFunctionBuilder implements RouterFunctions.Builder { @Override public RouterFunction build() { - RouterFunction result = this.routerFunctions.stream() - .reduce(RouterFunction::and) - .orElseThrow(IllegalStateException::new); + if (this.routerFunctions.isEmpty()) { + throw new IllegalStateException("No routes registered. Register a route with GET(), POST(), etc."); + } + RouterFunction result = new BuiltRouterFunction(this.routerFunctions); if (this.filterFunctions.isEmpty()) { return result; @@ -258,4 +260,30 @@ class RouterFunctionBuilder implements RouterFunctions.Builder { } } + + /** + * Router function returned by {@link #build()} that simply iterates over the registered routes. + */ + private static class BuiltRouterFunction extends RouterFunctions.AbstractRouterFunction { + + private List> routerFunctions; + + public BuiltRouterFunction(List> routerFunctions) { + Assert.notEmpty(routerFunctions, "RouterFunctions must not be empty"); + this.routerFunctions = routerFunctions; + } + + @Override + public Mono> route(ServerRequest request) { + return Flux.fromIterable(this.routerFunctions) + .concatMap(routerFunction -> routerFunction.route(request)) + .next(); + } + + @Override + public void accept(RouterFunctions.Visitor visitor) { + this.routerFunctions.forEach(routerFunction -> routerFunction.accept(visitor)); + } + } + } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java index 85e6ee1e202..cd777c38db6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java @@ -749,7 +749,7 @@ public abstract class RouterFunctions { } - private abstract static class AbstractRouterFunction implements RouterFunction { + abstract static class AbstractRouterFunction implements RouterFunction { @Override public String toString() { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctionBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctionBuilder.java index 5eb17d9191f..cc23d0144cd 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctionBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctionBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -237,9 +237,10 @@ class RouterFunctionBuilder implements RouterFunctions.Builder { @Override public RouterFunction build() { - RouterFunction result = this.routerFunctions.stream() - .reduce(RouterFunction::and) - .orElseThrow(IllegalStateException::new); + if (this.routerFunctions.isEmpty()) { + throw new IllegalStateException("No routes registered. Register a route with GET(), POST(), etc."); + } + RouterFunction result = new BuiltRouterFunction(this.routerFunctions); if (this.filterFunctions.isEmpty()) { return result; @@ -254,4 +255,35 @@ class RouterFunctionBuilder implements RouterFunctions.Builder { } } + + /** + * Router function returned by {@link #build()} that simply iterates over the registered routes. + */ + private static class BuiltRouterFunction extends RouterFunctions.AbstractRouterFunction { + + private List> routerFunctions; + + public BuiltRouterFunction(List> routerFunctions) { + Assert.notEmpty(routerFunctions, "RouterFunctions must not be empty"); + this.routerFunctions = routerFunctions; + } + + @Override + public Optional> route(ServerRequest request) { + for (RouterFunction routerFunction : this.routerFunctions) { + Optional> result = routerFunction.route(request); + if (result.isPresent()) { + return result; + } + } + return Optional.empty(); + } + + @Override + public void accept(RouterFunctions.Visitor visitor) { + this.routerFunctions.forEach(routerFunction -> routerFunction.accept(visitor)); + } + } + + } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java index 92943358d3d..9122b436293 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/RouterFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -660,7 +660,7 @@ public abstract class RouterFunctions { } - private abstract static class AbstractRouterFunction implements RouterFunction { + abstract static class AbstractRouterFunction implements RouterFunction { @Override public String toString() {