自己动手,写个Web服务器(Java版)——第三篇

本文介绍了一个简易Web服务器的实现过程,包括客户端请求解析、响应构建和服务提供等核心环节,并通过具体代码展示了HttpRequest、HttpResponse及Service类的设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    我们的服务器现在已经可以给客户端响应了,可是只能给固定的响应。接下来要做的事情就是把客户端提交的请求进行解析,然后得到请求的内容,返回客户的响应。这部分我们会分出三个类来,分别是:HttpRequestHttpResponseServiceHttpRequest用于解析请求,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服务器器就差不多完成了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值