CompletableFuture в SpringBoot-контроллере не работает, если тип возвращаемого значения метода void - PullRequest
0 голосов
/ 03 октября 2019

Я обнаружил следующую проблему, пытаясь вернуть фотографию в контроллере SpringBoot (оба метода имеют одинаковое поведение, но второй возвращает CompletableFuture).

Метод 1: ничего не отправляется в outputStream, и ответом является http 200.

@RequestMapping(value = FIND_PHOTO, method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
    public void getPhoto(HttpServletResponse response, @PathVariable String id) {
        ExceptionalConsumer<String, IOException> photoConsumer = photo -> {
            ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(photo));
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
            StreamUtils.copy(bais, response.getOutputStream());
        };

        photoService.findPhoto(id) //This returns a CompletableFuture<String>
            .thenAccept(photoConsumer);
    }

Метод 2: Возвращение данных через outputStream.

  @RequestMapping(value = FIND_PHOTO, method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
    public CompletableFuture<Void> getPhoto(HttpServletResponse response, @PathVariable String id) {
        ExceptionalConsumer<String, IOException> photoConsumer = photo -> {
            ByteArrayInputStream bais = new ByteArrayInputStream(Base64.getDecoder().decode(photo));
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
            StreamUtils.copy(bais, response.getOutputStream());
        };

        return photoService.findPhoto(id)
            .thenAccept(photoConsumer);
    }

Я думаю, что у Spring есть своего рода очередь для CompletableFutures, ожидающей завершения, но если возвращаемый метод равен void, то Spring не знает об асинхронном поведении, и тогда мне нужно будет вызвать get() или join() сам.

Может ли кто-нибудь подтвердить, является ли это реальным поведением или есть ошибка с моей стороны?

1 Ответ

0 голосов
/ 03 октября 2019

На самом деле вы не должны вызывать get () для CompletableFuture, если вы не обрабатываете исключения для этого ....

Spring не имеет этой очереди. Вот как это должно работать, если вы не вернете ничего, кроме того, что вы должны вызывать join (), и возвращенный объект из метода будет равен T для CompleatableFuture, или вы можете просто вернуть завершаемое будущее, поэтому ваши наблюдения верны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...