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.