Skip to content

Commit 78f3976

Browse files
committed
Merged and cleander GraphQLServlet classes
1 parent ebcfa80 commit 78f3976

File tree

5 files changed

+81
-666
lines changed

5 files changed

+81
-666
lines changed

src/main/java/graphql/servlet/AbstractGraphQLHttpServlet.java

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,28 @@
11
package graphql.servlet;
22

3+
import com.google.common.io.ByteStreams;
4+
import com.google.common.io.CharStreams;
35
import graphql.ExecutionResult;
46
import graphql.introspection.IntrospectionQuery;
57
import graphql.schema.GraphQLFieldDefinition;
68
import graphql.servlet.internal.GraphQLRequest;
7-
import org.apache.commons.fileupload.FileItem;
8-
import org.apache.commons.fileupload.FileItemFactory;
9-
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
10-
import org.apache.commons.fileupload.servlet.ServletFileUpload;
119
import org.slf4j.Logger;
1210
import org.slf4j.LoggerFactory;
1311

12+
import javax.servlet.AsyncContext;
1413
import javax.servlet.Servlet;
1514
import javax.servlet.ServletException;
1615
import javax.servlet.http.HttpServlet;
1716
import javax.servlet.http.HttpServletRequest;
1817
import javax.servlet.http.HttpServletResponse;
19-
import java.io.BufferedInputStream;
20-
import java.io.ByteArrayOutputStream;
21-
import java.io.IOException;
22-
import java.io.InputStream;
23-
import java.io.Writer;
24-
import java.util.ArrayList;
25-
import java.util.Collections;
26-
import java.util.HashMap;
27-
import java.util.List;
28-
import java.util.Map;
29-
import java.util.Objects;
30-
import java.util.Optional;
18+
import javax.servlet.http.Part;
19+
import java.io.*;
20+
import java.util.*;
3121
import java.util.function.BiConsumer;
3222
import java.util.function.Consumer;
3323
import java.util.function.Function;
3424
import java.util.stream.Collectors;
25+
import java.util.stream.Stream;
3526

