[Java] Get Body part of HttpResponse with Spring Filter

1 minute read

いい感じの凡例が見つからなかったので作ってみました。 STSのデバック環境下で動作確認済みです。

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();
 }
}

適当にサンプルを作って動作を確認。 下記サンプルの場合、PrintWriterExが動作した。

HelloController.java


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

下記サンプルの場合、GET/POSTのどちらの場合もServletOutputStreamExが動作した。

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\" }";
 }
}