Я получаю данные изображения (как byte[]
) из БД. Как вернуть это изображение @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());
}
Использование @ResponseBody
с зарегистрированным org.springframework.http.converter.ByteArrayHttpMessageConverter
конвертером, как сказал @Sid, у меня не работает :(.
@ResponseBody
@RequestMapping("/photo2")
public byte[] testphoto() throws IOException {
InputStream in = servletContext.getResourceAsStream("/images/no_image.jpg");
return IOUtils.toByteArray(in);
}
источник
В дополнение к регистрации
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); }
И аннотация mvc в файле servlet-context.xml:
<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, то
ResponseEntity
внутри у вас@ResponseBody
работает хорошо.Если вы это сделаете, то есть у вас есть
MappingJackson2HttpMessageConverter
настроенный (как и я) с использованиемResponseEntity
возврата aorg.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"); }
Измените тип носителя на любой имеющийся у вас формат изображения.
источник
ResourceLoader
, но создание имени пути из внешнего ввода, как в вашем примере, - плохая идея: cwe.mitre.org/data/definitions/22.htmlДля меня это работа Spring 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
аннотацией к моему методу.источник
В ответе необходимо указать тип носителя. Я использую аннотацию @GetMapping с Produce = MediaType.IMAGE_JPEG_VALUE. @RequestMapping будет работать так же.
@GetMapping(value="/current/chart",produces = MediaType.IMAGE_JPEG_VALUE) @ResponseBody public byte[] getChart() { return ...; }
Без типа носителя трудно угадать, что на самом деле возвращается (включая любого, кто читает код, браузер и, конечно, сам Spring). Байт [] просто неконкретен. Единственный способ определить тип носителя по байту [] - это обнюхать и угадать.
Предоставление типа мультимедиа - это просто лучшая практика
источник
Вот как я это делаю с помощью 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() ); }
источник
Весной 4 это очень просто, вам не нужно вносить никаких изменений в бобы. Отметьте свой возвращаемый тип только для @ResponseBody.
Пример:-
@RequestMapping(value = "/image/{id}") public @ResponseBody byte[] showImage(@PathVariable Integer id) { byte[] b; /* Do your logic and return */ return b; }
источник
Я думаю, вам может понадобиться сервис для хранения загруженных файлов и получения этого файла. Узнайте больше здесь
1) Создайте службу хранения
@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) Создайте Rest Controller для загрузки и получения файла
@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); }
}
источник