3627
/**
3728
* @author Andrew Potter
@@ -48,7 +39,9 @@ public abstract class AbstractGraphQLHttpServlet extends HttpServlet implements
4839
private static final GraphQLRequest INTROSPECTION_REQUEST = new GraphQLRequest(IntrospectionQuery.INTROSPECTION_QUERY, new HashMap<>(), null);
4940

5041
protected abstract GraphQLQueryInvoker getQueryInvoker();
42+
5143
protected abstract GraphQLInvocationInputFactory getInvocationInputFactory();
44+
5245
protected abstract GraphQLObjectMapper getGraphQLObjectMapper();
5346

5447
private final List<GraphQLServletListener> listeners;
@@ -89,10 +82,7 @@ public AbstractGraphQLHttpServlet(List<GraphQLServletListener> listeners, boolea
8982
variables.putAll(graphQLObjectMapper.deserializeVariables(request.getParameter("variables")));
9083
}
9184

92-
String operationName = null;
93-
if (request.getParameter("operationName") != null) {
94-
operationName = request.getParameter("operationName");
95-
}
85+
String operationName = request.getParameter("operationName");
9686

9787
query(queryInvoker, graphQLObjectMapper, invocationInputFactory.createReadOnly(new GraphQLRequest(query, variables, operationName), request), response);
9888
}
@@ -109,11 +99,18 @@ public AbstractGraphQLHttpServlet(List<GraphQLServletListener> listeners, boolea
10999
GraphQLQueryInvoker queryInvoker = getQueryInvoker();
110100

111101
try {
112-
if (ServletFileUpload.isMultipartContent(request)) {
113-
final Map<String, List<FileItem>> fileItems = fileUpload.parseParameterMap(request);
102+
if (APPLICATION_GRAPHQL.equals(request.getContentType())) {
103+
String query = CharStreams.toString(request.getReader());
104+
query(queryInvoker, graphQLObjectMapper, invocationInputFactory.create(graphQLObjectMapper.readGraphQLRequest(query), request), response);
105+
} else if (request.getContentType() != null && request.getContentType().startsWith("multipart/form-data") && !request.getParts().isEmpty()) {
106+
final Map<String, List<Part>> fileItems = request.getParts().stream()
107+
.collect(Collectors.toMap(
108+
Part::getName,
109+
Collections::singletonList,
110+
(l1, l2) -> Stream.concat(l1.stream(), l2.stream()).collect(Collectors.toList())));
114111

115112
if (fileItems.containsKey("graphql")) {
116-
final Optional<FileItem> graphqlItem = getFileItem(fileItems, "graphql");
113+
final Optional<Part> graphqlItem = getFileItem(fileItems, "graphql");
117114
if (graphqlItem.isPresent()) {
118115
InputStream inputStream = graphqlItem.get().getInputStream();
119116

@@ -134,7 +131,7 @@ public AbstractGraphQLHttpServlet(List<GraphQLServletListener> listeners, boolea
134131
}
135132
}
136133
} else if (fileItems.containsKey("query")) {
137-
final Optional<FileItem> queryItem = getFileItem(fileItems, "query");
134+
final Optional<Part> queryItem = getFileItem(fileItems, "query");
138135
if (queryItem.isPresent()) {
139136
InputStream inputStream = queryItem.get().getInputStream();
140137

@@ -148,18 +145,18 @@ public AbstractGraphQLHttpServlet(List<GraphQLServletListener> listeners, boolea
148145
queryBatched(queryInvoker, graphQLObjectMapper, invocationInput, response);
149146
return;
150147
} else {
151-
String query = new String(queryItem.get().get());
148+
String query = new String(ByteStreams.toByteArray(inputStream));
152149

153150
Map<String, Object> variables = null;
154-
final Optional<FileItem> variablesItem = getFileItem(fileItems, "variables");
151+
final Optional<Part> variablesItem = getFileItem(fileItems, "variables");
155152
if (variablesItem.isPresent()) {
156-
variables = graphQLObjectMapper.deserializeVariables(new String(variablesItem.get().get()));
153+
variables = graphQLObjectMapper.deserializeVariables(new String(ByteStreams.toByteArray(variablesItem.get().getInputStream())));
157154
}
158155

159156
String operationName = null;
160-
final Optional<FileItem> operationNameItem = getFileItem(fileItems, "operationName");
157+
final Optional<Part> operationNameItem = getFileItem(fileItems, "operationName");
161158
if (operationNameItem.isPresent()) {
162-
operationName = new String(operationNameItem.get().get()).trim();
159+
operationName = new String(ByteStreams.toByteArray(operationNameItem.get().getInputStream())).trim();
163160
}
164161

165162
GraphQLSingleInvocationInput invocationInput = invocationInputFactory.create(new GraphQLRequest(query, variables, operationName), request);
@@ -220,7 +217,18 @@ public String executeQuery(String query) {
220217
}
221218
}
222219

223-
private void doRequest(HttpServletRequest request, HttpServletResponse response, HttpRequestHandler handler) {
220+
private void doRequestAsync(HttpServletRequest request, HttpServletResponse response, HttpRequestHandler handler) {
221+
if (asyncServletMode) {
222+
AsyncContext asyncContext = request.startAsync();
223+
HttpServletRequest asyncRequest = (HttpServletRequest) asyncContext.getRequest();
224+
HttpServletResponse asyncResponse = (HttpServletResponse) asyncContext.getResponse();
225+
new Thread(() -> doRequest(asyncRequest, asyncResponse, handler, asyncContext)).start();
226+
} else {
227+
doRequest(request, response, handler, null);
228+
}
229+
}
230+
231+
private void doRequest(HttpServletRequest request, HttpServletResponse response, HttpRequestHandler handler, AsyncContext asyncContext) {
224232

225233
List<GraphQLServletListener.RequestCallback> requestCallbacks = runListeners(l -> l.onRequest(request, response));
226234

@@ -233,26 +241,24 @@ private void doRequest(HttpServletRequest request, HttpServletResponse response,
233241
runCallbacks(requestCallbacks, c -> c.onError(request, response, t));
234242
} finally {
235243
runCallbacks(requestCallbacks, c -> c.onFinally(request, response));
244+
if (asyncContext != null) {
245+
asyncContext.complete();
246+
}
236247
}
237248
}
238249

239250
@Override
240251
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
241-
doRequest(req, resp, getHandler);
252+
doRequestAsync(req, resp, getHandler);
242253
}
243254

244255
@Override
245256
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
246-
doRequest(req, resp, postHandler);
257+
doRequestAsync(req, resp, postHandler);
247258
}
248259

249-
private Optional<FileItem> getFileItem(Map<String, List<FileItem>> fileItems, String name) {
250-
List<FileItem> items = fileItems.get(name);
251-
if(items == null || items.isEmpty()) {
252-
return Optional.empty();
253-
}
254-
255-
return items.stream().findFirst();
260+
private Optional<Part> getFileItem(Map<String, List<Part>> fileItems, String name) {
261+
return Optional.ofNullable(fileItems.get(name)).filter(list -> !list.isEmpty()).map(list -> list.get(0));
256262
}
257263

258264
private void query(GraphQLQueryInvoker queryInvoker, GraphQLObjectMapper graphQLObjectMapper, GraphQLSingleInvocationInput invocationInput, HttpServletResponse resp) throws IOException {
@@ -272,7 +278,7 @@ private void queryBatched(GraphQLQueryInvoker queryInvoker, GraphQLObjectMapper
272278

273279
queryInvoker.query(invocationInput, (result, hasNext) -> {
274280
respWriter.write(graphQLObjectMapper.serializeResultAsJson(result));
275-
if(hasNext) {
281+
if (hasNext) {
276282
respWriter.write(',');
277283
}
278284
});
@@ -286,16 +292,16 @@ private <R> List<R> runListeners(Function<? super GraphQLServletListener, R> act
286292
}
287293

288294
return listeners.stream()
289-
.map(listener -> {
290-
try {
291-
return action.apply(listener);
292-
} catch (Throwable t) {
293-
log.error("Error running listener: {}", listener, t);
294-
return null;
295-
}
296-
})
297-
.filter(Objects::nonNull)
298-
.collect(Collectors.toList());
295+
.map(listener -> {
296+
try {
297+
return action.apply(listener);
298+
} catch (Throwable t) {
299+
log.error("Error running listener: {}", listener, t);
300+
return null;
301+
}
302+
})
303+
.filter(Objects::nonNull)
304+
.collect(Collectors.toList());
299305
}
300306

301307
private <T> void runCallbacks(List<T> callbacks, Consumer<T> action) {

src/main/java/graphql/servlet/GraphQLContext.java

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,42 @@
22

33
import javax.security.auth.Subject;
44
import javax.servlet.http.HttpServletRequest;
5-
import javax.servlet.http.HttpServletResponse;
65
import javax.servlet.http.Part;
76
import javax.websocket.server.HandshakeRequest;
87
import java.util.List;
98
import java.util.Map;
109
import java.util.Optional;
1110

1211
public class GraphQLContext {
13-
private Optional<HttpServletRequest> request;
14-
private Optional<HttpServletResponse> response;
12+
private HttpServletRequest httpServletRequest;
1513
private HandshakeRequest handshakeRequest;
1614

17-
private Optional<Subject> subject = Optional.empty();
18-
private Optional<Map<String, List<Part>>> files = Optional.empty();
15+
private Subject subject;
16+
private Map<String, List<Part>> files;
1917

20-
public GraphQLContext(Optional<HttpServletRequest> request, Optional<HttpServletResponse> response, HandshakeRequest handshakeRequest) {
21-
this.request = request;
22-
this.response = response;
18+
public GraphQLContext(HttpServletRequest httpServletRequest, HandshakeRequest handshakeRequest, Subject subject) {
19+
this.httpServletRequest = httpServletRequest;
2320
this.handshakeRequest = handshakeRequest;
21+
this.subject = subject;
2422
}
2523

26-
public Optional<HttpServletRequest> getRequest() {
27-
return request;
28-
}
29-
30-
public void setRequest(Optional<HttpServletRequest> request) {
31-
this.request = request;
32-
}
33-
34-
public Optional<HttpServletResponse> getResponse() {
35-
return response;
36-
}
37-
38-
public void setResponse(Optional<HttpServletResponse> response) {
39-
this.response = response;
24+
public Optional<HttpServletRequest> getHttpServletRequest() {
25+
return Optional.ofNullable(httpServletRequest);
4026
}
4127

4228
public Optional<Subject> getSubject() {
43-
return subject;
44-
}
45-
46-
public void setSubject(Optional<Subject> subject) {
47-
this.subject = subject;
29+
return Optional.ofNullable(subject);
4830
}
4931

5032
public Optional<HandshakeRequest> getHandshakeRequest() {
5133
return Optional.ofNullable(handshakeRequest);
5234
}
5335

5436
public Optional<Map<String, List<Part>>> getFiles() {
55-
return files;
37+
return Optional.ofNullable(files);
5638
}
5739

58-
public void setFiles(Optional<Map<String, List<Part>>> files) {
40+
public void setFiles(Map<String, List<Part>> files) {
5941
this.files = files;
6042
}
6143
}

0 commit comments

Comments
 (0)