Get the Response Body in Spring Boot Filter
Last Updated :
17 Sep, 2024
In a Spring Boot application, filters can be used to intercept requests and responses, allowing you to manipulate them before reaching the controller or after the response is generated. A common requirement is capturing or logging the response body in the Spring Boot filter, especially for monitoring, auditing, or debugging purposes. Capturing the response body in the filter isn't straightforward because once the response body is written, it cannot be retrieved directly from HttpServletResponse
. To address this, we can wrap the HttpServletResponse
and capture its content.
To capture the response body in the filter, we need to wrap the HttpServletResponse
object. This is achieved by creating a custom HttpServletResponseWrapper
that buffers the output stream, allowing us to read the response body even after it has been written.
Steps:
- Create the Custom HttpServletResponseWrapper: This wrapper class will buffer the output and allow us to capture the response body.
- Implement the Filter: The filter will use the wrapper to intercept and read the response body
Implementation to Get the Response Body in Spring Boot Filter
Step 1: Create the new Spring Boot project
Create a new Spring Boot project using IntelliJ IDEA. Choose the following options:
- Name:
spring-boot-response-filter
- Language: Java
- Type: Maven
- Packaging: Jar
Click the Next button to proceed.
Step 2: Add Dependencies
Add the following dependencies into the Spring Boot project.
- Spring Web
- Lombok
- Spring DevTools
Click on the Create button.
Project Structure
After successfully creating the project, the structure will look like the below image:
Step 3: Configure Application Properties
Open the application.properties
file and add the following configuration:
spring.application.name=spring-boot-response-filter
server.port = 8080
Step 4: Custom HTTP Response Wrapper
Create the CustomHttpResponseWrapper
class to wrap HttpServletResponse
and capture the response body.
CustomHttpResponseWrapper.java:
Java
package com.gfg.springbootresponsefilter;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.WriteListener;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Custom wrapper for HttpServletResponse to capture response body.
*/
public class CustomHttpResponseWrapper extends HttpServletResponseWrapper {
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
private final PrintWriter printWriter = new PrintWriter(outputStream);
public CustomHttpResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new ServletOutputStream() {
@Override
public boolean isReady() {
// Indicate whether the stream is ready to be written to.
return true; // Changed to true for better compatibility
}
@Override
public void setWriteListener(WriteListener writeListener) {
// No-op for synchronous processing
}
@Override
public void write(int b) throws IOException {
outputStream.write(b); // Write data to buffer
}
};
}
@Override
public PrintWriter getWriter() throws IOException {
return printWriter; // Use PrintWriter to capture text data
}
public byte[] getResponseData() throws IOException {
printWriter.flush(); // Ensure all data is written to the buffer
return outputStream.toByteArray(); // Return buffered response data
}
}
Step 5: Filter to Capture Response Body
Create the ResponseBodyLoggingFilter
class to intercept the response, capture the body, and log it before sending it back to the client.
ResponseBodyLoggingFilter.java:
Java
package com.gfg.springbootresponsefilter;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* Filter to capture and log the response body.
*/
@Component
public class ResponseBodyLoggingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// No initialization required
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// Cast response to HttpServletResponse
HttpServletResponse httpResponse = (HttpServletResponse) response;
// Wrap the response to capture the body
CustomHttpResponseWrapper responseWrapper = new CustomHttpResponseWrapper(httpResponse);
// Continue with the filter chain
chain.doFilter(request, responseWrapper);
// Get the response body data from the wrapper
byte[] responseData = responseWrapper.getResponseData();
String responseBody = new String(responseData, httpResponse.getCharacterEncoding());
// Log the response body
System.out.println("Response Body: " + responseBody);
// Write the response body back to the client
response.getOutputStream().write(responseData);
}
@Override
public void destroy() {
// No cleanup required
}
}
Step 6: Test Controller
Create the TestController
class with a simple REST controller that returns a message to simulate response content.
TestController.java:
Java
package com.gfg.springbootresponsefilter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* REST controller for testing response body capture.
*/
@RestController
public class TestController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!"; // Response message
}
}
Step 7: Main Class
The main class remains unchanged and is the entry point of the Spring Boot application.
SpringBootResponseFilterApplication.java:
Java
package com.gfg.springbootresponsefilter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootResponseFilterApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootResponseFilterApplication.class, args);
}
}
pom.xml File:
The pom.xml
file is configured with the necessary dependencies.
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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.gfg</groupId>
<artifactId>spring-boot-response-filter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-boot-response-filter</name>
<description>spring-boot-response-filter</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
Step 8: Run the Application
Once the project setup is complete, start the application. It will run on port 8080.
Step 9: Test the Application
Use Postman or any other API client to send a GET request to:
http://localhost:8080/hello
We should see the following message in the postman.
Application Logs
In the application logs, you should see the captured response body:
Conclusion
In this example project, we demonstrated how to capture the response body in a Spring Boot filter by creating a custom HttpServletResponseWrapper
. This technique can be useful for logging or modifying the response before it is sent to the client.
Similar Reads
Spring Boot - Servlet Filter
Spring boot Servlet Filter is a component used to intercept & manipulate HTTP requests and responses. Servlet filters help in performing pre-processing & post-processing tasks such as: Logging and Auditing: Logging operations can be performed by the servlet filter logging the request and res
8 min read
A Guide to RestClient in Spring Boot
In Spring Boot applications, external services often need to be communicated via REST APIs. Traditionally, RestTemplate was used for this purpose, but it is now considered a legacy approach. Starting from Spring Framework 6.1 and Spring Boot 3.2, RestClient has been introduced as a modern alternativ
9 min read
Spring Security Integration with Spring Boot
Spring Security is a powerful and customizable authentication and access control framework for Java applications. It provides comprehensive security services for Java EE-based enterprise software applications. This article will integrate Spring Security with a Spring Boot application, covering confi
5 min read
How to Log Request and Response Bodies in Spring WebFlux?
To log request and response bodies in Spring WebFlux, we need to use filters or logging mechanisms that can intercept and log the necessary information. In this article, we use WebFilter to filter the request types in the Spring application. Intercepting the Request Body:The getRequest().getBody() m
5 min read
Read file from Resources Folder in Spring Boot
Spring Boot is a framework for handling web applications, and it is easy to create stand-alone applications. The Spring Boot framework is an open-source Java-based framework mostly used for creating microservices. In this article, we will discuss how to read file from the resources folder in Spring
4 min read
Spring Boot â Setting Up a Spring Boot Project with Gradle
Spring Boot is a Java framework designed to simplify the development of stand-alone, production-ready Spring applications with minimal setup and configuration. It simplifies the setup and development of new Spring applications, reducing boilerplate code.In this article, we will guide you through set
4 min read
How to Define a Spring Boot Filter?
A filter in Spring Boot intercepts HTTP requests and responses in the web application. Filters allow developers to perform operations before or after a request is processed by the controller or servlet. They are useful for authentication, logging, request modification, and more tasks. Spring Boot si
7 min read
Spring Security - Find the Registered Filters
In Spring Boot, Spring Security is the most powerful and customizable authentication and access control framework for Java applications, and it provides strong security features to protect web applications from various security threats such as authentication, authorization, session management, and w
14 min read
Introduction to Spring Boot
Spring is widely used for creating scalable applications. For web applications, Spring provides Spring MVC, a commonly used module for building robust web applications. The major drawback of traditional Spring projects is that configuration can be time-consuming and overwhelming for new developers.
5 min read
How to Get All Endpoints in Spring Boot?
In Spring Boot applications, listing all the exposed endpoints can be highly beneficial for debugging or documentation purposes. This can be accomplished by leveraging Spring Boot Actuator, a sub-project of Spring Boot that provides production-ready features such as monitoring and management. In thi
3 min read