Реакция не может получить ответ restcontroller

Я попытался использовать restController для создания байтового массива файла, но когда я возвращаю его, чтобы отреагировать, реакция не получила байтовый массив. интерфейсная часть использует реакцию, внутренняя часть использует spring restController, и я использую Http для связи как спереди, так и сзади. что-то не так в моем коде? Спасибо за вашу помощь.

restController:

String fileName = DateUtility.dateToStr(new Date(), DateUtility.YYYYMMDD_HHMMSS) + " - "
            + reportNmaeByType.get(exportParam.getReportType()) + ".xls";
    HttpHeaders headers = new HttpHeaders();
    headers.setContentDispositionFormData("attachment", fileName);
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

    return new ResponseEntity<>(excelByte, HttpStatus.OK);

реагировать:

createExcelFile(){
    var params = {
    reportResultList: this.state.reportResult, 
    reportType: getReportSelector().state.selectedReportType,
    selectColumnMap: this.state.selectColumn,
    selectCusColumnMap: this.state.selectCusColumn
                }
    fetch("http://localhost:8080/mark-web/file/createExcel", {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(params)
    }).then(res => {
        if (res.ok) {
            console.log(res)
            console.log(this)
             console.log('create excel success!!')
        } else {
            console.log('create excel Fail!!')
        }
    })
}

отклик: введите описание изображения здесь

Обновление 2018/09/16:

Я добавил код в функцию реакции, и он, наконец, смог загрузить файл Excel, но файл сломан. Я проверил объект blob в ответ. он показывает, что blob - это объект json. это потому, что я не декодировал объект blob?

Реагировать:

}).then(res => {
       if(!res.ok){
        console.log("Failed To Download File")
       }else{
        return res.blob()
       }
    }).then(blob => {
        console.log(blob)
        let url = URL.createObjectURL(blob)
        console.log(url)
        var downloadAnchorNode = document.createElement('a')
        downloadAnchorNode.setAttribute("href", url)
        downloadAnchorNode.setAttribute("download", "excel" + ".xls")
        downloadAnchorNode.click()
        downloadAnchorNode.remove()
    })

отклик:

введите описание изображения здесь

И какой ответ вы получаете в своем браузере? Есть ошибка?

mrkernelpanic 10.09.2018 09:48

я не получил ни одной ошибки. я просто не нашел ответа

Jack 10.09.2018 09:55

помимо байтового массива, я мог бы получить еще один ответ

Jack 10.09.2018 10:08

Можете ли вы добавить блок catch в цепочку fetch .then? возможно, есть какая-то ошибка, которую вы не видите. Кроме того, если вы можете проверить вкладку сети инструментов разработчика браузеров, отправляется ли запрос и получил ли вы ожидаемый ответ.

dubes 10.09.2018 10:22

@dubes, я добавил картинку ответа.

Jack 10.09.2018 11:01

Спасибо! Итак, я предполагаю, что проблема в том, что вы не видите никакого вывода в console.log(res). Это верно?

dubes 10.09.2018 12:01

линейный код может работать.

Jack 10.09.2018 12:05
1
7
527
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, исходя из вашего сетевого графика, похоже, что ваш запрос завершается, как ожидалось, но вы просто не можете получить ByteArray из ответа.

С обычными запросами, которые возвращают JSON или XML для e.x. вы можете прочитать их за один раз, поскольку они являются частью тела. Однако в вашем случае ваше тело содержит Stream. Таким образом, вам придется самостоятельно обрабатывать чтение этого потока.

Вы можете сделать это с помощью response.blob():

Метод blob () считывает поток до завершения и возвращает объект Blob. Затем вы можете использовать этот объект blob для встраивания изображения или скачать файл. Для всех намерений и целей я бы рекомендовал использовать это. Если вы не имеете дело с огромными файлами (> 500 МБ), этого должно хватить.

Например:

fetch("http://localhost:8080/mark-web/file/createExcel", {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify(params)
    }).then(res => {
        if (!res.ok) { 
            throw new Error(res.statusText);
        } else {
            return res.blob()
        }
   }).then(blob => {// do your thing})
   .catch(err => console.log(error))

Или

Вы можете использовать экспериментальный интерфейс ReadableStream для более детального контроля над тем, что вы хотите с ним делать.

я хотел бы задать вопрос. байтовый массив и строка Base64 здесь одно и то же? Спасибо за вашу помощь

Jack 11.09.2018 08:38
Base64 - это схема кодирования, где массив байтов - это содержимое вашего файла. Однако Spring может отправлять вам массив байтов, закодированный в Base64. Обычные операции с большими двоичными объектами должны позаботиться об этом (я думаю), дайте мне знать, если вы столкнетесь с конкретной проблемой
dubes 11.09.2018 08:56

Я столкнулся с проблемой blob. Я предоставил некоторую информацию вверху. Я использовал java.util.Base64 для кодирования файла Excel в restController. искренне благодарю за ответ.

Jack 16.09.2018 19:36

@Jack это может быть связано с неправильным типом содержимого (должен быть октетным потоком, но, похоже, читается как json) в ответе вашего контроллера отдыха. Взгляните на этот ответ о том, как лучше всего отправить файл: stackoverflow.com/a/35683261/1695393, дайте мне знать, если он по-прежнему не работает

dubes 18.09.2018 09:28

спасибо за вашу помощь. я решил свои проблемы

Jack 28.09.2018 11:53

Потрясающие! Рад слышать!

dubes 28.09.2018 12:50

Другие вопросы по теме