歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java實現一個簡單的Web服務器

Web服務器也稱為超文本傳輸協議服務器,使用http與其客戶端進行通信,基於java的web服務器會使用兩個重要的類,java.net.Socket類和java.net.ServerSocket類,並基於發送http消息進行通信。

基於Java實現的最簡單的Web服務器  http://www.linuxidc.com/Linux/2014-01/94647.htm

這個簡單的Web服務器會有以下三個類:

*HttpServer

*Request

*Response

應用程序的入口在HttpServer類中,main()方法創建一個HttpServer實例,然後調用其await()方法,顧名思義,await()方法會在指定端口上等待HTTP請求,對其進行處理,然後發送響應信息回客戶端,在接收到關閉命令前,它會保持等待狀態。

該應用程序僅發送位於指定目錄的靜態資源的請求,如html文件和圖像,它也可以將傳入到的http請求字節流顯示到控制台,但是,它並不發送任何頭信息到浏覽器,如日期或者cookies等。

下面為這幾個類的源碼:

Request

package cn.com.server;

import java.io.InputStream;

public class Request {
 private InputStream input;
 
 private String uri;
 
 public Request(InputStream input){
  this.input=input;
 }
 
 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 (Exception 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());
 }
 
 public String parseUri(String requestString){
  int index1,index2;
  index1=requestString.indexOf(" ");
  if(index1!=-1){
   index2=requestString.indexOf(" ",index1+1);
   if(index2>index1){
    return requestString.substring(index1+1,index2);
   }
  }
  return null;
 }
 
 public String getUri(){
  return this.uri;
 }
}

Request類表示一個HTTP請求,可以傳遞InputStream對象來創建Request對象,可以調用InputStream對象中的read()方法來讀取HTTP請求

的原始數據。

上述源碼中的parse()方法用於解析Http請求的原始數據,parse()方法會調用私有方法parseUrI()來解析HTTP請求的URI,除此之外,並沒有

做太多的工作,parseUri()方法將URI存儲在變量uri中,調用公共方法getUri()會返回請求的uri。

Response:

package cn.com.server;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * HTTP Response = Status-Line
 *   *(( general-header | response-header | entity-header ) CRLF)
 *   CRLF
 *   [message-body]
 *   Status-Line=Http-Version SP Status-Code SP Reason-Phrase CRLF
 *
 */
public class Response {
 private static final int BUFFER_SIZE=1024;
 Request request;
 OutputStream output;
 
 public Response(OutputStream output){
  this.output=output;
 }
 
 public void setRequest(Request request){
  this.request=request;
 }
 
 public void sendStaticResource()throws IOException{
  byte[] bytes=new byte[BUFFER_SIZE];
  FileInputStream fis=null;
  try {
   File file=new File(HttpServer.WEB_ROOT,request.getUri());
   if(file.exists()){
    fis=new FileInputStream(file);
    int ch=fis.read(bytes,0,BUFFER_SIZE);
    while(ch!=-1){
     output.write(bytes, 0, BUFFER_SIZE);
     ch=fis.read(bytes, 0, BUFFER_SIZE);
    }
   }else{
    //file not found
    String errorMessage="HTTP/1.1 404 File Not Found\r\n"+
    "Content-Type:text/html\r\n"+
    "Content-Length:23\r\n"+
    "\r\n"+
    "<h1>File Not Found</h1>";
    output.write(errorMessage.getBytes());
   }
  } catch (Exception e) {
   System.out.println(e.toString());
  }finally{
   if(fis!=null){
    fis.close();
   }
  }
 }
}

Response對象在HttpServer類的await()方法中通過傳入套接字中獲取的OutputStream來創建。

Response類有兩個公共方法:setRequest()和sendStaticResource(),setRequest()方法會接收一個Request對象為參數,sendStaticResource()方法用於發送一個靜態資源到浏覽器,如Html文件。

HttpServer:

package cn.com.server;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class HttpServer {
 /**
  * WEB_ROOT is the directory where our html and other files reside.
  * For this package,WEB_ROOT is the "webroot" directory under the
  * working directory.
  * the working directory is the location in the file system
  * from where the java command was invoke.
  */
 public static final String WEB_ROOT=System.getProperty("user.dir")+File.separator+"webroot";
 
 private static final String SHUTDOWN_COMMAND="/SHUTDOWN";
 
 private boolean shutdown=false;
 
 public static void main(String[] args) {
  HttpServer server=new HttpServer();
  server.await();
 }
 
 public void await(){
  ServerSocket serverSocket=null;
  int port=8080;
  try {
   serverSocket=new ServerSocket(port,1,InetAddress.getByName("127.0.0.1"));
  } catch (Exception e) {
   e.printStackTrace();
   System.exit(0);
  }
  while(!shutdown){
   Socket socket=null;
   InputStream input=null;
   OutputStream output=null;
   try {
    socket=serverSocket.accept();
    input=socket.getInputStream();
    output=socket.getOutputStream();
    //create Request object and parse
    Request request=new Request(input);
    request.parse();
   
    //create Response object
    Response response=new Response(output);
    response.setRequest(request);
    response.sendStaticResource();
   } catch (Exception e) {
    e.printStackTrace();
    continue;
   }
  }
 }
}

這個類表示一個Web服務器,這個Web服務器可以處理對指定目錄的靜態資源的請求,該目錄包括由公有靜態變量final WEB_ROOT指明的目錄及其所有子目錄。

現在在webroot中創建一個html頁面,命名為index.html,源碼如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
 <h1>Hello World!</h1>
</body>
</html>

現在啟動該WEB服務器,並請求index.html靜態頁面。

所對應的控制台的輸出:

如此,一個簡單的http服務器便完成了。

Copyright © Linux教程網 All Rights Reserved