Spring MVC : @ResponseBody에서 이미지를 반환하는 방법은 무엇입니까?
byte[]
DB에서 이미지 데이터 ( )를 가져옵니다. 이 이미지를 어떻게 반환 @ResponseBody
합니까?
편집하다
메소드 매개 변수로 @ResponseBody
사용 하지 않고 수행했습니다 HttpServletResponse
.
@RequestMapping("/photo1")
public void photo(HttpServletResponse response) throws IOException {
response.setContentType("image/jpeg");
InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
IOUtils.copy(in, response.getOutputStream());
}
@Sid @ResponseBody
가 등록 된 org.springframework.http.converter.ByteArrayHttpMessageConverter
변환기 와 함께 사용하면 작동하지 않습니다 :(.
@ResponseBody
@RequestMapping("/photo2")
public byte[] testphoto() throws IOException {
InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
return IOUtils.toByteArray(in);
}
3.1 이상의 Spring 버전을 사용하는 경우 @RequestMapping
주석에 "produces"를 지정할 수 있습니다 . 아래 예제는 즉시 사용할 수 있습니다. web mvc를 사용하도록 설정 한 경우 레지스터 변환기 또는 다른 항목이 필요하지 않습니다 ( @EnableWebMvc
).
@ResponseBody
@RequestMapping(value = "/photo2", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public byte[] testphoto() throws IOException {
InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
return IOUtils.toByteArray(in);
}
Spring 4.1 이상을 사용하면 추가 종속성없이 거의 모든 것을 (예 : 그림, pdf, 문서, 항아리, 우편 번호 등) 반환 할 수 있습니다. 예를 들어 다음은 MongoDB GridFS에서 사용자의 프로필 사진을 반환하는 방법 일 수 있습니다.
@RequestMapping(value = "user/avatar/{userId}", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity<InputStreamResource> downloadUserAvatarImage(@PathVariable Long userId) {
GridFSDBFile gridFsFile = fileService.findUserAccountAvatarById(userId);
return ResponseEntity.ok()
.contentLength(gridFsFile.getLength())
.contentType(MediaType.parseMediaType(gridFsFile.getContentType()))
.body(new InputStreamResource(gridFsFile.getInputStream()));
}
참고 사항 :
InputStreamResource를 리턴 유형으로하는 ResponseEntity
ResponseEntity 빌더 스타일 작성
이 방법을 사용하면 HttpServletResponse의 자동 배선, IOException 발생 또는 스트림 데이터 복사에 대해 걱정할 필요가 없습니다.
을 등록하는 ByteArrayHttpMessageConverter
것 외에도을 (를) ResponseEntity
대신 사용할 수 있습니다 @ResponseBody
. 다음 코드는 저에게 효과적입니다.
@RequestMapping("/photo2")
public ResponseEntity<byte[]> testphoto() throws IOException {
InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, HttpStatus.CREATED);
}
Spring 3.1.x 및 3.2.x를 사용하면 다음과 같이해야합니다.
컨트롤러 방법 :
@RequestMapping("/photo2")
public @ResponseBody byte[] testphoto() throws IOException {
InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
return IOUtils.toByteArray(in);
}
servlet-context.xml 파일의 mvc 주석 :
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>image/jpeg</value>
<value>image/png</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
여기에 몇 가지 대답 외에도 몇 가지 지침 (Spring 4.1)이 있습니다.
당신이 가진, 당신의 WebMvcConfig에 구성된 모든 messageconverters이없는 못했을 경우에 대비 ResponseEntity
하여 내부에서 @ResponseBody
잘 작동합니다.
당신이하는 경우, 즉 당신은 반환을 MappingJackson2HttpMessageConverter
사용하여 (나와 같이) 구성 ResponseEntity
했습니다 org.springframework.http.converter.HttpMessageNotWritableException
.
이 경우 작동하는 유일한 해결책은 다음과 같이 포장하는 것 byte[]
입니다 @ResponseBody
.
@RequestMapping(value = "/get/image/{id}", method=RequestMethod.GET, produces = MediaType.IMAGE_PNG_VALUE)
public @ResponseBody byte[] showImageOnId(@PathVariable("id") String id) {
byte[] b = whatEverMethodUsedToObtainBytes(id);
return b;
}
이 경우 다음 ByteArrayHttpMessageConverer
과 같이 WebMvcConfig에서 메시지 변환기를 올바르게 구성하고를 추가 하십시오.
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(mappingJackson2HttpMessageConverter());
converters.add(byteArrayHttpMessageConverter());
}
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(objectMapper);
return converter;
}
@Bean
public ByteArrayHttpMessageConverter byteArrayHttpMessageConverter() {
ByteArrayHttpMessageConverter arrayHttpMessageConverter = new ByteArrayHttpMessageConverter();
arrayHttpMessageConverter.setSupportedMediaTypes(getSupportedMediaTypes());
return arrayHttpMessageConverter;
}
private List<MediaType> getSupportedMediaTypes() {
List<MediaType> list = new ArrayList<MediaType>();
list.add(MediaType.IMAGE_JPEG);
list.add(MediaType.IMAGE_PNG);
list.add(MediaType.APPLICATION_OCTET_STREAM);
return list;
}
응용 프로그램 컨텍스트에서 AnnotationMethodHandlerAdapter 및 registerByteArrayHttpMessageConverter를 선언하십시오.
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<util:list>
<bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
</util:list>
</property>
</bean>
또한 핸들러 메소드에서 응답에 적합한 컨텐츠 유형을 설정하십시오.
@RequestMapping(value = "/get-image",method = RequestMethod.GET)
public ResponseEntity<byte[]> getImage() throws IOException {
RandomAccessFile f = new RandomAccessFile("/home/vivex/apache-tomcat-7.0.59/tmpFiles/1.jpg", "r");
byte[] b = new byte[(int)f.length()];
f.readFully(b);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
return new ResponseEntity<byte[]>(b, headers, HttpStatus.CREATED);
}
나를 위해 일했다.
나는 이것을 선호한다 :
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@ResponseBody
@RequestMapping(value = "/{id}", produces = "image/bmp")
public Resource texture(@PathVariable("id") String id) {
return resourceLoader.getResource("classpath:images/" + id + ".bmp");
}
미디어 유형을 현재 이미지 형식으로 변경하십시오.
그것은 봄 4에서 나를 위해 일하고 있습니다.
@RequestMapping(value = "/image/{id}", method = RequestMethod.GET)
public void findImage(@PathVariable("id") String id, HttpServletResponse resp){
final Foto anafoto = <find object>
resp.reset();
resp.setContentType(MediaType.IMAGE_JPEG_VALUE);
resp.setContentLength(anafoto.getImage().length);
final BufferedInputStream in = new BufferedInputStream(new ByteArrayInputStream(anafoto.getImageInBytes()));
try {
FileCopyUtils.copy(in, resp.getOutputStream());
resp.flushBuffer();
} catch (final IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
대답 중 하나가 저에게 효과적이지 않으므로 다음과 같이 처리했습니다.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("your content type here"));
headers.set("Content-Disposition", "attachment; filename=fileName.jpg");
headers.setContentLength(fileContent.length);
return new ResponseEntity<>(fileContent, headers, HttpStatus.OK);
Content-Disposition
헤더 설정 @ResponseBody
방법에 주석이 달린 파일을 다운로드 할 수있었습니다 .
이것이 Spring Boot와 Guava에서 수행하는 방법입니다.
@RequestMapping(value = "/getimage", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public void getImage( HttpServletResponse response ) throws IOException
{
ByteStreams.copy( getClass().getResourceAsStream( "/preview-image.jpg" ), response.getOutputStream() );
}
You should specify the media type in the response. I'm using a @GetMapping annotation with produces = MediaType.IMAGE_JPEG_VALUE. @RequestMapping will work the same.
@GetMapping(value="/current/chart",produces = MediaType.IMAGE_JPEG_VALUE)
@ResponseBody
public byte[] getChart() {
return ...;
}
Without a media type, it is hard to guess what is actually returned (includes anybody who reads the code, browser and of course Spring itself). A byte[] is just not specific. The only way to determine the media type from a byte[] is sniffing and guessing around.
Providing a media type is just best practice
In spring 4 it's very easy you don't need to make any changes in beans. Only mark your return type to @ResponseBody.
Example:-
@RequestMapping(value = "/image/{id}")
public @ResponseBody
byte[] showImage(@PathVariable Integer id) {
byte[] b;
/* Do your logic and return
*/
return b;
}
I think you maybe need a service to store file upload and get that file. Check more detail from here
1) Create a Storage Sevice
@Service
public class StorageService {
Logger log = LoggerFactory.getLogger(this.getClass().getName());
private final Path rootLocation = Paths.get("upload-dir");
public void store(MultipartFile file) {
try {
Files.copy(file.getInputStream(), this.rootLocation.resolve(file.getOriginalFilename()));
} catch (Exception e) {
throw new RuntimeException("FAIL!");
}
}
public Resource loadFile(String filename) {
try {
Path file = rootLocation.resolve(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
} else {
throw new RuntimeException("FAIL!");
}
} catch (MalformedURLException e) {
throw new RuntimeException("FAIL!");
}
}
public void deleteAll() {
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}
public void init() {
try {
Files.createDirectory(rootLocation);
} catch (IOException e) {
throw new RuntimeException("Could not initialize storage!");
}
}
}
2) Create Rest Controller to upload and get file
@Controller
public class UploadController {
@Autowired
StorageService storageService;
List<String> files = new ArrayList<String>();
@PostMapping("/post")
public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
String message = "";
try {
storageService.store(file);
files.add(file.getOriginalFilename());
message = "You successfully uploaded " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.OK).body(message);
} catch (Exception e) {
message = "FAIL to upload " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
}
}
@GetMapping("/getallfiles")
public ResponseEntity<List<String>> getListFiles(Model model) {
List<String> fileNames = files
.stream().map(fileName -> MvcUriComponentsBuilder
.fromMethodName(UploadController.class, "getFile", fileName).build().toString())
.collect(Collectors.toList());
return ResponseEntity.ok().body(fileNames);
}
@GetMapping("/files/{filename:.+}")
@ResponseBody
public ResponseEntity<Resource> getFile(@PathVariable String filename) {
Resource file = storageService.loadFile(filename);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"")
.body(file);
}
}
참고URL : https://stackoverflow.com/questions/5690228/spring-mvc-how-to-return-image-in-responsebody
'Programing' 카테고리의 다른 글
C # 스위치 명령문 제한-왜? (0) | 2020.06.24 |
---|---|
포스트 백이란 무엇입니까? (0) | 2020.06.24 |
시프트 연산자는 Java에서 어떻게 작동합니까? (0) | 2020.06.24 |
Python에서 JSON을 직렬화 할 때 "TypeError : (정수)를 JSON 직렬화 할 수 없습니다"? (0) | 2020.06.24 |
rm이 파일을 찾지 못했다고보고하지 못하게하는 방법은 무엇입니까? (0) | 2020.06.24 |