Как сохранить Mono <FilePart>в MongoDB? - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь сохранить данные формы (включая некоторые файлы), поступающие из внешнего интерфейса:

React:
handleSubmit = (e) => {
        e.preventDefault();
        e.stopPropagation();
        const { authors, title, genre, description, content, cover} = this.state;
        let formData = new FormData();
        formData.append('authors', authors);
        formData.append('title', title);
        formData.append('genre', genre);
        formData.append('description', description);
        formData.append('content', content, content.name);
        formData.append('cover', cover, cover.name);
        postBook(formData)
            ...
    };

...

export function postBook(formData) {
    return fetch('/api/books/', {
        method: 'post',
        body: formData
    });
}

На сервере я пытаюсь использовать WebFlux и сохранять данные из веб-формы в MongoDB:

@RestController
@RequestMapping("api/books")
public class BookController {
   ...
@PostMapping(value = "/", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public Mono<BookDto> addNewBook(
            @RequestPart("authors") Mono<FormFieldPart> aut,
            @RequestPart("title") Mono<FormFieldPart> tle,
            @RequestPart("genre") Mono<FormFieldPart> gnr,
            @RequestPart("description") Mono<FormFieldPart> descr,
            @RequestPart("content") Mono<FilePart> cont,
            @RequestPart("cover") Mono<FilePart> cov) {
        Mono<String> authors = aut.map(FormFieldPart::value);
        Mono<String> title = tle.map(FormFieldPart::value);
        Mono<String> genre = gnr.map(FormFieldPart::value);
        Mono<String> description = descr.map(FormFieldPart::value);
        Flux<DataBuffer> content = cont.flatMapMany(Part::content);
        Flux<DataBuffer> cover = cov.flatMapMany(Part::content);
        return bookService.addNewBook(authors, title, genre, description, content, cover)
                .map(mapper::mapBookToDto)
                .switchIfEmpty(Mono.error(new Exception()));
    }
}

@Service
public class BookServiceImpl implements BookService {
  private GridFsTemplate fsTemplate;

  @Override
    public Mono<Book> addNewBook(Mono<String> authors, 
                                 Mono<String> title, 
                                 Mono<String> genre, 
                                 Mono<String> description, 
                                 Flux<DataBuffer> content, 
                                 Flux<DataBuffer> cover) {
        ???
        return null;
    }
}

Проблема заключается в том, чтобы сохранить файл в форме Flux<DataBuffer> в MongoDB. Я пытался использовать что-то вроде этого:

content.flatMap(DataBuffer::asInputStream).flatMap(is -> fsTemplate.store(is))

Но, похоже, это не работает. Есть ли способ сохранить Mono<FilePart> в MongoDB как один файл?

Буду признателен за вашу помощь.

1 Ответ

0 голосов
/ 06 мая 2019

ReactiveGridFsTemplate может быть полезен для сохранения Mono<FilePart> в MongoDB:

@PostMapping("")
    public Mono<ResponseEntity> upload(@RequestPart Mono<FilePart> fileParts) {
        return fileParts
            .flatMap(part -> this.gridFsTemplate.store(part.content(), part.filename()))
            .map((id) -> ok().body(Map.of("id", id.toHexString())));
}

нашел здесь

...