簡體   English   中英

如何在 Spring 引導中使用 restTemplate 檢索資源 object?

[英]How do I retrieve Resource object using restTemplate in Spring Boot?

所以,基本上是標題。

我有 2 個微服務。 一個生成並發送一個 zip 文件,另一個接收它,然后施展魔法,將其轉換為字節數組 [],然后將其發送到其他地方。 但這只是理論上的——我無法讓它發揮作用。

我需要下載一個資源( https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/resources.html ),其中包含我生成的 zip 存檔被包裝到的 InputStream . 將它寫在 HttpServletResponse 的 OutputStream 中對我不起作用,因為我無法使用它 - 稍后我需要操作文件,這種方法僅適用於瀏覽器下載(?)

所以我在第一個微服務中這樣做了:

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(baos);
        ZipOutputStream zos = new ZipOutputStream(bos);
        try {
            zos = service.generateZip(blablabla, zos);

            baos.close();
            bos.close();
            zos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        ByteArrayResource resource = new ByteArrayResource(baos.toByteArray());    

        ResponseEntity<Resource> response = ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType("application/zip;charset=UTF-8"))
                    .contentLength(resource.contentLength())
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            ContentDisposition.parse(format("attachment; filename=\"doc_%s.zip\"", id)).toString())
                    .body(resource); 

這是第二個:

    public byte[] getZip(DocRequest request) throws IOException {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/zip;charset=UTF-8"));
        headers.setAccept(Collections.singletonList(MediaType.parseMediaType("application/zip;charset=UTF-8")));
        // headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        // headers.setAccept(Collections.singletonList(MediaType.APPLICATION_OCTET_STREAM));

        Resource response = restTemplate.exchange(
                        apiUrl + "/doc/get-zip/" + request.getId(),
                        HttpMethod.GET,
                        new HttpEntity<>(null, headers),
                        Resource.class)
                .getBody();

        return (response != null) ? IOUtils.toByteArray(response.getInputStream()) : null;
    }

還將ResourceHttpMessageConverter添加到 restTemplate 到兩個微服務的配置中:

        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
        converter.setObjectMapper(objectMapper);

        ResourceHttpMessageConverter resourceConverter = new ResourceHttpMessageConverter();
        resourceConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));

        return builder.interceptors(...)
                .messageConverters(resourceConverter, converter)
                .configure(restTemplate);

沒有它們,我會得到一個如下所示的錯誤:

{"method":"POST","exceptionName":"RestClientException","detail":"Error while extracting response for type [interface org.springframework.core.io.Resource] and content type [application/octet-stream]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Invalid UTF-8 middle byte 0x59; nested exception is com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 middle byte 0x59\n at [Source: (ByteArrayInputStream); line: 1, column: 13]"}

或者

{"method":"POST","exceptionName":"RestClientException","detail":"Error while extracting response for type [interface org.springframework.core.io.Resource] and content type [application/zip;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Invalid UTF-8 start byte 0x91; nested exception is com.fasterxml.jackson.core.JsonParseException: Invalid UTF-8 start byte 0x91\n at [Source: (ByteArrayInputStream); line: 1, column: 12]"}

取決於 contentType(分別為 application/octet-stream 和 application/zip(application/zip;charset=UTF-8))。

添加ResourceHttpMessageConverter后,它現在給了我

{"method":"POST","exceptionName":"RestClientException","detail":"Error while extracting response for type [interface org.springframework.core.io.Resource] and content type [application/octet-stream]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'PK\u0003..': was expecting ('true', 'false' or 'null'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'PK\u0003...': was expecting ('true', 'false' or 'null')\n at [Source: (ByteArrayInputStream); line: 1, column: 28]"}

也許我用錯了什么? 任何意見,將不勝感激。 先感謝您

最終將字節數組編碼為 base64 字符串,然后將其發送為

return ResponseEntity.ok().body(Base64Utils.encodeToString(baos.toByteArray()));

然后在我的接收微服務中,我將以下內容添加到我的 restTemplate 配置中:

// idk if it's need to put StringHttpMessageConverter first in the list, but I did it just in case
List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new MappingJackson2HttpMessageConverter());
restTemplate.setMessageConverters(messageConverters);

它奏效了!

不知道是否正確,但也許有人會覺得有幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM