【问题标题】:Spring display image in jsp from MongoDB来自MongoDB的jsp中的Spring显示图像
【发布时间】:2014-04-03 20:35:25
【问题描述】:

我需要从 MongoDB GridFS 系统获取图像,然后将其显示在 JSP img 标记中。 这是我的代码不起作用:

@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>

最后,控制器被正确调用,但错误一定在里面。

提前谢谢

【问题讨论】:

  • 这里的方法不是很好。您应该在标记中嵌入图像数据。您应该使用控制器端点来模拟文件。一般做法如图here
  • 对JSP不太了解。究竟是什么错误?你看不到图像还是什么?如果您想将图像数据嵌入到 标记中,这里是一个example。不过,这绝对不是一个好主意。
  • 问题是img没有显示在视图中,无论如何要从GridfsDbFile中获取Base64字符串以便至少在视图中显示它,这是我第一次这样做
  • 这是如何内联的?我认为要内联,您必须将src 属性设置为“数据:”。他所做的只是调用一个 Spring 控制器,该控制器返回一个与从驱动器读取图像相同的二进制文件。
  • 那么,这是正确的方法吗?因为我认为这样它也不起作用 out.write(Base64.encode(imageBytes),0,Base64.encode(imageBytes).length);

标签: mongodb jsp spring-mvc servlets gridfs


【解决方案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>

感谢大家的帮助

【讨论】:

    【解决方案2】:

    试试这个,

    @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[]并在@RequestMapping中指定produces = MediaType.IMAGE_JPEG_VALUE 喜欢:

    @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);        
        }
    

    两种方式都适合我。

    【讨论】:

      猜你喜欢
      • 2016-04-27
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-24
      相关资源
      最近更新 更多