包装ServletRequest和ServletResponse

为什么要记录Request Body

  在做测试(这里主要是指的App端,网页端直接firebug即可)的时候,在接口测试错误出现Bug的时候,方便定位错误。

  封装ServletRequest

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



封装ServletResponse

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



你可能感兴趣的:(java,RequestWrapper,ResponseWrapper)