所以我已经在这两天了,并且在Java中不够精明,无法完全实现解决这个问题的方法。在客户端我发现了一些excellent user documentation,并且相信我有正确的部分,但是当涉及到处理服务器中的入站multipart / formdata时,我有点迷失。
我的应用程序的基础是基于HowToGraphQL Java教程,因为我觉得他们在组织代码库方面做得很好,并使事情变得非常简单和易懂。不幸的是,文件上传不是他们所涵盖的领域,而是根据graphql-java软件包的维护者no plans exist to directly support this feature。
然而,这并不是说这是不可能的。 GraphQL规范本身就是一个指南,社区选择如何调用规范取决于它们。许多人已经成功地整合了文件上传,尽管通常包含custom middleware
遗憾的是,对我而言,障碍很可能只是缺乏领域知识。我主要使用JavaScript和Python,大多数都有Java的学术经验。不完全确定从哪里开始,但我想我将需要跟踪响应对象,我认为该对象绑定到SimpleGraphQLServlet类并找到提取入站文件对象的方法。
希望得到一些更专业的建议或帮助来提出解决方案。我没有在SO上找到任何可靠的基于Java的片段来解决这个问题,因此解决这个问题可能会让其他人试图采用这个平台。
编辑:
可能找到了一种方法来做到这一点,但仍未找出具体细节。在扩展SimpleGraphQLServlet类的GraphQLEndpoint类中,我们公开了doPost()方法。然而,提取数据最终导致一系列错误,第一个错误是使用@MultipartConfig注释解决的,然而下一个错误让我再次陷入停滞状态。 “缺少MultiPart请求的内容。”
这个doPost()方法似乎在发生突变后被调用,所以即使我设法获取提取的文件数据,似乎数据也会出错。另外我想知道丢失的内容是否是Mutation消费后期数据的结果,假设它甚至到达了。
然而,所有其他参数完好无损,因此只需访问此文件即可。
答案 0 :(得分:1)
关于HowToGraphQL的Java教程令人遗憾地过时了。我正在努力更新它(我是原作者),但这需要时间。
当前的最佳实践是在以模式优先方式工作时直接使用graphql-java的RuntimeWiring
*。这里有一些基本文档:http://graphql-java.readthedocs.io/en/v6/schema.html
无论如何,处理文件上传的方式没有改变:将整个HttpServletRequest
对象或仅仅二进制部分粘贴到共享上下文中:
graphQL.execute(ExecutionInput.newExecutionInput()
.query(operation)
.context(request.getPart("file")) //add the binary to the context
.build());
稍后,在DataFetcher
中,您可以通过以下方式获取它:DataFetchingEnvironment#getContext
:
Part file = environment.getContext();
file.getInputStream(); //do something with the binary content
当然,您可以使用其他(动态)结构作为上下文,而不是直接使用二进制。
这种处理上传的侧载方式是使用JSON作为传输格式的结果,而JSON是文本的。文件下载通常在GraphQL之外处理的原因相同(其中响应仅包含启动下载所需的ID或URL)。参考服务器实现包括使用相同策略的示例 目前,据我所知,还没有非JSON GraphQL客户端。
*对于代码优先,graphql-spqr(我的项目)仍然是最方便的方式。
答案 1 :(得分:0)
目前,不幸的是,对我来说解决方案并不完全符合我认为的最佳实践,使用可上传文件,作为multipart / form-data发送,然后在服务器上注入中间件。但是我能够传输文件数据,所以这是一个很好的开始。
最终我选择将上传的文件编码为base64,然后通过GraphQL突变将数据作为String类型发送,然后在接收时我能够解码base64字符串。
现在我所看到的只是传输的文件内容,而不是元数据。由于某些元数据对我来说很有价值,因此需要与base64字符串一起发送,或者我只是忽略了这个元素并确实存在。
无论哪种方式,我都会在解决这个问题时留下一些我发现有用的资源,如果有其他人遇到这个问题,可能会觉得它很有用。我不认为我当前的解决方案是真正的答案,所以也许随着这些软件包的发展,我们将看到更好的方法来通过Relay / graphql-java上传文件。