How to properly return an image in the response in Spring app?

10,427

Solution 1

The problem is, that you have to specify the mime type (and if your image is larger you will need to specify its length too).

An other solution () is to return a Spring ResponseEntity or HttpEntity (HttpEntity is enough if you always return http status code 200, ResponseEntity (a subclass of HttpEntity) is for example needed if you want to return other http status codes, like not found).

@Controller
public class PhotoController {
    @RequestMapping("/carPhoto.html")
    @ResponseBody
    public HttpEntity<byte[]> getCarPhoto(
            @RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
            @RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {


        byte[] image = image's bytes array from db by photo Id and Type;

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.IMAGE_JPEG); //or what ever type it is
        headers.setContentLength(image.length);
        return new HttpEntity<byte[]>(image, headers);
    }
}

Solution 2

There are several ways. Easiest is to use @ResponseBody with a byte[] as your return type, set your Content-Type and such, the write the bytes to the output stream using the HttpServletResponse.

A more elegant solution (IMO) would be to return a ModelAndView, then set the View on that to a custom view that sets the proper headers (Content-Type and such) and writes out the bytes to the HttpServletResponse's output stream.


Share:
10,427
kumade
Author by

kumade

Developing software since 2002. Web developer since 2006. Working remotely in international and distributed teams since 2008. Playing video games since my childhood and having some game development experience since 2004. Responsible, inventive, always eager for new knowledge. Common-law-married to my wonderful wife, who is an experienced programmer too and a great artist.

Updated on June 04, 2022

Comments

  • kumade
    kumade almost 2 years

    I 'm using Spring 3.0.1.RELEASE for my webapp (and i have no way for upgrading it) and i'm trying to render some images from database on web-page.

    I have following simple Spring configs:

    spring-application.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:task="http://www.springframework.org/schema/task"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    
        <task:annotation-driven />
    
        <context:annotation-config />
    
        <context:spring-configured />
    
        <context:component-scan base-package="com.me" />
    
        <bean id="hibernateSessionFactory" class="com.me.dbaccess.HibernateSessionFactory">
            <constructor-arg ref="sessionFactory"/>
        </bean>
    </beans>
    

    spring-mvc.xml:

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    
        <mvc:annotation-driven/>
    
        <bean id="tilesViewResolver" class="com.me.util.TilesExposingBeansViewResolver">
            <property name="viewClass" value="com.me.util.TilesExposingBeansView"/>
            <property name="exposeContextBeansAsAttributes" value="true"/>
        </bean>
    
        <bean id="tilesConfigurer"
              class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
            <property name="definitions">
                <list>
                    <value>/WEB-INF/config/tiles-defs.xml</value>
                </list>
            </property>
        </bean>
    </beans>
    

    I have following controller:

    @Controller
    public class PhotoController {
        @RequestMapping("/carPhoto.html")
        @ResponseBody
        public byte[] getCarPhoto(
                @RequestParam(UrlParameters.PHOTO_ID) Integer photoId,
                @RequestParam(UrlParameters.PHOTO_TYPE) String photoType) {
            //return image's bytes array from db by photo Id and Type;
        }
    }
    

    And finally, I have simple jsp-page:

    <%@page contentType="text/html; charset=utf-8"%>
    <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <img id="photoImage" src="<c:url value="/carPhoto.html?photoType=1&photoId=22556793"/>" />
    

    If I open this page - I can see this image without any problems.

    But if I copy image "src" attribute and paste it in browser's address bar (Firefox 19.0.2) - then browser offers me to save carPhoto.html, instead of just render the image. Should I perform some additional setup?