Serving image file in Spring Boot
last modified July 31, 2023
In this article 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.
Spring image example
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. 
build.gradle
...
src
├── main
│   ├── java
│   │   └── com
│   │       └── zetcode
│   │           ├── Application.java
│   │           └── controller
│   │               └── MyController.java
│   └── resources
│       └── image
│           └── sid.jpg
└── test
    └── java
This is the project structure.
plugins {
    id 'org.springframework.boot' version '3.1.1'
    id 'io.spring.dependency-management' version '1.1.0'
    id 'java'
}
group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
    mavenCentral()
}
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}
This is the Gradle build file. The spring-boot-starter-web is a
starter for building web applications with Spring MVC. It uses Tomcat as the
default embedded server. 
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.
Serve image with HttpServletResponse
In the first case, we directly write to the HttpServletResponse.
package com.zetcode.controller;
import jakarta.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;
import java.io.IOException;
@RestController
public class MyController {
    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public void getImage(HttpServletResponse response) throws IOException {
        var 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.
var 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.
Serve image with ResponseEntity
In the second case, we use ResponseEntity.
package com.zetcode.controller;
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;
import java.io.IOException;
@RestController
public class MyController {
    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public ResponseEntity<byte[]> getImage() throws IOException {
        var 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.
Serve image with ResponseEntity and InputStreamResource
In the third case, we use ResponseEntity and InputStreamResource.
InputStreamResource is Spring's abstraction of low-level resources.
package com.zetcode.controller;
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;
import java.io.IOException;
@RestController
public class MyController {
    @RequestMapping(value = "/sid", method = RequestMethod.GET,
            produces = MediaType.IMAGE_JPEG_VALUE)
    public ResponseEntity<InputStreamResource> getImage() throws IOException {
        var 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.
$ ./gradlew bootRun
We start Spring Boot application.
We navigate to http://localhost:8080/sid to display the image in
the browser.
In this article we have shown how to send image data to the client from a Spring Boot applications.