Вопрос:

GraphQL-Spring-Boot загрузить двоичный файл

java spring spring-boot graphql

1290 просмотра

1 ответ

36 Репутация автора

Я пытаюсь загрузить мутацию GraphQL и изображение в виде application / form-data. Часть GraphQL работает, но я хотел бы «сохранить» загруженный двоичный файл и добавить путь к данным GraphQL. В createGraphQLContext у меня есть доступ к HttpServletRequest, но (multi) части пусты. Я использую graphql-spring-boot-starter со встроенным tomcat 8.5 и прилагаемыми Java-инструментами GraphQL

Это мой ретранслятор современного вызова / 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" )

Но мои части в запросах являются пустым 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);
    }
}

Я понятия не имею, что делать. Надеюсь, кто-то может мне помочь.

Спасибо.

Автор: Mike Источник Размещён: 01.01.2018 02:33

Ответы (1)


2 плюса

36 Репутация автора

Решение

По умолчанию встроенный в Spring boot Tomcat поддерживает многочастную поддержку Servlet 3.x. Java-сервлет GraphQL поддерживает использование FileUpload. Чтобы все заработало, вы должны отключить конфигурацию Spring по умолчанию, состоящую из нескольких частей, например:

Добавьте maven-зависимость для commons-fileupload в pom.xml

    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.3</version>
    </dependency>

Application.yml

spring:
    servlet:
      multipart:
         enabled: false

Класс Spring Boot Application

@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;
    }
}
Автор: Mike Размещён: 13.01.2018 03:38
Вопросы из категории :
32x32