Request 类对应 HTTP 请求。创建这个类的实例,并传给它从 Socket 获得的 InputStream 对象,从而捕获与客户端的通信。呼叫 InputStream 对象的 read 方法中的一个就可以得到 HTTP 请求的原始数据。 Request 类有二个 public 方法 parse 与 getUri。parse 方法解析 HTTP 请求的原始数据。它做的事情不多--唯一它使之有效的信息是 HTTP 请求的 URI ,这个通过呼叫私有方法 parseUri 来获得。parseUri 方法把 URI 作为一个变量。调用 getUri 方法可以得到 HTTP 请求的 URI 。 要明白 parse 与 parseUri 的工作原理,你需要知道 HTTP 请求的结构,由 RFC2616 定义。 一个 HTTP 请求包括三个部分: Request line Headers Message body 现在,我们只需要关注 HTTP 请求的第一部分--请求行。请求行以方法记号开始,接着是请求的 URI 与协议版本,以回车换行符结束。请求行的元素之间以空格分开。例如,一个用 GET 方法的 index.Html 文件的请求行如下: GET /index.html HTTP/1.1 parse 方法从 socket 的 InputStream 传递给 Request 对象中读取字节流,把这个字节数组存在缓冲里。然后,它把 buffer 字节数组里的字节放入叫做 request 的 StringBuffer 对象中,再把 StringBuffer 替换成 String 传递给 parseUri 方法。 parse 方法的代码如列表 1.2 Listing 1.2. The Request class' parse method
public void parse() { // Read a set of characters from the socket StringBuffer request = new StringBuffer(2048); int i; byte[] buffer = new byte[2048];
try { i = input.read(buffer); } catch (IOException e) { e.PRintStackTrace(); i = -1; }
for (int j=0; j<i; j++) { request.append((char) buffer[j]); }
System.out.print(request.toString()); uri = parseUri(request.toString()); }
parseUri 方法查找请求行的第一个与第二个空格,从而从请求行获得了 URI 。列表 1.3 展示了 parseUri 方法的代码。 Listing 1.3. The Request class' parseUri method