33import com .fasterxml .jackson .annotation .JsonIgnoreProperties ;
44import com .fasterxml .jackson .core .JsonParser ;
55import com .fasterxml .jackson .core .type .TypeReference ;
6- import com .fasterxml .jackson .databind .DeserializationContext ;
7- import com .fasterxml .jackson .databind .InjectableValues ;
8- import com .fasterxml .jackson .databind .JsonDeserializer ;
9- import com .fasterxml .jackson .databind .ObjectMapper ;
10- import com .fasterxml .jackson .databind .ObjectReader ;
6+ import com .fasterxml .jackson .databind .*;
117import com .fasterxml .jackson .databind .annotation .JsonDeserialize ;
128import com .google .common .io .ByteStreams ;
139import com .google .common .io .CharStreams ;
3026import javax .servlet .http .HttpServletRequest ;
3127import javax .servlet .http .HttpServletResponse ;
3228import javax .servlet .http .Part ;
33- import java .io .BufferedInputStream ;
34- import java .io .ByteArrayOutputStream ;
35- import java .io .IOException ;
36- import java .io .InputStream ;
37- import java .io .Writer ;
29+ import java .io .*;
3830import java .security .AccessController ;
3931import java .security .PrivilegedAction ;
40- import java .util .ArrayList ;
41- import java .util .Collection ;
42- import java .util .Collections ;
43- import java .util .HashMap ;
44- import java .util .Iterator ;
45- import java .util .LinkedHashMap ;
46- import java .util .List ;
47- import java .util .Map ;
48- import java .util .Objects ;
49- import java .util .Optional ;
32+ import java .util .*;
5033import java .util .function .BiConsumer ;
5134import java .util .function .Consumer ;
5235import java .util .function .Function ;
@@ -66,12 +49,17 @@ public abstract class GraphQLServlet extends HttpServlet implements Servlet, Gra
6649 public static final int STATUS_BAD_REQUEST = 400 ;
6750
6851 protected abstract GraphQLSchemaProvider getSchemaProvider ();
52+
6953 protected abstract GraphQLContext createContext (Optional <HttpServletRequest > request , Optional <HttpServletResponse > response );
54+
7055 protected abstract Object createRootObject (Optional <HttpServletRequest > request , Optional <HttpServletResponse > response );
56+
7157 protected abstract ExecutionStrategyProvider getExecutionStrategyProvider ();
58+
7259 protected abstract Instrumentation getInstrumentation ();
7360
7461 protected abstract GraphQLErrorHandler getGraphQLErrorHandler ();
62+
7563 protected abstract PreparsedDocumentProvider getPreparsedDocumentProvider ();
7664
7765 private final LazyObjectMapperBuilder lazyObjectMapperBuilder ;
@@ -128,12 +116,11 @@ public GraphQLServlet(ObjectMapperConfigurer objectMapperConfigurer, List<GraphQ
128116 final Object rootObject = createRootObject (Optional .of (request ), Optional .of (response ));
129117
130118 try {
131- Collection <Part > parts = request .getParts ();
132119 if (APPLICATION_GRAPHQL .equals (request .getContentType ())) {
133120 String query = CharStreams .toString (request .getReader ());
134121 doQuery (query , null , null , getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
135- } else if (! parts .isEmpty ()) {
136- final Map <String , List <Part >> fileItems = parts .stream ()
122+ } else if (request . getContentType () != null && request . getContentType (). startsWith ( "multipart/form-data" ) && ! request . getParts () .isEmpty ()) {
123+ final Map <String , List <Part >> fileItems = request . getParts () .stream ()
137124 .collect (Collectors .toMap (
138125 Part ::getName ,
139126 Collections ::singletonList ,
@@ -195,18 +182,7 @@ public GraphQLServlet(ObjectMapperConfigurer objectMapperConfigurer, List<GraphQ
195182 response .setStatus (STATUS_BAD_REQUEST );
196183 log .info ("Bad POST multipart request: no part named \" graphql\" or \" query\" " );
197184 } else {
198- // this is not a multipart request
199- InputStream inputStream = request .getInputStream ();
200-
201- if (!inputStream .markSupported ()) {
202- inputStream = new BufferedInputStream (inputStream );
203- }
204-
205- if (isBatchedQuery (inputStream )) {
206- doBatchedQuery (getGraphQLRequestMapper ().readValues (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
207- } else {
208- doQuery (getGraphQLRequestMapper ().readValue (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
209- }
185+ handleNonMultipartRequest (request , response , context , rootObject );
210186 }
211187 } catch (Exception e ) {
212188 log .info ("Bad POST request: parsing failed" , e );
@@ -215,6 +191,21 @@ public GraphQLServlet(ObjectMapperConfigurer objectMapperConfigurer, List<GraphQ
215191 };
216192 }
217193
194+ private void handleNonMultipartRequest (HttpServletRequest request , HttpServletResponse response , GraphQLContext context , Object rootObject ) throws Exception {
195+ // this is not a multipart request
196+ InputStream inputStream = request .getInputStream ();
197+
198+ if (!inputStream .markSupported ()) {
199+ inputStream = new BufferedInputStream (inputStream );
200+ }
201+
202+ if (isBatchedQuery (inputStream )) {
203+ doBatchedQuery (getGraphQLRequestMapper ().readValues (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
204+ } else {
205+ doQuery (getGraphQLRequestMapper ().readValue (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
206+ }
207+ }
208+
218209 protected ObjectMapper getMapper () {
219210 return lazyObjectMapperBuilder .getMapper ();
220211 }
@@ -291,12 +282,12 @@ private Optional<Part> getFileItem(Map<String, List<Part>> fileItems, String nam
291282 private GraphQL newGraphQL (GraphQLSchema schema ) {
292283 ExecutionStrategyProvider executionStrategyProvider = getExecutionStrategyProvider ();
293284 return GraphQL .newGraphQL (schema )
294- .queryExecutionStrategy (executionStrategyProvider .getQueryExecutionStrategy ())
295- .mutationExecutionStrategy (executionStrategyProvider .getMutationExecutionStrategy ())
296- .subscriptionExecutionStrategy (executionStrategyProvider .getSubscriptionExecutionStrategy ())
297- .instrumentation (getInstrumentation ())
298- .preparsedDocumentProvider (getPreparsedDocumentProvider ())
299- .build ();
285+ .queryExecutionStrategy (executionStrategyProvider .getQueryExecutionStrategy ())
286+ .mutationExecutionStrategy (executionStrategyProvider .getMutationExecutionStrategy ())
287+ .subscriptionExecutionStrategy (executionStrategyProvider .getSubscriptionExecutionStrategy ())
288+ .instrumentation (getInstrumentation ())
289+ .preparsedDocumentProvider (getPreparsedDocumentProvider ())
290+ .build ();
300291 }
301292
302293 private void doQuery (GraphQLRequest graphQLRequest , GraphQLSchema schema , GraphQLContext context , Object rootObject , HttpServletRequest httpReq , HttpServletResponse httpRes ) throws Exception {
@@ -354,7 +345,7 @@ private void query(String query, String operationName, Map<String, Object> varia
354345 graphQLResponse .setResponse (response );
355346 responseHandler .handle (graphQLResponse );
356347
357- if (getGraphQLErrorHandler ().errorsPresent (errors )) {
348+ if (getGraphQLErrorHandler ().errorsPresent (errors )) {
358349 runCallbacks (operationCallbacks , c -> c .onError (context , operationName , query , variables , data , errors , extensions ));
359350 } else {
360351 runCallbacks (operationCallbacks , c -> c .onSuccess (context , operationName , query , variables , data , extensions ));
@@ -373,7 +364,7 @@ private Map<String, Object> createResultFromDataErrorsAndExtensions(Object data,
373364 result .put ("errors" , getGraphQLErrorHandler ().processErrors (errors ));
374365 }
375366
376- if (extensions != null ){
367+ if (extensions != null ) {
377368 result .put ("extensions" , extensions );
378369 }
379370
@@ -386,16 +377,16 @@ private <R> List<R> runListeners(Function<? super GraphQLServletListener, R> act
386377 }
387378
388379 return listeners .stream ()
389- .map (listener -> {
390- try {
391- return action .apply (listener );
392- } catch (Throwable t ) {
393- log .error ("Error running listener: {}" , listener , t );
394- return null ;
395- }
396- })
397- .filter (Objects ::nonNull )
398- .collect (Collectors .toList ());
380+ .map (listener -> {
381+ try {
382+ return action .apply (listener );
383+ } catch (Throwable t ) {
384+ log .error ("Error running listener: {}" , listener , t );
385+ return null ;
386+ }
387+ })
388+ .filter (Objects ::nonNull )
389+ .collect (Collectors .toList ());
399390 }
400391
401392 private <T > void runCallbacks (List <T > callbacks , Consumer <T > action ) {
@@ -431,7 +422,8 @@ private static Map<String, Object> deserializeVariablesObject(Object variables,
431422 return genericVariables ;
432423 } else if (variables instanceof String ) {
433424 try {
434- return mapper .readValue ((String ) variables , new TypeReference <Map <String , Object >>() {});
425+ return mapper .readValue ((String ) variables , new TypeReference <Map <String , Object >>() {
426+ });
435427 } catch (IOException e ) {
436428 throw new RuntimeException (e );
437429 }
0 commit comments