HttpRequest对象的封装
摘要:
这篇文章主要为大家介绍一下在本服务器中如何对Request对象进行封装。
第一步:定义一个抽象类HttpRequest
public abstract class HttpRequest {
private String type ; // 标识这个请求的类型,GET,POST
public HttpRequest(String type) {
this.type = type;
} // 构造方法
public String getType() {
return type;
} // 获得类型
// abstract methods
abstract public void setHeader(String contentPerLine) ; // 设置请求头
abstract public Vector<String> getHeader() ; // 获得请求头
}
解释:
在这里有很多朋友可能会问为什么要定义这样一个抽象类,在这里呢,是为了后续的服务器完善的时候有良好的可拓展性。当我们想添加多一个请求的时候,就可以编写一个新类,继承这个父类,然后编写新的逻辑即可。
设计原则:
里氏代换原则、开闭原则
第二步:定义一个简单工厂RequestFactory,负责生产request。
public class RequestFactory { // 该类是一个工具类,无需创建对象
public static HttpRequest parseRequest(InputStream stream) throws Exception {
// 参数说明:stream是通过客户端的socket获得来自浏览器的输入流
int b = 0 ;
StringBuffer requestBuffer = new StringBuffer() ; // 请求保存
b = stream.read() ; // 阻塞接受数据
requestBuffer.append((char)b) ;
int size = stream.available() ; // 查看请求的总长度
System.out.println("request:"); // 打印console
System.out.print((char)b);
while(size--!=0){
b = stream.read() ;
System.out.print((char)b);
requestBuffer.append((char)b) ;
}
System.out.println();
// 解析请求
String request = requestBuffer.toString() ;
String requestType = request.substring(0,request.indexOf(" ")) ; // 获得请求类型
StringTokenizer stringTokenizer = new StringTokenizer(request,"\r\n") ; // 切分字符串
HttpRequest httpRequest = null ;
// 根据请求类型生成不同的对象,这里用到了迪米特法则
if (requestType.equalsIgnoreCase("GET")){
httpRequest = new Get(requestType) ;
}else if (requestType.equalsIgnoreCase("POST")){
httpRequest = new Post(requestType) ;
}
else if (requestType.equalsIgnoreCase("HEAD")){
httpRequest = new Head(requestType) ;
}else{
System.out.println("暂无该请求的处理方式");
return null ;
}
// 构建请求头
while(stringTokenizer.hasMoreTokens()){
String line = stringTokenizer.nextToken() ;
httpRequest.setHeader(line+"\r\n");
}
return httpRequest ;
}
}
注意:
这里在开发过程中遇到过bug,主要是avaliable获得浏览器的请求的长度为0,这个问题已经得到解决了,至于是为什么可以去看一下我之前的一篇文章。
设计模式:
简单工厂模式。
第三步:构建get请求。
public class Get extends HttpRequest{
private Vector<String> headers ; // 保存头信息
public Get(String type) {
super(type);
}
@Override
public Vector<String> getHeader() {
return headers ;
} // 获得头信息
@Override
public void setHeader(String contentPerLine) { // 设置头信息
if (headers==null){
headers = new Vector<>() ;
}
headers.add(contentPerLine) ;
}
}
解释:
主要封装了设置头和返回头的一些方法。
第四步:构建Post请求。
public class Post extends HttpRequest{
private Vector<String> headers ;
public Post(String type) {
super(type);
}
@Override
public Vector<String> getHeader() {
return headers;
}
@Override
public void setHeader(String contentPerLine) {
if (headers==null){
headers = new Vector<>() ;
}
headers.add(contentPerLine) ;
}
}
第五步:构建Head请求
public class Head extends HttpRequest{
private Vector<String> headers ;
private StringBuffer packet ;
public Head(String type) {
super(type);
}
@Override
public Vector<String> getHeader() {
return headers ;
}
@Override
public void setHeader(String contentPerLine) {
if (headers==null){
headers = new Vector<>() ;
}
headers.add(contentPerLine) ;
}
}
总结:
来个小总结吧,这一次我们主要实现了各种请求的封装,其主要的用途就是把来自客户端(浏览器)的请求做了解析,方便我们后续构建response。
感谢阅读,欢迎指教。