【问题标题】:Spring MVC: How to return an image from controller?Spring MVC:如何从控制器返回图像?
【发布时间】:2016-02-29 13:16:38
【问题描述】:

我正在尝试返回这样的图像。

 @RequestMapping(value = "admin/image/{userId}")
public ResponseEntity<byte[]> getPhoto(@PathVariable int userId) throws IOException {
    UserDB userDB = UserDBService.getUserWithId(userId);
    if (userDB != null) {
        try {
            byte[] image;
            try {
                String path = ApplicationPropertiesConstants.SAFESITE_DOCUMENTS_DIRECTORY + userDB.getSite().getId() + "\\342.png";
                InputStream is = new FileInputStream(path);
                BufferedImage img = ImageIO.read(is);
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ImageIO.write(img, "png", bos);
                final HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.IMAGE_PNG);

                return new ResponseEntity<byte[]>(IOUtils.toByteArray(is), headers, HttpStatus.CREATED);
            } catch (FileNotFoundException e) {
                image = org.apache.commons.io.FileUtils.readFileToByteArray(new File("dfd"));
            }

            return null;
        } catch (IOException ignored) {
        }
    }
    return null;
}

虽然当我访问 url 时图像不显示。

知道为什么会这样吗?我需要使用 Apache Tiles 吗?目前我正在使用 jstlView。

<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

【问题讨论】:

  • 你得到什么回应?
  • 响应数据加载失败
  • 如果你有一个InputStream,你可以返回一个ResponseEntity&lt;Resource&gt;,正文是new InputStreamResource(inputStream)
  • 如果你使用byte[]你应该设置内容长度标题。正确的状态是HttpStatus.OK btw。
  • 我不知道你所说的 body 是 new InputStreamResource(inputStream) 是什么意思

标签: spring spring-mvc


【解决方案1】:

}

response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment;filename=EDC-"+ title + ".txt");
ServletOutputStream out = response.getOutputStream();
out.print(myString.trim());
out.flush();
out.close();

【讨论】:

  • 请添加一些细节和解释,以便对其他人有所帮助
【解决方案2】:

获取您的图像文件并将其写入响应。

@RequestMapping(value = "/getImage", method = RequestMethod.GET)
  public void showImage(HttpServletResponse response) throws Exception {

    ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();

    try {
      BufferedImage image = //CALL_OR_CREATE_YOUR_IMAGE_OBJECT;
      ImageIO.write(image, "jpeg", jpegOutputStream);
    } catch (IllegalArgumentException e) {
      response.sendError(HttpServletResponse.SC_NOT_FOUND);
    }

    byte[] imgByte = jpegOutputStream.toByteArray();

    response.setHeader("Cache-Control", "no-store");
    response.setHeader("Pragma", "no-cache");
    response.setDateHeader("Expires", 0);
    response.setContentType("image/jpeg");
    ServletOutputStream responseOutputStream = response.getOutputStream();
    responseOutputStream.write(imgByte);
    responseOutputStream.flush();
    responseOutputStream.close();
  }

【讨论】:

  • 好的,谢谢。如果我知道想要做同样的事情,但会返回任何类型的文件(作为下载链接),我该怎么做?
  • 要返回任何文件,如图像、pdf 或下载链接,您必须设置标题。例如:下载链接 String mimeType = "application/octet-stream"; response.setContentType(mimeType); response.setHeader("Content-Disposition", String.format("inline; filename=\"" + file.getName() +"\""));
  • PDF 链接 response.setContentType("application/pdf"); response.setHeader("content-disposition", "inline;filename=" + "form.pdf");
【解决方案3】:

这样不行,你需要类似的东西

@RequestMapping(...)
void getImage(...) {
  response.setContentType(mimeType);
  response.setHeader("Content-Disposition", String.format("inline; filename=\"" + file.getName() +"\""));
  response.setContentLength((int)file.length());
  InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
  FileCopyUtils.copy(inputStream, response.getOutputStream());
}

【讨论】: