|
16 | 16 |
|
17 | 17 | package org.springframework.web.reactive.function.server;
|
18 | 18 |
|
| 19 | +import java.util.Collections; |
| 20 | +import java.util.LinkedHashMap; |
19 | 21 | import java.util.List;
|
20 | 22 | import java.util.Map;
|
21 | 23 | import java.util.function.BiFunction;
|
@@ -858,6 +860,27 @@ Builder onError(Predicate<? super Throwable> predicate,
|
858 | 860 | <T extends Throwable> Builder onError(Class<T> exceptionType,
|
859 | 861 | BiFunction<? super T, ServerRequest, Mono<ServerResponse>> responseProvider);
|
860 | 862 |
|
| 863 | + /** |
| 864 | + * Add an attribute with the given name and value to the last route built with this builder. |
| 865 | + * @param name the attribute name |
| 866 | + * @param value the attribute value |
| 867 | + * @return this builder |
| 868 | + * @since 5.3 |
| 869 | + */ |
| 870 | + Builder withAttribute(String name, Object value); |
| 871 | + |
| 872 | + /** |
| 873 | + * Manipulate the attributes of the last route built with the given consumer. |
| 874 | + * <p>The map provided to the consumer is "live", so that the consumer can be used |
| 875 | + * to {@linkplain Map#put(Object, Object) overwrite} existing attributes, |
| 876 | + * {@linkplain Map#remove(Object) remove} attributes, or use any of the other |
| 877 | + * {@link Map} methods. |
| 878 | + * @param attributesConsumer a function that consumes the attributes map |
| 879 | + * @return this builder |
| 880 | + * @since 5.3 |
| 881 | + */ |
| 882 | + Builder withAttributes(Consumer<Map<String, Object>> attributesConsumer); |
| 883 | + |
861 | 884 | /**
|
862 | 885 | * Builds the {@code RouterFunction}. All created routes are
|
863 | 886 | * {@linkplain RouterFunction#and(RouterFunction) composed} with one another, and filters
|
@@ -902,6 +925,14 @@ public interface Visitor {
|
902 | 925 | */
|
903 | 926 | void resources(Function<ServerRequest, Mono<Resource>> lookupFunction);
|
904 | 927 |
|
| 928 | + /** |
| 929 | + * Receive notification of a router function with attributes. The |
| 930 | + * given attributes apply to the router notification that follows this one. |
| 931 | + * @param attributes the attributes that apply to the following router |
| 932 | + * @since 5.3 |
| 933 | + */ |
| 934 | + void attributes(Map<String, Object> attributes); |
| 935 | + |
905 | 936 | /**
|
906 | 937 | * Receive notification of an unknown router function. This method is called for router
|
907 | 938 | * functions that were not created via the various {@link RouterFunctions} methods.
|
@@ -1126,6 +1157,58 @@ public void accept(Visitor visitor) {
|
1126 | 1157 | }
|
1127 | 1158 |
|
1128 | 1159 |
|
| 1160 | + static final class AttributesRouterFunction<T extends ServerResponse> extends AbstractRouterFunction<T> { |
| 1161 | + |
| 1162 | + private final RouterFunction<T> delegate; |
| 1163 | + |
| 1164 | + private final Map<String,Object> attributes; |
| 1165 | + |
| 1166 | + public AttributesRouterFunction(RouterFunction<T> delegate, Map<String, Object> attributes) { |
| 1167 | + this.delegate = delegate; |
| 1168 | + this.attributes = initAttributes(attributes); |
| 1169 | + } |
| 1170 | + |
| 1171 | + private static Map<String, Object> initAttributes(Map<String, Object> attributes) { |
| 1172 | + if (attributes.isEmpty()) { |
| 1173 | + return Collections.emptyMap(); |
| 1174 | + } |
| 1175 | + else { |
| 1176 | + return Collections.unmodifiableMap(new LinkedHashMap<>(attributes)); |
| 1177 | + } |
| 1178 | + } |
| 1179 | + |
| 1180 | + @Override |
| 1181 | + public Mono<HandlerFunction<T>> route(ServerRequest request) { |
| 1182 | + return this.delegate.route(request); |
| 1183 | + } |
| 1184 | + |
| 1185 | + @Override |
| 1186 | + public void accept(Visitor visitor) { |
| 1187 | + visitor.attributes(this.attributes); |
| 1188 | + this.delegate.accept(visitor); |
| 1189 | + } |
| 1190 | + |
| 1191 | + @Override |
| 1192 | + public RouterFunction<T> withAttribute(String name, Object value) { |
| 1193 | + Assert.hasLength(name, "Name must not be empty"); |
| 1194 | + Assert.notNull(value, "Value must not be null"); |
| 1195 | + |
| 1196 | + Map<String, Object> attributes = new LinkedHashMap<>(this.attributes); |
| 1197 | + attributes.put(name, value); |
| 1198 | + return new AttributesRouterFunction<>(this.delegate, attributes); |
| 1199 | + } |
| 1200 | + |
| 1201 | + @Override |
| 1202 | + public RouterFunction<T> withAttributes(Consumer<Map<String, Object>> attributesConsumer) { |
| 1203 | + Assert.notNull(attributesConsumer, "AttributesConsumer must not be null"); |
| 1204 | + |
| 1205 | + Map<String, Object> attributes = new LinkedHashMap<>(this.attributes); |
| 1206 | + attributesConsumer.accept(attributes); |
| 1207 | + return new AttributesRouterFunction<>(this.delegate, attributes); |
| 1208 | + } |
| 1209 | + } |
| 1210 | + |
| 1211 | + |
1129 | 1212 | private static class HandlerStrategiesResponseContext implements ServerResponse.Context {
|
1130 | 1213 |
|
1131 | 1214 | private final HandlerStrategies strategies;
|
|
0 commit comments