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 graphql .ExecutionInput ;
2925import javax .servlet .http .HttpServletRequest ;
3026import javax .servlet .http .HttpServletResponse ;
3127import javax .servlet .http .Part ;
32- import java .io .BufferedInputStream ;
33- import java .io .ByteArrayOutputStream ;
34- import java .io .IOException ;
35- import java .io .InputStream ;
36- import java .io .Writer ;
28+ import java .io .*;
3729import java .security .AccessController ;
3830import java .security .PrivilegedAction ;
39- import java .util .ArrayList ;
40- import java .util .Collection ;
41- import java .util .Collections ;
42- import java .util .HashMap ;
43- import java .util .Iterator ;
44- import java .util .LinkedHashMap ;
45- import java .util .List ;
46- import java .util .Map ;
47- import java .util .Objects ;
48- import java .util .Optional ;
31+ import java .util .*;
4932import java .util .function .BiConsumer ;
5033import java .util .function .Consumer ;
5134import java .util .function .Function ;
@@ -64,12 +47,17 @@ public abstract class GraphQLServlet extends HttpServlet implements Servlet, Gra
6447 public static final int STATUS_BAD_REQUEST = 400 ;
6548
6649 protected abstract GraphQLSchemaProvider getSchemaProvider ();
50+
6751 protected abstract GraphQLContext createContext (Optional <HttpServletRequest > request , Optional <HttpServletResponse > response );
52+
6853 protected abstract Object createRootObject (Optional <HttpServletRequest > request , Optional <HttpServletResponse > response );
54+
6955 protected abstract ExecutionStrategyProvider getExecutionStrategyProvider ();
56+
7057 protected abstract Instrumentation getInstrumentation ();
7158
7259 protected abstract GraphQLErrorHandler getGraphQLErrorHandler ();
60+
7361 protected abstract PreparsedDocumentProvider getPreparsedDocumentProvider ();
7462
7563 private final LazyObjectMapperBuilder lazyObjectMapperBuilder ;
@@ -126,9 +114,8 @@ public GraphQLServlet(ObjectMapperConfigurer objectMapperConfigurer, List<GraphQ
126114 final Object rootObject = createRootObject (Optional .of (request ), Optional .of (response ));
127115
128116 try {
129- Collection <Part > parts = request .getParts ();
130- if (!parts .isEmpty ()) {
131- final Map <String , List <Part >> fileItems = parts .stream ()
117+ if (request .getContentType ().equals ("multipart/form-data" ) && !request .getParts ().isEmpty ()) {
118+ final Map <String , List <Part >> fileItems = request .getParts ().stream ()
132119 .collect (Collectors .toMap (
133120 Part ::getName ,
134121 Collections ::singletonList ,
@@ -189,18 +176,7 @@ public GraphQLServlet(ObjectMapperConfigurer objectMapperConfigurer, List<GraphQ
189176 response .setStatus (STATUS_BAD_REQUEST );
190177 log .info ("Bad POST multipart request: no part named \" graphql\" or \" query\" " );
191178 } else {
192- // this is not a multipart request
193- InputStream inputStream = request .getInputStream ();
194-
195- if (!inputStream .markSupported ()) {
196- inputStream = new BufferedInputStream (inputStream );
197- }
198-
199- if (isBatchedQuery (inputStream )) {
200- doBatchedQuery (getGraphQLRequestMapper ().readValues (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
201- } else {
202- doQuery (getGraphQLRequestMapper ().readValue (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
203- }
179+ handleNonMultipartRequest (request , response , context , rootObject );
204180 }
205181 } catch (Exception e ) {
206182 log .info ("Bad POST request: parsing failed" , e );
@@ -209,6 +185,21 @@ public GraphQLServlet(ObjectMapperConfigurer objectMapperConfigurer, List<GraphQ
209185 };
210186 }
211187
188+ private void handleNonMultipartRequest (HttpServletRequest request , HttpServletResponse response , GraphQLContext context , Object rootObject ) throws Exception {
189+ // this is not a multipart request
190+ InputStream inputStream = request .getInputStream ();
191+
192+ if (!inputStream .markSupported ()) {
193+ inputStream = new BufferedInputStream (inputStream );
194+ }
195+
196+ if (isBatchedQuery (inputStream )) {
197+ doBatchedQuery (getGraphQLRequestMapper ().readValues (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
198+ } else {
199+ doQuery (getGraphQLRequestMapper ().readValue (inputStream ), getSchemaProvider ().getSchema (request ), context , rootObject , request , response );
200+ }
201+ }
202+
212203 protected ObjectMapper getMapper () {
213204 return lazyObjectMapperBuilder .getMapper ();
214205 }
@@ -285,12 +276,12 @@ private Optional<Part> getFileItem(Map<String, List<Part>> fileItems, String nam
285276 private GraphQL newGraphQL (GraphQLSchema schema ) {
286277 ExecutionStrategyProvider executionStrategyProvider = getExecutionStrategyProvider ();
287278 return GraphQL .newGraphQL (schema )
288- .queryExecutionStrategy (executionStrategyProvider .getQueryExecutionStrategy ())
289- .mutationExecutionStrategy (executionStrategyProvider .getMutationExecutionStrategy ())
290- .subscriptionExecutionStrategy (executionStrategyProvider .getSubscriptionExecutionStrategy ())
291- .instrumentation (getInstrumentation ())
292- .preparsedDocumentProvider (getPreparsedDocumentProvider ())
293- .build ();
279+ .queryExecutionStrategy (executionStrategyProvider .getQueryExecutionStrategy ())
280+ .mutationExecutionStrategy (executionStrategyProvider .getMutationExecutionStrategy ())
281+ .subscriptionExecutionStrategy (executionStrategyProvider .getSubscriptionExecutionStrategy ())
282+ .instrumentation (getInstrumentation ())
283+ .preparsedDocumentProvider (getPreparsedDocumentProvider ())
284+ .build ();
294285 }
295286
296287 private void doQuery (GraphQLRequest graphQLRequest , GraphQLSchema schema , GraphQLContext context , Object rootObject , HttpServletRequest httpReq , HttpServletResponse httpRes ) throws Exception {
@@ -348,7 +339,7 @@ private void query(String query, String operationName, Map<String, Object> varia
348339 graphQLResponse .setResponse (response );
349340 responseHandler .handle (graphQLResponse );
350341
351- if (getGraphQLErrorHandler ().errorsPresent (errors )) {
342+ if (getGraphQLErrorHandler ().errorsPresent (errors )) {
352343 runCallbacks (operationCallbacks , c -> c .onError (context , operationName , query , variables , data , errors , extensions ));
353344 } else {
354345 runCallbacks (operationCallbacks , c -> c .onSuccess (context , operationName , query , variables , data , extensions ));
@@ -367,7 +358,7 @@ private Map<String, Object> createResultFromDataErrorsAndExtensions(Object data,
367358 result .put ("errors" , getGraphQLErrorHandler ().processErrors (errors ));
368359 }
369360
370- if (extensions != null ){
361+ if (extensions != null ) {
371362 result .put ("extensions" , extensions );
372363 }
373364
@@ -380,16 +371,16 @@ private <R> List<R> runListeners(Function<? super GraphQLServletListener, R> act
380371 }
381372
382373 return listeners .stream ()
383- .map (listener -> {
384- try {
385- return action .apply (listener );
386- } catch (Throwable t ) {
387- log .error ("Error running listener: {}" , listener , t );
388- return null ;
389- }
390- })
391- .filter (Objects ::nonNull )
392- .collect (Collectors .toList ());
374+ .map (listener -> {
375+ try {
376+ return action .apply (listener );
377+ } catch (Throwable t ) {
378+ log .error ("Error running listener: {}" , listener , t );
379+ return null ;
380+ }
381+ })
382+ .filter (Objects ::nonNull )
383+ .collect (Collectors .toList ());
393384 }
394385
395386 private <T > void runCallbacks (List <T > callbacks , Consumer <T > action ) {
@@ -425,7 +416,8 @@ private static Map<String, Object> deserializeVariablesObject(Object variables,
425416 return genericVariables ;
426417 } else if (variables instanceof String ) {
427418 try {
428- return mapper .readValue ((String ) variables , new TypeReference <Map <String , Object >>() {});
419+ return mapper .readValue ((String ) variables , new TypeReference <Map <String , Object >>() {
420+ });
429421 } catch (IOException e ) {
430422 throw new RuntimeException (e );
431423 }
0 commit comments