graphql-spring-boot上传二进制文件 [英] graphql-spring-boot upload binary
问题描述
我正在尝试上传GraphQL突变和图像作为应用程序/表单数据. GraphQL部分正在工作,但是我想保存"上载的二进制文件并将路径添加到GraphQL数据.在createGraphQLContext中,我可以访问HttpServletRequest,但是(多个)部分为空. 我将 graphql-spring-boot-starter 与嵌入式tomcat 8.5和提供了 GraphQL Java工具
I am trying to upload a GraphQL mutation and an image as application/form-data. The GraphQL part is working, but I would like to 'save' the uploaded binary and add the path to the GraphQL data. In the createGraphQLContext I have access to the HttpServletRequest but the (multi)parts are empty. I use the graphql-spring-boot-starter with embedded tomcat 8.5 and the supplied GraphQL Java Tools
这是我对/graphql的Relay Modern呼叫
This is my Relay Modern call to /graphql
------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" )
In my @Component
public class MyGraphQLContextBuilder implements GraphQLContextBuilder
I have access to HttpServletRequest
and would like to access the file using req.getPart( "file" )
但是我在请求中的部分是空的 智能调试器
But my parts in the requests are empty intellij debugger
我已将其添加到我的应用程序中.yml
I've added this to my 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启用多部分配置,但部分仍然为空.
And tried different @configuration to enable multipart configurations but parts are still empty.
@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);
}
}
我不知道该怎么办.希望有人能帮助我.
I have no clue what to do. Hoping some one could help me.
谢谢.
推荐答案
Spring boot的嵌入式Tomcat默认为Servlet 3.x多部分支持. GraphQL Java servlet支持公用FileUpload.为了使工作正常,您必须禁用Spring boots默认的multipart配置,例如:
Spring boot's embedded Tomcat is defaulted to Servlet 3.x multipart support. GraphQL java servlet supports commons FileUpload. To make things work you have to disable Spring boots default multipart config, like:
在pom.xml中为commons-fileupload添加maven依赖
Add maven dependency for commons-fileupload in pom.xml
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
Application.yml
Application.yml
spring:
servlet:
multipart:
enabled: false
Spring Boot Application类
Spring Boot Application class
@EnableAutoConfiguration(exclude={MultipartAutoConfiguration.class})
然后在您的@Configuration中添加一个@Bean
And in your @Configuration add a @Bean
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(100000);
return multipartResolver;
}
现在,您可以在GraphQL上下文中找到上载的多部分文件,因为它们已自动映射到:
Now you can find the uploaded multipart files in the GraphQL Context because they are automatically mapped to:
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上传二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!