主要问题是,graphql-java-tools
对于包含非基本类型(如List
、String
、Integer
、Boolean
等)的字段的解析器进行字段映射可能会有问题...
我们通过创建我们自己的自定义标量来解决这个问题,基本上就像ApolloScalar.Upload
. 但是,我们不是返回 type 的对象Part
,而是返回我们自己的解析器类型FileUpload
,其中包含 contentType asString
和 inputStream as byte[]
,然后字段映射工作,我们可以byte[]
在解析器中读取。
首先,设置要在解析器中使用的新类型:
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
}
让我知道它是否不适合你:)