Get Body part of HttpResponse with Filter of Spring

I couldn't find a nice legend, so I made one. It has been confirmed to work under the STS debug environment.

LoggingFilter.java


@Component
public class LoggingFilter implements Filter {
	private static final Logger log = LoggerFactory.getLogger(LoggingFilter.class.getName());

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		HttpServletResponseWrapperEx httpResponseEx = new HttpServletResponseWrapperEx(httpResponse);	
		chain.doFilter(request, httpResponseEx);

		String responseBody = httpResponseEx.getBody();		
		log.debug(responseBody);
	}
}

HttpServletResponseWrapperEx.java



public class HttpServletResponseWrapperEx extends HttpServletResponseWrapper {
	private ServletResponse response;
	private PrintWriterEx writerEx;
	private ServletOutputStreamEx outputStreamEx;
	
	public HttpServletResponseWrapperEx(HttpServletResponse response) {
		super(response);
		this.response = response;
	}
	
	@Override
	public ServletOutputStream getOutputStream() throws IOException {

		ServletOutputStream stream = this.response.getOutputStream();
		
		if (null == this.outputStreamEx) {
			this.outputStreamEx = new ServletOutputStreamEx(stream);
		}
		
		return this.outputStreamEx;
	}
	
	@Override
	public PrintWriter getWriter() throws IOException {
		PrintWriter writer = this.response.getWriter();
		this.writerEx = new PrintWriterEx(writer);
		return this.writerEx;
	}
	
	public String getBody() {
		String result = "";
		
		if (null != this.outputStreamEx) {
			result = this.outputStreamEx.getBody();
		}
		else if (null != this.writerEx) {
			result = this.writerEx.getBody();
		}
		
		return result;
	}
}

ServletOutputStreamEx.java



public class ServletOutputStreamEx extends ServletOutputStream {
	private StringBuilder body = new StringBuilder();
	private ServletOutputStream target;
	
	public ServletOutputStreamEx(ServletOutputStream target) {
		this.target = target;
	}

	@Override
	public boolean isReady() {
		return this.target.isReady();
	}

	@Override
	public void setWriteListener(WriteListener listener) {
		this.target.setWriteListener(listener);		
	}

	@Override
	public void write(int b) throws IOException {
		this.target.write(b);
		byte [] value = new byte[] {(byte)b};
		String temp = new String(value);
		body.append(temp);		
	}
	
	public String getBody() {
		return this.body.toString();
	}
}

PrintWriterEx.java


public class PrintWriterEx extends PrintWriter {

	private StringBuilder body = new StringBuilder();
	
	public PrintWriterEx(Writer out) {
		super(out);
	}
	
	@Override
	public void write(int c) {
		super.write(c);
		this.body.append((char)c);
	}
	
	@Override
	public void write(char[] chars, int offset, int length) {
		super.write(chars, offset, length);
		this.body.append(chars, offset, length);
	}
	
	public void write(String string, int offset, int length) {
		super.write(string, offset, length);
		this.body.append(string, offset, length);
	}
	
	public String getBody() {
		return this.body.toString();
	}
}

Make an appropriate sample and check the operation. In the case of the sample below, PrintWriterEx worked.

HelloController.java


@Controller
public class HeloController{
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Model model) {
        model.addAttribute("message", "Hello Springboot");
        return "index";
    }
}

In the case of the sample below, ServletOutputStreamEx worked in both cases of GET / POST.

GoodbyeController.java


@RestController
public class GoodbyeController {

	@RequestMapping(path = "/goodbye", method = RequestMethod.GET)
	public String goodbye() {
		return "good bye";
	}
	
	@RequestMapping(path = "/goodbyebye", method = RequestMethod.POST)
	public String goodbyebye() {
		return "{ message: \"goodbye\" }";
	}
}

Recommended Posts

Get Body part of HttpResponse with Filter of Spring
Get started with Spring boot
Get validation results with Spring Boot
Filter the result of BindingResult [Spring]
Get Flux result of Spring Web Flux from JS with Fetch API
How to read Body of Request multiple times with Spring Boot + Spring Security
Extract a part of a string with Ruby
Collective handling of Spring validation errors with @ControllerAdvice
[JavaScript] I can't get the response body at the time of error with axios (ajax)
I created an api domain with Spring Framework. Part 2
Compatibility of Spring JDBC and MyBatis with Spring Data JDBC (provisional)
Access the built-in h2db of spring boot with jdbcTemplate
[Spring Boot] Get user information with Rest API (beginner)
I tried to get started with Spring Data JPA
Until the use of Spring Data and JPA Part 2
Customize REST API error response with Spring Boot (Part 2)
Create Restapi with Spring Boot ((1) Until Run of App)
Until the use of Spring Data and JPA Part 1
I created an api domain with Spring Framework. Part 1
How to boot by environment with Spring Boot of Maven
Customize REST API error response with Spring Boot (Part 1)
Control the processing flow of Spring Batch with JavaConfig.
Replace only part of the URL host with java
Build a WEB system with Spring + Doma + H2DB Part 2
Let's find out how to receive in Request Body with REST API of Spring Boot