主要问题是graphql-java-tools 可能无法为包含非基本类型字段的解析器进行字段映射,例如List、String、Integer、Boolean 等...
我们通过创建自己的自定义标量(基本上类似于ApolloScalar.Upload)解决了这个问题。但是不是返回类型为Part的对象,而是返回我们自己的解析器类型FileUpload,其中包含String的contentType和byte[]的inputStream,然后字段映射工作,我们可以读取@987654332 @ 在解析器中。
首先,设置要在解析器中使用的新类型:
public class FileUpload {
private String contentType;
private byte[] content;
public FileUpload(String contentType, byte[] content) {
this.contentType = contentType;
this.content = content;
}
public String getContentType() {
return contentType;
}
public byte[] getContent() {
return content;
}
}
然后我们创建一个看起来很像ApolloScalars.Upload 的自定义标量,但返回我们自己的解析器类型FileUpload:
public class MyScalars {
public static final GraphQLScalarType FileUpload = new GraphQLScalarType(
"FileUpload",
"A file part in a multipart request",
new Coercing<FileUpload, Void>() {
@Override
public Void serialize(Object dataFetcherResult) {
throw new CoercingSerializeException("Upload is an input-only type");
}
@Override
public FileUpload parseValue(Object input) {
if (input instanceof Part) {
Part part = (Part) input;
try {
String contentType = part.getContentType();
byte[] content = new byte[part.getInputStream().available()];
part.delete();
return new FileUpload(contentType, content);
} catch (IOException e) {
throw new CoercingParseValueException("Couldn't read content of the uploaded file");
}
} else if (null == input) {
return null;
} else {
throw new CoercingParseValueException(
"Expected type " + Part.class.getName() + " but was " + input.getClass().getName());
}
}
@Override
public FileUpload parseLiteral(Object input) {
throw new CoercingParseLiteralException(
"Must use variables to specify Upload values");
}
});
}
在解析器中,您现在可以从解析器参数中获取文件:
public class FileUploadResolver implements GraphQLMutationResolver {
public Boolean uploadFile(FileUpload fileUpload) {
String fileContentType = fileUpload.getContentType();
byte[] fileContent = fileUpload.getContent();
// Do something in order to persist the file :)
return true;
}
}
在模式中,您将其声明为:
scalar FileUpload
type Mutation {
uploadFile(fileUpload: FileUpload): Boolean
}
如果它不适合你,请告诉我:)