我们的服务器现在已经可以给客户端响应了,可是只能给固定的响应。接下来要做的事情就是把客户端提交的请求进行解析,然后得到请求的内容,返回客户的响应。这部分我们会分出三个类来,分别是:HttpRequest,HttpResponse,Service。HttpRequest用于解析请求,HttpResponse用于构造响应。Service用于提供服务。那么,开始看代码吧!
package mywebserver4;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
public class HttpRequest {
StringBuilder requestBody = new StringBuilder();
StringBuilder requestHead = new StringBuilder();
Map requestMap = new HashMap();
public void addHead(String headLine) {
requestHead.append(headLine);
StringTokenizer token = new StringTokenizer(headLine, ":");
String propName = token.nextToken();
String propBody = token.nextToken();
requestMap.put(propName.trim(), propBody.trim());
}
public void addFirstLine(String line) {
StringTokenizer token = new StringTokenizer(line);
String method = token.nextToken();
String path = token.nextToken();
String httpVersion = token.nextToken();
requestMap.put("method", method.trim());
requestMap.put("path", path.trim());
requestMap.put("httpVersion", httpVersion.trim());
}
public void addBody(String headBody) {
requestBody.append(headBody);
}
public String getRequestPath() {
return (String)requestMap.get("path");
}
public String getAllRequestString(){
StringBuilder allRequest = new StringBuilder();
java.util.Iterator it = this.requestMap.entrySet().iterator();
while (it.hasNext()) {
java.util.Map.Entry entry = (java.util.Map.Entry) it.next();
// entry.getKey() 返回与此项对应的键
// entry.getValue() 返回与此项对应的值
allRequest.append(entry.getKey()+": ");
allRequest.append(entry.getValue()+"/n");
}
return allRequest.toString();
}
public static void main(String [] args){
HttpRequest req = new HttpRequest();
req.addHead("a:1234");
req.addHead("b: 5678");
System.out.println(req.getAllRequestString());
}
}
package mywebserver4;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class HttpResponse {
StringBuilder responseBody = new StringBuilder();
StringBuilder responseHead = new StringBuilder();
// 拼接响应头
public HttpResponse() {
responseHead.append("HTTP/1.1 200 OK");
responseHead.append("/n");
responseHead.append("Server: AllenWebServer");
responseHead.append("/n");
}
public void setBodyLength(int length){
responseHead.append("Content-Length: " + length);
responseHead.append("/n");
responseHead.append("/n");
}
public String getHead(){
return responseHead.toString();
}
public String getBody(){
return responseBody.toString();
}
public StringBuilder getResponseBody(){
return this.responseBody;
}
}
package mywebserver4;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Service {
public static String appRootPath = "E:/";
public static void doService(HttpRequest request, HttpResponse response,
BufferedWriter bw) {
FileReader htmlFR;
try {
String path = request.getRequestPath();
String realPath;
if ("/".equals(path)) {
realPath = "/index.html";
} else {
realPath = appRootPath + path;
}
htmlFR = new FileReader(realPath);
BufferedReader htmlBR = new BufferedReader(htmlFR);
String Line = htmlBR.readLine();
while (Line != null) {
response.getResponseBody().append(Line);
Line = htmlBR.readLine();
}
htmlBR.close();
htmlFR.close();
} catch (FileNotFoundException e1) {
response.getResponseBody().append("找不到文件!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 得到相应体的长度。
int bodylength = response.getResponseBody().toString().getBytes().length;
response.setBodyLength(bodylength);
try {
bw.write(response.getHead());
bw.flush();
bw.write(response.getBody());
bw.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package mywebserver4;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
/**
* @author allen
* @version 0.2
*/
public class Server {
public static void main(String[] args) {
ServerSocket ss = null;
try {
ss = new ServerSocket(80);
while (true) {
Socket s = ss.accept();
HttpRequest request = new HttpRequest();
BufferedReader br = new BufferedReader(new InputStreamReader(s
.getInputStream()));
String requestLine = "";
char[] body;
boolean haveBody = false;
int length = 0;
boolean ifFirst = true;
do {
requestLine = br.readLine();
if (!requestLine.equals("")) {
if (ifFirst) {
request.addFirstLine(requestLine);
ifFirst = false;
} else {
request.addHead(requestLine);
}
// post方式提交的请求还要取得,请求体的内容
if (requestLine.startsWith("Content-Length")) {
StringTokenizer st = new StringTokenizer(
requestLine, ":");
st.nextToken();
String bodyLength = st.nextToken().trim();
length = Integer.parseInt(bodyLength);
haveBody = true;
}
}
if (requestLine.equals("") && haveBody) {
body = new char[length];
br.read(body, 0, length);
request.addBody(new String(body));
}
} while (!requestLine.equals(""));
// 开始响应
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s
.getOutputStream()));
HttpResponse response = new HttpResponse();
Service.doService(request, response, bw);
br.close();
s.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 资源清理代码
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
到现在,已经实现了解析客户请求,得到请求的文件名,然后把e:/下的文件(文本文件)返回给客户端!
一个比较简单的Web服务器器就差不多完成了!