diff --git a/graphql-spring-boot-starter/build.gradle b/graphql-spring-boot-starter/build.gradle index 1fd80e0e..1393d4aa 100644 --- a/graphql-spring-boot-starter/build.gradle +++ b/graphql-spring-boot-starter/build.gradle @@ -36,6 +36,7 @@ dependencies { compileOnly 'org.springframework:spring-webmvc' compileOnly 'org.springframework:spring-websocket' compileOnly 'javax.servlet:javax.servlet-api' + compileOnly 'javax.websocket:javax.websocket-api' compileOnly 'io.micrometer:micrometer-core' compileOnly 'org.springframework.boot:spring-boot-actuator-autoconfigure' diff --git a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/WebMvcGraphQLAutoConfiguration.java b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/WebMvcGraphQLAutoConfiguration.java index e60ef8a3..e0b8655f 100644 --- a/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/WebMvcGraphQLAutoConfiguration.java +++ b/graphql-spring-boot-starter/src/main/java/org/springframework/graphql/boot/WebMvcGraphQLAutoConfiguration.java @@ -18,6 +18,8 @@ package org.springframework.graphql.boot; import java.util.Collections; import java.util.Map; +import javax.websocket.server.ServerContainer; + import graphql.GraphQL; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -39,6 +41,7 @@ import org.springframework.web.servlet.function.RouterFunction; import org.springframework.web.servlet.function.RouterFunctions; import org.springframework.web.servlet.function.ServerResponse; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; +import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.support.DefaultHandshakeHandler; import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler; @@ -58,22 +61,6 @@ public class WebMvcGraphQLAutoConfiguration { return new GraphQLHttpHandler(graphQLBuilder.build(), Collections.emptyList()); } - @Bean - @ConditionalOnMissingBean - public GraphQLWebSocketHandler graphQLWebSocketHandler( - GraphQL.Builder graphQLBuilder, GraphQLProperties properties, HttpMessageConverters converters) { - - HttpMessageConverter converter = converters.getConverters().stream() - .filter(candidate -> candidate.canRead(Map.class, MediaType.APPLICATION_JSON)) - .findFirst() - .orElseThrow(() -> new IllegalStateException("No JSON converter")); - - return new GraphQLWebSocketHandler( - graphQLBuilder.build(), Collections.emptyList(), - converter, properties.getConnectionInitTimeoutDuration() - ); - } - @Bean public RouterFunction graphQLQueryEndpoint( ResourceLoader resourceLoader, GraphQLHttpHandler handler, GraphQLProperties properties) { @@ -87,16 +74,38 @@ public class WebMvcGraphQLAutoConfiguration { .build(); } - @Bean - public HandlerMapping graphQLWebSocketEndpoint(GraphQLWebSocketHandler handler, GraphQLProperties properties) { - WebSocketHttpRequestHandler httpRequestHandler = - new WebSocketHttpRequestHandler(handler, new DefaultHandshakeHandler()); - String path = properties.getWebSocketPath(); - SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); - mapping.setUrlMap(Collections.singletonMap(path, httpRequestHandler)); - mapping.setOrder(-1); // Ahead of annotated controllers - return mapping; + @ConditionalOnClass({ServerContainer.class, WebSocketHandler.class}) + static class WebSocketConfiguration { + + @Bean + @ConditionalOnMissingBean + public GraphQLWebSocketHandler graphQLWebSocketHandler( + GraphQL.Builder graphQLBuilder, GraphQLProperties properties, HttpMessageConverters converters) { + + HttpMessageConverter converter = converters.getConverters().stream() + .filter(candidate -> candidate.canRead(Map.class, MediaType.APPLICATION_JSON)) + .findFirst() + .orElseThrow(() -> new IllegalStateException("No JSON converter")); + + return new GraphQLWebSocketHandler( + graphQLBuilder.build(), Collections.emptyList(), + converter, properties.getConnectionInitTimeoutDuration() + ); + } + + @Bean + public HandlerMapping graphQLWebSocketEndpoint(GraphQLWebSocketHandler handler, GraphQLProperties properties) { + WebSocketHttpRequestHandler httpRequestHandler = + new WebSocketHttpRequestHandler(handler, new DefaultHandshakeHandler()); + + String path = properties.getWebSocketPath(); + SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); + mapping.setUrlMap(Collections.singletonMap(path, httpRequestHandler)); + mapping.setOrder(-1); // Ahead of annotated controllers + return mapping; + } + } }