graphql-spring-boot 上传二进制文件
Posted
技术标签:
【中文标题】graphql-spring-boot 上传二进制文件【英文标题】:graphql-spring-boot upload binary 【发布时间】:2018-06-11 13:00:04 【问题描述】:我正在尝试将 GraphQL 突变和图像上传为应用程序/表单数据。 GraphQL 部分正在工作,但我想“保存”上传的二进制文件并将路径添加到 GraphQL 数据。在 createGraphQLContext 我可以访问 HttpServletRequest 但(多)部分是空的。 我使用带有嵌入式 tomcat 8.5 的 graphql-spring-boot-starter 和提供的 GraphQL Java Tools
这是我对 /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" )
访问该文件
但我在请求中的部分是空的 intellij debugger
我已将此添加到我的 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);
我不知道该怎么做。希望有人可以帮助我。
谢谢。
【问题讨论】:
【参考方案1】:Spring boot 的嵌入式 Tomcat 默认支持 Servlet 3.x 多部分。 GraphQL java servlet 支持 commons FileUpload。要使事情正常工作,您必须禁用 Spring Boots 默认的多部分配置,例如:
在 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;
【讨论】:
以上是关于graphql-spring-boot 上传二进制文件的主要内容,如果未能解决你的问题,请参考以下文章