SpringのFilterでHttpResponseのBody部を取得する

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

```java: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);
	}
}

```



```java: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;
	}
}
```



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



```java: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が動作した。

```java: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が動作した。

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