Question

I need to get an image from MongoDB GridFS system, then displaying it in a JSP img tag. This is my code that isnt working:

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

Firstly i get the GridFSDBFile and then I need to get the byte[].After that i write it in the response object but i dont know if i am doing it correctly.

The code in the JSP is as follows:

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

Finally, the controller is called correctly but the mistake must be inside it.

Thx in advance

Was it helpful?

Solution

Finally i reached a solution by myself, i post it so others can work it out:

The Controller part

@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

    }

}

The JSP view

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

Thank you everyone for your help

OTHER TIPS

try this,

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

and in jsp render image like:

<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

Note: This is not better way to display images in spring MVC, But in Servlets


Other way is(two lines of code):

return direct byte[] and specify produces = MediaType.IMAGE_JPEG_VALUE in @RequestMapping like:

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

Both way's are worked fine for me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top