graphql-spring-boot上传二进制文件 [英] graphql-spring-boot upload binary

查看:121
本文介绍了graphql-spring-boot上传二进制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试上传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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