Serving image file in Spring Boot

In this tutorial, we show how to serve an image file in Spring Boot RESTful web application. The image is a JPEG file located in the resources directory.

Spring is a Java application framework for developing Java enterprise applications. It also helps integrate various enterprise components. Spring Boot makes it easy to create Spring-powered, production-grade applications and services with minimum setup requirements.

We are going to show three ways to send image data to the client.

Application

The web application contains a sid.jpg file in the src/main/resources/image directory. ClassPathResource is used to get hold of the image file.

$ tree
.
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── zetcode
    │   │           ├── Application.java
    │   │           └── controller
    │   │               └── MyController.java
    │   └── resources
    │       └── image
    │           └── sid.jpg
    └── test
        └── java

This is the project structure.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.zetcode</groupId>
    <artifactId>SpringBootServeImage</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
    </parent>    
    
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>              
       
    </dependencies>    

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>            
        </plugins>
    </build>    
</project>

This is the Maven build file. Spring Boot starters are a set of useful dependency descriptors which greatly simplify Maven configuration. The spring-boot-starter-parent has some common configurations for a Spring Boot application. The spring-boot-starter-web is a starter for building web applications with Spring MVC. It uses Tomcat as the default embedded server. The spring-boot-maven-plugin provides Spring Boot support in Maven, allowing us to package executable JAR or WAR archives. Its spring-boot:run goal executes the Spring Boot application.

Application.java
package com.zetcode;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

The Application sets up the Spring Boot application. @SpringBootApplication enables component scanning and autoconfiguration.

Using HttpServletResponse

In the first case, we directly write to the HttpServletResponse.

MyController.java
package com.zetcode.controller;

import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public void getImage(HttpServletResponse response) throws IOException {

        ClassPathResource imgFile = new ClassPathResource("image/sid.jpg");

        response.setContentType(MediaType.IMAGE_JPEG_VALUE);
        StreamUtils.copy(imgFile.getInputStream(), response.getOutputStream());
    }
}

In this controller, we get the image resource and write it directly to the response object.

ClassPathResource imgFile = new ClassPathResource("image/sid.jpg");

We get the image resource from the classpath (src/main/resources directory is in the Java classpath) with the ClassPathResource.

response.setContentType(MediaType.IMAGE_JPEG_VALUE);

The content type of the response is set to the MediaType.IMAGE_JPEG_VALUE.

StreamUtils.copy(imgFile.getInputStream(), response.getOutputStream());

With StreamUtils we copy the data from the image to the response object.

Using ResponseEntity

In the second case, we use ResponseEntity.

MyController.java
package com.zetcode.controller;

import java.io.IOException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public ResponseEntity<byte[]> getImage() throws IOException {

        ClassPathResource imgFile = new ClassPathResource("image/sid.jpg");
        byte[] bytes = StreamUtils.copyToByteArray(imgFile.getInputStream());

        return ResponseEntity
                .ok()
                .contentType(MediaType.IMAGE_JPEG)
                .body(bytes);
    }
}

The getImage() method return type is set to ResponseEntity<byte[]>.

byte[] bytes = StreamUtils.copyToByteArray(imgFile.getInputStream());

With the StreamUtils.copyToByteArray() we copy the image data into a byte array.

return ResponseEntity
        .ok()
        .contentType(MediaType.IMAGE_JPEG)
        .body(bytes);

The byte array is given to the body of the ResponseEntity.

Using ResponseEntity and InputStreamResource

In the third case, we use ResponseEntity and InputStreamResource. InputStreamResource is Spring's abstraction of low-level resources.

MyController.java
package com.zetcode.controller;

import java.io.IOException;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public ResponseEntity<InputStreamResource> getImage() throws IOException {

        ClassPathResource imgFile = new ClassPathResource("image/sid.jpg");

        return ResponseEntity
                .ok()
                .contentType(MediaType.IMAGE_JPEG)
                .body(new InputStreamResource(imgFile.getInputStream()));
    }
}

The getImage() method return type is set to ResponseEntity<InputStreamResource>.

return ResponseEntity
        .ok()
        .contentType(MediaType.IMAGE_JPEG)
        .body(new InputStreamResource(imgFile.getInputStream()));

The body of the ResponseEntity returns an InputStreamResource.

$ mvn spring-boot:run

We start Spring Boot application.

We navigate to http://localhost:8080/sid to display the image in the browser.

In this tutorial, we have shown how to send image data to the client from a Spring Boot applications. We used three different methods. You might also be interested in these related tutorials: Displaying image in Java, Creating PDF report in Spring Boot, Spring Boot REST Data JPA tutorial, Spring Boot basic annotations, Spring Boot H2 tutorial, Spring Boot JasperReports web integration, Introduction to Spring web applications, Spring Boot first web application, and Java tutorial.