首页 > 解决方案 > 通过 react/axios 从 spring 获取请求中查看 pdf

问题描述

我有一个 spring 端点,它提供一个 pdf 作为字节 [] 和一个当我尝试调用端点时得到 406 的 React ui。

弹簧端点:

@GetMapping(value = "report/{report_id}", produces = MediaType.APPLICATION_PDF_VALUE)
    public ResponseEntity<InputStreamResource> generateReviewTaskReport(
            HttpServletResponse response,
            @PathVariable("report_id") String reportId,
            @RequestAttribute(USER_ID) String loginId) {

        byte[] report = reportService.generateReport(reportId, loginId);
        ByteArrayInputStream inputStream =  new ByteArrayInputStream(report);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentLength(report.length);
        headers.add("Content-Disposition", "inline;filename=" + reportId + "_report.pdf");

        return ResponseEntity
                .ok()
                .headers(headers)
                .contentType(MediaType.APPLICATION_PDF)
                .body(new InputStreamResource(inputStream));
    }

我试过了:

headers.add("Content-Disposition", "attachment;filename=" + reportId + "_report.pdf");

同样的结果。

反应请求:

export const getReport = (reportId = '') => (dispatch) => {
  const report = `${apiConfig.reportUrl}${reportId}`

  const promise = axios.get(report,
     {
        responseType: 'blob',
        headers: {
          'Accept': 'application/pdf'
      }
    })

  return dispatch({
    type: GET_REPORT,
    payload: promise,
  })
}


case GET_REPORT:
      if (payload.data) {
        const report = new Blob([payload.data])
        reportUrl = URL.createObjectURL(report)
        window.open(reportUrl, "_blank")
      }

我试过 responseType:'bufferArray',从我的 spring 端点返回一个普通的 byte[],总是得到一个 406。我猜这是因为我的'Accept'标头中有错误的 mime 类型。我试过'application/pdf'和'*/*',结果一样。我需要哪些标头来接受 InputStreamResource 或 byte[]?

使用邮递员,我可以很好地下载文件。

我的配置:

@Component
public class WebConfiguration extends WebMvcConfigurationSupport {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(byteArrayHttpMessageConverter());
        converters.add(new ResourceHttpMessageConverter());
    }

    @Bean
    public HttpMessageConverter byteArrayHttpMessageConverter() {
        ByteArrayHttpMessageConverter arrayHttpMessageConverter =
                new ByteArrayHttpMessageConverter();
        arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
        return arrayHttpMessageConverter;
    }

    private List<MediaType> getSupportedMediaTypes() {
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.APPLICATION_PDF);
        mediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);

        return mediaTypes;
    }
}

标签: reactjsspring-mvcaxios

解决方案


一个通用的解决方案,但我认为在你的情况下它应该可以正常工作;)

axios({
  url: 'http://api.dev/file-download', //your url
  method: 'GET',
  responseType: 'blob', // important
}).then((response) => {
   const url = window.URL.createObjectURL(new Blob([response.data]));
   const link = document.createElement('a');
   link.href = url;
   link.setAttribute('download', 'file.pdf'); //or any other extension
   document.body.appendChild(link);
   link.click();
});

要点:https ://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743

完整学分:https ://gist.github.com/javilobo8


推荐阅读