티스토리 뷰

728x90

에러스택

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.example.demo.controller.ResourceController$$Lambda$821/0x000000011a429db0] with preset Content-Type 'application/octet-stream']

환경

  • spring boot 2.4.x

외부 파일을 다운로드 하는 Controller에서 에러 발생
문제가 된 코드

@RestController
public class ResourceController {

    @GetMapping("/resource")
    public ResponseEntity<?> resource() throws IOException {


        final ClassPathResource classPathResource = new ClassPathResource("test.json.gz");
        final File file = classPathResource.getFile();

        final StreamingResponseBody streamingResponseBody = outputStream -> {
            try (final InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
                FileCopyUtils.copy(inputStream, outputStream);
            }
        };

        final HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set(HttpHeaders.CONTENT_ENCODING, "gzip");
        httpHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getName().replace(".gz", ""));

        return ResponseEntity.ok()
                .headers(httpHeaders)
                .contentLength(file.length())
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(streamingResponseBody);

    }
}

 

큰 용량 파일을 다운로드받기위해서 StreamingResponseBody를 람다로 그대로 리턴했는데 안된다.

 

스프링 Contributor의 답변을 보면

ResponseEntity의 응답이 wildcard로 되어있고 응답본문이 람다이고 해당 유형을 확인할 수 없어서 오류가 난다고 한다.

 

해결방법

응답을 와일드카드로 주지말고 실제 타입을 명시해주자.

 @GetMapping("/resource2")
 public ResponseEntity<StreamingResponseBody> resourceType() throws IOException {


    final ClassPathResource classPathResource = new ClassPathResource("test.json.gz");
    final File file = classPathResource.getFile();

 	final StreamingResponseBody streamingResponseBody = outputStream -> {
        try (final InputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
            FileCopyUtils.copy(inputStream, outputStream);
        }
    };

    final HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.set(HttpHeaders.CONTENT_ENCODING, "gzip");
    httpHeaders.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + file.getName().replace(".gz", ""));

    return ResponseEntity.ok()
            .headers(httpHeaders)
            .contentLength(file.length())
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(streamingResponseBody);

}

 

참고

https://github.com/spring-projects/spring-framework/issues/25996

 

"No converter ..." for wildcard ResponseEntity with StreamingResponseBody as body · Issue #25996 · spring-projects/spring-fram

Affects: 2.2.4 That controller works perfectly: @GetMapping("/test") public ResponseEntity<StreamingResponseBody> test() { var response = ResponseEntity.ok().contentType(MediaType.APPLICATION_OCTET...

github.com

https://github.com/sskim91/java-spring-lab/blob/main/spring-resource-in-action/spring-resource-in-action/src/main/java/com/example/demo/controller/ResourceController.java

 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함