Spring Framework
"No converter ..." for wildcard ResponseEntity with StreamingResponseBody as body"
터프남
2024. 3. 3. 18:46
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
728x90
반응형