如果我使用graphql,我无法找到如何上传文件,有人能给我演示一下吗?我会很感激的!
参考资料:https://github.com/graphql-java-kickstart/graphql-java-tools/issues/240
我用graphql-java-kickstart graphql-java-tools在springboot中尝试过,但是它没有工作。
@Component
public class FilesUpload implements GraphQLMutationResolver {
public Boolean testMultiFilesUpload(List<Part> parts, DataFetchingEnvironment env) {
// get file parts from DataFetchingEnvironment, the parts parameter is not used
List<Part> attchmentParts = env.getArgument("files");
System.out.println(attchmentParts);
return true;
}
}这是我的模式
type Mutation {
testSingleFileUpload(file: Upload): UploadResult
}我希望这个解析器可以打印attchmentParts,所以我可以得到文件部分。
发布于 2019-08-08 02:20:51
scalar Upload
我们应该将GraphQLScalarType配置为上传,使用如下所示:
@Configuration公共类GraphqlConfig { @Bean公共GraphQLScalarType uploadScalarDefine() {返回ApolloScalars.Upload;}这是Resolver:
public Boolean testMultiFilesUpload(List<Part> parts, DataFetchingEnvironment env) {
// get file parts from DataFetchingEnvironment, the parts parameter is not use
List<Part> attachmentParts = env.getArgument("files");
int i = 1;
for (Part part : attachmentParts) {
String uploadName = "copy" + i;
try {
part.write("your path:" + uploadName);
} catch (IOException e) {
e.printStackTrace();
}
i++;
}
return true;
}
}javax.servlet.http.Part配置杰克逊反序列化器并将其注册到ObjectMapper
公共类PartDeserializer扩展JsonDeserializer {@覆盖公共部分反序列化(JsonParser p,DeserializationContext ctxt)抛出IOException,JsonProcessingException {返回null;}
为什么我们返回null?因为List<Part> parts总是null,所以在解析器的方法中,从DataFetchingEnvironment获取parts参数;
Environment.getArgument(“文件”)将其注册到ObjectMapper:
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
SimpleModule module = new SimpleModule();
module.addDeserializer(Part.class, new PartDeserializer());
objectMapper.registerModule(module);
return objectMapper;
}操作{“查询”:“突变($files: Upload!!) {testMultiFilesUpload(文件:$文件)}”,“变量”:{“文件”:null }映射{ " file0 ":"variables.files.0“,”file1“:”variables.file.1“}file0文件file1文件
就像这样:
请记住选择窗体数据选项。

通过,我们可以上传多个文件,
发布于 2019-10-24 14:58:42
主要的问题是,graphql-java-tools可能有一些问题,需要为包含非基本类型的字段(如List、String、Integer、Boolean等)的解析器进行字段映射。
我们通过创建我们自己的自定义标量来解决这个问题,这基本上类似于ApolloScalar.Upload。但是,我们没有返回Part类型的对象,而是返回自己的解析器类型FileUpload,其中包含contentType作为String,inputStream作为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
}如果对你不起作用,请告诉我:)
发布于 2020-05-14 21:04:50
为了添加到上面的答案中,对于任何像我这样可以用GraphQLSchemaGenerator和模式优先方法找到0个文件上传示例的人,您必须创建一个TypeMapper并将其添加到您的GraphQLSchemaGenerator中:
public class FileUploadMapper implements TypeMapper {
@Override
public GraphQLOutputType toGraphQLType(
final AnnotatedType javaType, final OperationMapper operationMapper,
final Set<Class<? extends TypeMapper>> mappersToSkip, final BuildContext buildContext) {
return MyScalars.FileUpload;
}
@Override
public GraphQLInputType toGraphQLInputType(
final AnnotatedType javaType, final OperationMapper operationMapper,
final Set<Class<? extends TypeMapper>> mappersToSkip, final BuildContext buildContext) {
return MyScalars.FileUpload;
}
@Override
public boolean supports(final AnnotatedType type) {
return type.getType().equals(FileUpload.class); //class of your fileUpload POJO from the previous answer
}
}然后在GraphQL @配置文件中构建GraphQLSchema:
public GraphQLSchema schema(GraphQLSchemaGenerator schemaGenerator) {
return schemaGenerator
.withTypeMappers(new FileUploadMapper()) //add this line
.generate();
}然后在你的变异解析器中
@GraphQLMutation(name = "fileUpload")
public void fileUpload(
@GraphQLArgument(name = "file") FileUpload fileUpload //type here must be the POJO.class referenced in your TypeMapper
) {
//do something with the byte[] from fileUpload.getContent();
return;
}https://stackoverflow.com/questions/57372259
复制相似问题