Spring Boot 컨트롤러에서 이미지를 반환하고 파일 시스템처럼 사용하는 방법
스택 오버플로우에서 제공하는 다양한 방법을 시도해 보았는데, 뭔가를 놓친 것 같습니다.
현재 다음과 같은 이미지가 표시되는 Android 클라이언트(코드를 변경할 수 없음)가 있습니다.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
어디에url
이미지의 위치(CDN의 정적 리소스)입니다.이제 내 Spring Boot API Endpoint는 동일한 코드가 API(Spring boot version 1.3.3)에서 이미지를 가져올 수 있도록 동일한 방식으로 파일 리소스처럼 동작해야 합니다.
그래서 나는 이것을 가지고 있습니다.
@ResponseBody
@RequestMapping(value = "/Image/{id:.+}", method = RequestMethod.GET, consumes = MediaType.ALL_VALUE, produces = MediaType.IMAGE_JPEG_VALUE)
public ResponseEntity<byte[]> getImage(@PathVariable("id")String id) {
byte[] image = imageService.getImage(id); //this just gets the data from a database
return ResponseEntity.ok(image);
}
Android 코드가 다음을 시도할 때http://someurl/image1.jpg
로그에 다음과 같은 오류가 발생합니다.
처리기 [public organ.springframework.http]의 예외를 해결하는 중입니다.ResponseEntity com. my project.MyController.getImage(java.lang).String)]: org.springframework.web.HttpMediaType 허용 안 됨예외:허용 가능한 표현을 찾을 수 없습니다.
플러그를 꽂을 때도 동일한 오류가 발생합니다.http://someurl/image1.jpg
브라우저로 이동합니다.
이상하게도 내 시험은 확인할 수 있습니다.
Response response = given()
.pathParam("id", "image1.jpg")
.when()
.get("MyController/Image/{id}");
assertEquals(HttpStatus.OK.value(), response.getStatusCode());
byte[] array = response.asByteArray(); //byte array is identical to test image
일반적인 방식으로 이미지가 제공되는 것처럼 동작하도록 하려면 어떻게 해야 합니까? (안드로이드 코드가 보내는 내용 유형 헤더는 변경할 수 없습니다)
편집
코멘트 뒤 코드(내용유형설정, 테이크아웃)produces
):
@RequestMapping(value = "/Image/{id:.+}", method = RequestMethod.GET, consumes = MediaType.ALL_VALUE)
public ResponseEntity<byte[]> getImage(@PathVariable("id")String id, HttpServletResponse response) {
byte[] image = imageService.getImage(id); //this just gets the data from a database
response.setContentType(MediaType.IMAGE_JPEG_VALUE);
return ResponseEntity.ok(image);
}
브라우저에서 이것은 문자열화된 정크를 제공하는 것처럼 보입니다.안드로이드에서는 에러가 나지 않지만 이미지가 나타나지 않습니다.
저는 이것이 효과가 있을 거라 믿습니다.
@RequestMapping(value = "/Image/{id:.+}", method = RequestMethod.GET)
public ResponseEntity<byte[]> getImage(@PathVariable("id") String id) {
byte[] image = imageService.getImage(id);
return ResponseEntity.ok().contentType(MediaType.IMAGE_JPEG).body(image);
}
컨텐츠 유형이 다음에 대해 설정되어 있음을 유의하십시오.ResponseEntity
, 을 위한 것이 아닌HttpServletResponse
직접적으로.
드디어 이걸 고쳤네요...나는 추가해야 했습니다.ByteArrayHttpMessageConverter
나에게WebMvcConfigurerAdapter
하위 클래스:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
final ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
final List<MediaType> list = new ArrayList<>();
list.add(MediaType.IMAGE_JPEG);
list.add(MediaType.APPLICATION_OCTET_STREAM);
arrayHttpMessageConverter.setSupportedMediaTypes(list);
converters.add(arrayHttpMessageConverter);
super.configureMessageConverters(converters);
}
파일/마임 유형을 모르는 경우 이 작업을 수행할 수 있습니다.업로드된 파일을 가져다가 guid로 파일 이름을 바꾸고 확장자가 없으며 브라우저/스마트폰이 이미지를 로드할 수 있는 문제가 없는 경우에 이 작업을 수행했습니다.두번째는 다운로드 받을 파일을 제공하는 것입니다.
@RestController
@RequestMapping("img")
public class ImageController {
@GetMapping("showme")
public ResponseEntity<byte[]> getImage() throws IOException{
File img = new File("src/main/resources/static/test.jpg");
return ResponseEntity.ok().contentType(MediaType.valueOf(FileTypeMap.getDefaultFileTypeMap().getContentType(img))).body(Files.readAllBytes(img.toPath()));
}
@GetMapping("thing")
public ResponseEntity<byte[]> what() throws IOException{
File file = new File("src/main/resources/static/thing.pdf");
return ResponseEntity.ok()
.header("Content-Disposition", "attachment; filename=" +file.getName())
.contentType(MediaType.valueOf(FileTypeMap.getDefaultFileTypeMap().getContentType(file)))
.body(Files.readAllBytes(file.toPath()));
}
}
추가해야 하는 java 9+ 업데이트compile 'com.sun.activation:javax.activation:1.2.0'
이것 또한 jakarta에 의해 옮겨졌거나 픽업되었습니다. 이 게시물을 보세요.
Apache Commons(아파치 커먼즈)를 사용하여 엔드포인트에서 이미지를 노출할 수 있습니다.
@RequestMapping(value = "/image/{imageid}",method= RequestMethod.GET,produces = MediaType.IMAGE_JPEG_VALUE)
public @ResponseBody byte[] getImageWithMediaType(@PathVariable int imageid) throws IOException {
InputStream in = new ByteArrayInputStream(getImage(imageid));
return IOUtils.toByteArray(in);
}
모든 이미지가 엔드포인트에서 제공됩니다./image/{imageid}
언급URL : https://stackoverflow.com/questions/40557637/how-to-return-an-image-in-spring-boot-controller-and-serve-like-a-file-system
'programing' 카테고리의 다른 글
C에서 EOF 검출 (0) | 2023.10.30 |
---|---|
UpdatePanel의 ListView의 LinkButton으로 인해 전체 포스트백 발생 (0) | 2023.10.30 |
목표-C에서 NSDate를 현재 UTC로 설정 (0) | 2023.10.30 |
트리거(ORA-39083, ORA-00942)와 관련된 Oracle IMPDP REMAP_SCHMA 문제에 대한 좋은 해결 방법이 있습니까? (0) | 2023.10.30 |
익명 블록 안에 선택 결과 표시 (0) | 2023.10.30 |