@EnableWebFlux setup supports WebSocketHandler

Closes gh-22587
This commit is contained in:
Rossen Stoyanchev
2020-08-31 04:27:37 +01:00
parent 8f369ffed5
commit 591ab8a00a
8 changed files with 183 additions and 18 deletions

View File

@@ -27,6 +27,7 @@ import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
import org.springframework.web.reactive.socket.server.WebSocketService;
/**
* A subclass of {@code WebFluxConfigurationSupport} that detects and delegates
@@ -98,6 +99,12 @@ public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport
return (messageCodesResolver != null ? messageCodesResolver : super.getMessageCodesResolver());
}
@Override
protected WebSocketService getWebSocketService() {
WebSocketService service = this.configurers.getWebSocketService();
return (service != null ? service : super.getWebSocketService());
}
@Override
protected void configureViewResolvers(ViewResolverRegistry registry) {
this.configurers.configureViewResolvers(registry);

View File

@@ -65,6 +65,8 @@ import org.springframework.web.reactive.result.method.annotation.ResponseBodyRes
import org.springframework.web.reactive.result.method.annotation.ResponseEntityResultHandler;
import org.springframework.web.reactive.result.view.ViewResolutionResultHandler;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.reactive.socket.server.WebSocketService;
import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import org.springframework.web.server.i18n.AcceptHeaderLocaleContextResolver;
@@ -431,6 +433,24 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
return new SimpleHandlerAdapter();
}
@Bean
public WebSocketHandlerAdapter webFluxWebSocketHandlerAdapter() {
WebSocketService service = getWebSocketService();
WebSocketHandlerAdapter adapter = (service != null ?
new WebSocketHandlerAdapter(service) : new WebSocketHandlerAdapter());
// For backwards compatibility, lower the (default) priority
int defaultOrder = adapter.getOrder();
adapter.setOrder(defaultOrder + 1);
return adapter;
}
@Nullable
protected WebSocketService getWebSocketService() {
return null;
}
@Bean
public ResponseEntityResultHandler responseEntityResultHandler(
@Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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.
@@ -25,6 +25,7 @@ import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
import org.springframework.web.reactive.socket.server.WebSocketService;
/**
* Defines callback methods to customize the configuration for WebFlux
@@ -124,6 +125,18 @@ public interface WebFluxConfigurer {
return null;
}
/**
* Provide the {@link WebSocketService} to create
* {@link org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter}
* with. This can be used to configure server-specific properties through the
* {@link org.springframework.web.reactive.socket.server.RequestUpgradeStrategy}.
* @since 5.3
*/
@Nullable
default WebSocketService getWebSocketService() {
return null;
}
/**
* Configure view resolution for rendering responses with a view and a model,
* where the view is typically an HTML template but could also be based on

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 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.
@@ -30,6 +30,7 @@ import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
import org.springframework.web.reactive.socket.server.WebSocketService;
/**
* A {@link WebFluxConfigurer} that delegates to one or more others.
@@ -70,6 +71,12 @@ public class WebFluxConfigurerComposite implements WebFluxConfigurer {
this.delegates.forEach(delegate -> delegate.addResourceHandlers(registry));
}
@Nullable
@Override
public WebSocketService getWebSocketService() {
return createSingleBean(WebFluxConfigurer::getWebSocketService, WebSocketService.class);
}
@Override
public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
this.delegates.forEach(delegate -> delegate.configureArgumentResolvers(configurer));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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.
@@ -17,8 +17,8 @@ package org.springframework.web.reactive.socket.server.support;
import reactor.core.publisher.Mono;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.web.reactive.DispatcherHandler;
import org.springframework.web.reactive.HandlerAdapter;
import org.springframework.web.reactive.HandlerResult;
import org.springframework.web.reactive.socket.WebSocketHandler;
@@ -26,18 +26,30 @@ import org.springframework.web.reactive.socket.server.WebSocketService;
import org.springframework.web.server.ServerWebExchange;
/**
* {@link HandlerAdapter} that allows using a {@link WebSocketHandler} with the
* generic {@link DispatcherHandler} mapping URLs directly to such handlers.
* Requests are handled by delegating to the configured {@link WebSocketService}
* which by default is {@link HandshakeWebSocketService}.
* {@code HandlerAdapter} that allows
* {@link org.springframework.web.reactive.DispatcherHandler} to support
* handlers of type {@link WebSocketHandler} with such handlers mapped to
* URL patterns via
* {@link org.springframework.web.reactive.handler.SimpleUrlHandlerMapping}.
*
* <p>Requests are handled by delegating to a
* {@link WebSocketService}, by default {@link HandshakeWebSocketService},
* which checks the WebSocket handshake request parameters, upgrades to a
* WebSocket interaction, and uses the {@link WebSocketHandler} to handle it.
*
* <p>As of 5.3 the WebFlux Java configuration, imported via
* {@code @EnableWebFlux}, includes a declaration of this adapter and therefore
* it no longer needs to be present in application configuration.
*
* @author Rossen Stoyanchev
* @since 5.0
*/
public class WebSocketHandlerAdapter implements HandlerAdapter {
public class WebSocketHandlerAdapter implements HandlerAdapter, Ordered {
private final WebSocketService webSocketService;
private int order = 2;
/**
* Default constructor that creates and uses a
@@ -56,6 +68,25 @@ public class WebSocketHandlerAdapter implements HandlerAdapter {
}
/**
* Set the order value for this adapter.
* <p>By default this is set to 2.
* @param order the value to set to
* @since 5.3
*/
public void setOrder(int order) {
this.order = order;
}
/**
* Return the {@link #setOrder(int) configured} order for this instance.
* @since 5.3
*/
@Override
public int getOrder() {
return this.order;
}
/**
* Return the configured {@code WebSocketService} to handle requests.
*/