2014-03-27 23 views
1

我需要从MongoDB GridFS系统获取图像,然后将其显示在JSP img标记中。 这是我的代码,心不是工作:来自MongoDB的jsp中的春天显示图像

@RequestMapping(value = "/getPhoto", method = RequestMethod.GET) 
public @ResponseBody 
void getPhoto(HttpServletRequest request, 
     HttpServletResponse response) { 
    try { 
    System.out.println("getting photo..."); 
    GridFSDBFile imageForOutput = userFacade.loadProfilePhoto((User) SecurityContextHolder.getContext().getAuthentication() 
      .getPrincipal()); 
    BufferedImage image = ImageIO.read(imageForOutput.getInputStream()); 
    byte[] imageBytes = ((DataBufferByte) image.getData().getDataBuffer()).getData(); 
    response.setHeader("expires", "0"); 
    response.setContentType("image/jpg"); 
    response.setContentLength(imageBytes.length); 
    OutputStream out = response.getOutputStream(); 
    out.write(imageBytes, 0, imageBytes.length); 
    out.flush(); 
    out.close(); 
    return; 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 
    } 

首先我得到的GridFSDBFile,然后我需要得到的byte []之后,我把它写在响应对象,但我不知道如果我这样做。正确。

在JSP中的代码如下:

<c:url var="getPhoto" value="/settingsAdmin/getPhoto" /> 
<div id="preview"> 
    <img id="imagePreview" src="${getPhoto}" alt="Profile Photo"/> 
</div> 

最后,控制器被正确调用,但这个错误必须在它里面。

THX提前

+0

这里的方法不是很好。你应该**不要**在你的标记中嵌入图像数据。您**应该**使用控制器端点来模拟文件。一般的方法显示[这里](http://stackoverflow.com/a/22400508/2313887) –

+0

不知道太多关于JSP。错误究竟是什么?你看不到图像或什么?如果要将图像数据嵌入到标记中,请使用[示例](http://stackoverflow.com/questions/1207190/embedding-base64-images)。但绝对不是一个好主意。 – yaoxing

+0

问题是img没有显示在视图中,是否有从GridfsDbFile中获取Base64字符串以便至少在视图中显示它,它是我第一次这样做 – guille209

回答

1

最后我达到了自己的解决方案,我将它张贴,以便其他人可以解决这个问题:

控制器部

@RequestMapping(value = "/getPhoto", method = RequestMethod.GET) 
public @ResponseBody 
void getPhoto(HttpServletRequest request, 
     HttpServletResponse response) { 
    try { 
      GridFSDBFile imageForOutput = userFacade.loadProfilePhoto((User) SecurityContextHolder.getContext().getAuthentication() 
        .getPrincipal()); 
      InputStream is = imageForOutput.getInputStream(); 
      ByteArrayOutputStream buffer = new ByteArrayOutputStream(); 
      int nRead; 
      byte[] data = new byte[16384]; 
      while ((nRead = is.read(data, 0, data.length)) != -1) { 
       buffer.write(data, 0, nRead); 
      } 
      buffer.flush(); 
      byte[]imagenEnBytes = buffer.toByteArray(); 


      response.setHeader("Accept-ranges","bytes"); 
      response.setContentType("image/jpeg"); 
      response.setContentLength(imagenEnBytes.length); 
      response.setHeader("Expires","0"); 
      response.setHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0"); 
      response.setHeader("Content-Description","File Transfer"); 
      response.setHeader("Content-Transfer-Encoding:","binary"); 

      OutputStream out = response.getOutputStream(); 
      out.write(imagenEnBytes); 
      out.flush(); 
      out.close(); 
    } catch (Exception e) { 
     // TODO Auto-generated catch block 

    } 

} 

的JSP视图

<c:url var="getPhoto" value="/settingsAdmin/getPhoto" /> 
<div id="preview"> 
    <img id="imagePreview" src="${getPhoto}"alt="Profile Photo"/> 
</div> 

谢谢大家你的帮助

0

试试这个,

@Controller 
public class GetImageController { 

    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB. 

    @Autowired 
    ServletContext servletContext; 

    @RequestMapping(value="/getImage", method=RequestMethod.GET) 
    public void getPhoto(HttpServletRequest request, 
      HttpServletResponse response) { 
     try { 
     System.out.println("getting photo..."); 

     File image = new File("E:\\path\\to\\image.jpg"); 
     System.out.println("file exists: "+image.exists()); 
     // Get content type by filename. 
     String contentType = servletContext.getMimeType(image.getName()); 

     // Init servlet response. 
     response.reset(); 
     response.setBufferSize(DEFAULT_BUFFER_SIZE); 
     response.setContentType(contentType); 
     response.setHeader("Content-Length", String.valueOf(image.length())); 
     response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\""); 

     // Prepare streams. 
     BufferedInputStream input = null; 
     BufferedOutputStream output = null; 

     try { 
      // Open streams. 
      input = new BufferedInputStream(new FileInputStream(image), DEFAULT_BUFFER_SIZE); 
      output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE); 

      // Write file contents to response. 
      byte[] buffer = new byte[DEFAULT_BUFFER_SIZE]; 
      int length; 
      while ((length = input.read(buffer)) > 0) { 
       output.write(buffer, 0, length); 
      } 
     } finally { 
      // Gently close streams. 
      close(output); 
      close(input); 
     } 
     // Check if file is actually an image (avoid download of other files by hackers!). 
     // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp 
     if (contentType == null || !contentType.startsWith("image")) { 
      // Do your thing if the file appears not being a real image. 
      // Throw an exception, or send 404, or show default/warning image, or just ignore it. 
      response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404. 
      return; 
     } 

    } 

    // Helpers (can be refactored to public utility class) ---------------------------------------- 

    private static void close(Closeable resource) { 
     if (resource != null) { 
      try { 
       resource.close(); 
      } catch (IOException e) { 
       // Do your thing with the exception. Print it, log it or mail it. 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

,并在JSP渲染样图像:

<c:url value="/getImage" var="imgUrl"/> 
<img alt="my image" src="${imgUrl}"> //to display on browser 
<a href="${imgUrl}">img</a> //to display in new window 

注:这是不是显示Spring MVC中的图像更好的办法,但在Servlets中


另一种方式是(两行代码):

回报直接byte[]并指定produces = MediaType.IMAGE_JPEG_VALUE@RequestMapping ,如:

@RequestMapping(value="/getImage", method=RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) 
    public @ResponseBody byte[] getPhoto() throws IOException { 
     System.out.println("getting photo..."); 

     FileInputStream image = new FileInputStream(new File("E:\\path\\to\\image.jpg")); 
     return IOUtils.toByteArray(image);   
    } 

两种方式的是为我工作得很好。