我正在尝试上传GraphQL突变和图像作为应用程序/表单数据。GraphQL部分正在工作,但是我想“保存”上载的二进制文件并将路径添加到GraphQL数据。在createGraphQLContext中,我可以访问HttpServletRequest,但是(多个)部分为空。我使用带有嵌入式tomcat 8.5和提供的GraphQL Java工具的graphql-spring-boot-starter
这是我对/ graphql的Relay Modern调用
------WebKitFormBoundaryWBzwQyVX0TvBTIBD Content-Disposition: form-data; name="query" mutation CreateProjectMutation( $input: ProjectInput! ) { createProject(input: $input) { id name } } ------WebKitFormBoundaryWBzwQyVX0TvBTIBD Content-Disposition: form-data; name="variables" {"input":{"name":"sdasas"}} ------WebKitFormBoundaryWBzwQyVX0TvBTIBD Content-Disposition: form-data; name="file"; filename="51zvT5zy44L._SL500_AC_SS350_.jpg" Content-Type: image/jpeg ------WebKitFormBoundaryWBzwQyVX0TvBTIBD--
在我中,@Component public class MyGraphQLContextBuilder implements GraphQLContextBuilder我有权HttpServletRequest使用以下文件访问该文件:req.getPart( "file" )
@Component public class MyGraphQLContextBuilder implements GraphQLContextBuilder
HttpServletRequest
req.getPart( "file" )
但是我在请求中的部分是空的 intellij调试器
我已将此添加到我的application.yml
spring: http: multipart: enabled: true file-size-threshold: 10MB location: /tmp max-file-size: 10MB max-request-size: 15MB resolve-lazily: false
并尝试使用不同的@configuration启用多部分配置,但部分仍然为空。
@Configuration public class MultipartConfig { @Bean public MultipartResolver multipartResolver() { StandardServletMultipartResolver resolver = new StandardServletMultipartResolver(); return resolver; } } import javax.servlet.MultipartConfigElement; import javax.servlet.ServletRegistration.Dynamic; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class MyInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] {}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[] { MultipartConfig.class }; } @Override protected String[] getServletMappings() { return new String[] { "/graphql" }; } @Override protected void customizeRegistration(Dynamic registration) { //Parameters:- // location - the directory location where files will be stored // maxFileSize - the maximum size allowed for uploaded files // maxRequestSize - the maximum size allowed for multipart/form-data requests // fileSizeThreshold - the size threshold after which files will be written to disk MultipartConfigElement multipartConfig = new MultipartConfigElement("/tmp", 1048576, 10485760, 0); registration.setMultipartConfig(multipartConfig); } }
我不知道该怎么办。希望有人可以帮助我。
谢谢。
Spring boot的嵌入式Tomcat默认为Servlet 3.x多部分支持。GraphQL Java servlet支持公用FileUpload。为了使工作正常,您必须禁用Spring boots默认的multipart配置,例如:
在pom.xml中为commons-fileupload添加Maven依赖项
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.3</version> </dependency>
Application.yml
spring: servlet: multipart: enabled: false
Spring Boot应用程序类
@EnableAutoConfiguration(exclude={MultipartAutoConfiguration.class})
然后在您的@Configuration中添加一个@Bean
@Bean(name = "multipartResolver") public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(); multipartResolver.setMaxUploadSize(100000); return multipartResolver; }
现在,您可以在GraphQL上下文中找到上载的多部分文件,因为它们会自动映射到:
environment -> context -> files
可从 DataFetchingEnvironment访问
突变的实现示例:
@Component public class Mutation implements GraphQLMutationResolver { @Autowired private TokenService tokenService; @Autowired private UserRepository userRepository; @Autowired private UserService userService; @Autowired private ProjectRepository repository; @Autowired @Qualifier( value = "modeshape" ) private StorageService storageService; @GraphQLField @GraphQLRelayMutation public ProjectItem createProject( CreateProjectInput input, DataFetchingEnvironment environment ) { Project project = new Project( input.getName() ); project.setDescription( input.getDescription() ); GraphQLContext context = environment.getContext(); Optional<Map<String, List<FileItem>>> files = context.getFiles(); files.ifPresent( keys -> { List<FileItem> file = keys.get( "file" ); List<StorageService.FileInfo> storedFiles = file.stream().map( f -> storageService.store( f, "files", true ) ).collect( Collectors.toList() ); project.setFile( storedFiles.get( 0 ).getUuid() ); } ); repository.save( project ); return new ProjectItem( project ); } class CreateProjectInput { private String name; private String description; private String clientMutationId; @GraphQLField public String getName() { return name; } public String getDescription() { return description; } public void setDescription( String description ) { this.description = description; } @GraphQLField public String getClientMutationId() { return clientMutationId; } }