diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java index fb7c630d..9951fcaf 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 the original author or authors. + * Copyright 2020-2024 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. @@ -20,12 +20,13 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import jakarta.servlet.ServletException; import jakarta.servlet.http.Cookie; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.core.ParameterizedTypeReference; @@ -44,7 +45,7 @@ import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; /** - * GraphQL handler to expose as a WebMvc.fn endpoint via + * GraphQL handler to expose as a WebMvc functional endpoint via * {@link org.springframework.web.servlet.function.RouterFunctions}. * * @author Rossen Stoyanchev @@ -56,7 +57,7 @@ public class GraphQlHttpHandler { private static final Log logger = LogFactory.getLog(GraphQlHttpHandler.class); private static final ParameterizedTypeReference> MAP_PARAMETERIZED_TYPE_REF = - new ParameterizedTypeReference>() {}; + new ParameterizedTypeReference<>() {}; // To be removed in favor of Framework's MediaType.APPLICATION_GRAPHQL_RESPONSE private static final MediaType APPLICATION_GRAPHQL_RESPONSE = @@ -97,7 +98,7 @@ public class GraphQlHttpHandler { logger.debug("Executing: " + graphQlRequest); } - Mono responseMono = this.graphQlHandler.handleRequest(graphQlRequest) + CompletableFuture future = this.graphQlHandler.handleRequest(graphQlRequest) .map(response -> { if (logger.isDebugEnabled()) { logger.debug("Execution complete"); @@ -106,9 +107,22 @@ public class GraphQlHttpHandler { builder.headers(headers -> headers.putAll(response.getResponseHeaders())); builder.contentType(selectResponseMediaType(serverRequest)); return builder.body(response.toMap()); - }); + }) + .toFuture(); - return ServerResponse.async(responseMono); + if (future.isDone()) { + try { + return future.get(); + } + catch (ExecutionException ex) { + throw new ServletException(ex.getCause()); + } + catch (InterruptedException ex) { + throw new ServletException(ex); + } + } + + return ServerResponse.async(future); } private static MultiValueMap initCookies(ServerRequest serverRequest) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java index 19ee887e..77221827 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -122,7 +122,10 @@ public class GraphQlHttpHandlerTests { MockHttpServletRequest servletRequest, GraphQlHttpHandler handler) throws ServletException, IOException { ServerRequest request = ServerRequest.create(servletRequest, MESSAGE_READERS); - ServerResponse response = ((AsyncServerResponse) handler.handleRequest(request)).block(); + ServerResponse response = handler.handleRequest(request); + if (response instanceof AsyncServerResponse asyncResponse) { + asyncResponse.block(); + } MockHttpServletResponse servletResponse = new MockHttpServletResponse(); response.writeTo(servletRequest, servletResponse, new DefaultContext());