Skip to content
This repository was archived by the owner on Oct 25, 2021. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
First attempt to make graph POSTs with multiPartFiles work
  • Loading branch information
jakubbrodzinski committed May 24, 2019
commit 87e21fa6d8af3d32159d566f61a4a75dcb81c49a
2 changes: 2 additions & 0 deletions graphql-java-spring-webmvc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ dependencies {
compile "org.springframework:spring-context:$springVersion"
compile "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
compile "com.graphql-java:graphql-java:$graphqlJavaVersion"
compile "javax.servlet:javax.servlet-api:4.0.1"


testCompile("org.assertj:assertj-core:$assertJVersion")
testCompile group: 'junit', name: 'junit', version: '4.12'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,25 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import org.springframework.web.server.ResponseStatusException;

import javax.naming.OperationNotSupportedException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

Expand All @@ -46,7 +53,7 @@ public Object graphqlPOST(
@RequestParam(value = "operationName", required = false) String operationName,
@RequestParam(value = "variables", required = false) String variablesJson,
@RequestBody(required = false) String body,
WebRequest webRequest) throws IOException {
WebRequest webRequest) throws IOException, OperationNotSupportedException {

if (body == null) {
body = "";
Expand All @@ -69,6 +76,45 @@ public Object graphqlPOST(
request.setQuery("");
}
return executeRequest(request.getQuery(), request.getOperationName(), request.getVariables(), webRequest);
}else if(contentType!=null && contentType.startsWith(MediaType.MULTIPART_FORM_DATA_VALUE)){
// In this case body is not mapped, same as all on @RequestParams.
// Because we send files as variables we just have to take care of variables part of deserialized GraphQLRequestBody.
// "map" parameter tells us how to link multiPartFiles to their variables.
// Map can look like this:
// {
// "0" : ["variables.files"],
// "1" : ["variables.filesList.0"],
// "2" : ["variables.filesList.1"]
// }
// It tells us that multipartFile
// that has a key "0" should be linked to variable named file, and multipartFile with a key "1" should be put as 0th indexed element
// in list named filesList in variables and "2" as a 1st element in the same list.
GraphQLRequestBody request = jsonSerializer.deserialize(webRequest.getParameter("operations"),GraphQLRequestBody.class);
if(request.getQuery() != null) {
LinkedHashMap<String, ArrayList<String>> multipartFileKeyVariablePathMap = this.jsonSerializer.deserialize(webRequest.getParameter("map"), LinkedHashMap.class);

StandardMultipartHttpServletRequest multiPartRequest = (StandardMultipartHttpServletRequest) ((ServletWebRequest) webRequest).getNativeRequest();
Map<String, MultipartFile> multipartFileMap = multiPartRequest.getFileMap();

for(Map.Entry<String,MultipartFile> e: multipartFileMap.entrySet()){
String pathString = multipartFileKeyVariablePathMap.get(e.getKey()).get(0); /*i.e. "variables.files" or "variables.fileList.NUMBER*/
if (pathString.matches("variables\\.[a-zA-Z0-9]*?\\.\\d")) {
String[] splittedPath = pathString.split("\\.", 3);
final Object variablesArray = request.getVariables().get(splittedPath[1]);
if (variablesArray instanceof ArrayList)
((ArrayList) variablesArray).set(Integer.parseInt(splittedPath[2]), e.getValue());
else
throw new OperationNotSupportedException("Array of files represented by not supported collection");
} else if (pathString.startsWith("variables.")) {
String[] splittedPath = pathString.split("\\.",2);
request.getVariables().put(splittedPath[1],e.getValue());
}
}
}else {
request.setQuery("");
}

return executeRequest(request.getQuery(),request.getOperationName(),request.getVariables(),webRequest);
}

// In addition to the above, we recommend supporting two additional cases:
Expand Down