梱包サーブレットRequestとサーブレットResponse


なぜRequest Bodyを記録するのか
テスト(ここでは主にApp側を指し、Web側は直接firebugでよい)を行う場合、インタフェーステストエラーでBugが発生した場合、位置決めエラーが便利になります.
パッケージングサーブレットRequest
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class RequestWrapper extends HttpServletRequestWrapper {

	private final byte[] buffer;

	private ServletInputStream sis;

	private BufferedReader reader;

	public byte[] getBuffer() {
		return buffer;
	}

	public RequestWrapper(HttpServletRequest request) throws IOException {
		super(request);
		final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		copyStream(request.getInputStream(), byteArrayOutputStream);
		buffer = byteArrayOutputStream.toByteArray();
	}

	@Override
	public BufferedReader getReader() throws IOException {
		if (reader == null) {
			String characterEncoding = this.getCharacterEncoding();
			if (characterEncoding == null) {
				reader = new BufferedReader(new InputStreamReader(
						this.getInputStream()));
			} else {
				reader = new BufferedReader(new InputStreamReader(
						this.getInputStream(), characterEncoding));
			}
		}
		return reader;
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		if (sis == null) {
			final ByteArrayInputStream bais = new ByteArrayInputStream(buffer);
			sis = new ServletInputStream() {
				@Override
				public int read() throws IOException {
					return bais.read();
				}
			};
		}
		return sis;
	}

	private void copyStream(InputStream input, OutputStream output)
			throws IOException {
		final byte[] bytes = new byte[1024];
		int length;
		while ((length = input.read(bytes)) != -1) {
			output.write(bytes, 0, length);
		}
	}
	
	public String doGetRequestBody() {
		return new String(buffer);
	}
}
java.io.EOFException: No content to map to Object due to end of input
java.lang.IllegalStateException: getReader() has already been called for this request

パッケージングサーブレットResponse
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class ResponseWrapper extends HttpServletResponseWrapper {

	private ByteArrayOutputStream buffer = null;
	private ServletOutputStream out = null;
	private PrintWriter writer = null;

	public ResponseWrapper(HttpServletResponse resp) throws IOException {
		super(resp);
		buffer = new ByteArrayOutputStream();//         
		out = new WapperedOutputStream(buffer);
		writer = new PrintWriter(new OutputStreamWriter(buffer,
				this.getCharacterEncoding()));
	}

	//       outputstream   
	@Override
	public ServletOutputStream getOutputStream() throws IOException {
		return out;
	}

	//       writer   
	@Override
	public PrintWriter getWriter() throws UnsupportedEncodingException {
		return writer;
	}

	//       flushBuffer   
	@Override
	public void flushBuffer() throws IOException {
		if (out != null) {
			out.flush();
		}
		if (writer != null) {
			writer.flush();
		}
	}

	@Override
	public void reset() {
		buffer.reset();
	}

	public String getContent() throws IOException {
		flushBuffer();//  out、writer         WapperedResponse buffer  ,       
		return new String(buffer.toByteArray());
	}

	//    , ServletOutputStream    
	private class WapperedOutputStream extends ServletOutputStream {
		private ByteArrayOutputStream bos = null;

		public WapperedOutputStream(ByteArrayOutputStream stream)
				throws IOException {
			bos = stream;
		}

		@Override
		public void write(int b) throws IOException {
			bos.write(b);
		}
	}
}