装饰者模式:打个比方就像快递,主体是你的东西,纸箱,泡沫这些都是装饰。为的是解决,主体和装饰n:n组合,不至于类太多。
java中最典型的io流设计就是装饰者。这里举一个实际中的列子,我们有效运用的例子。
对httpServletRequest的封装,主要是获取请求的body数据,
采用装饰者,我们分离我们的输入参数body。
因为我们在@requestBody中要用到。
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.StreamUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.ByteArrayInputStream;
import java.io.IOException;
/**
* @Auther: Administrator
* @Date: 2020/2/16 0016 11:39
* @Description:
*/
public class MyHttpServletWrapper extends HttpServletRequestWrapper {
private byte[] body;
public MyHttpServletWrapper(HttpServletRequest request) {
super(request);
}
public void setBody(Object body) {
String str = JSONObject.toJSONString(body);
this.body = str.getBytes();
}
/**
*
* 功能描述:重载这个方法,是因为该方法在@RequestBody修饰的方法中会用到
*
* @param:
* @return:
* @auther: Administrator
* @date: 2020/2/16 0016 16:54
*/
@Override
public ServletInputStream getInputStream() throws IOException {
if(null == body){
return new ByteArrayInputStreamWrap(StreamUtils.copyToByteArray(super.getInputStream()));
}
return new ByteArrayInputStreamWrap(body);
}
private class ByteArrayInputStreamWrap extends ServletInputStream{
ByteArrayInputStream inputStream;
public ByteArrayInputStreamWrap(byte[] body) {
this.inputStream =new ByteArrayInputStream(body);
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener readListener) {
}
@Override
public int read() throws IOException {
return inputStream.read();
}
}
}