How Tomcat Works學習筆記

 

1 第一章、 一個簡單的web服務器

這一章主要介紹一個web服務器是怎樣工作的,一個web服務器通常也叫Http服務器因爲通過http協議與客戶端(瀏覽器)交互。

1.1     超文本傳輸協議HTTP

HTTP協議包括HTTP Request和HTTP Response

Client初始化連接的時候爲傳送一個HTTP Request,包括三個部分:

         方法-URI-協議/版本

         Request 頭

         Request 體

與Request HTTP相似,HTTP Response也包括三個部分:

         協議-狀態-描述

         Response 頭

         Response 體

1.2     Socket 和 ServerSocket

套接字socket代表客戶端與服務器連接,你可以通過他與服務器建立連接,可以指定host和port,Java中用Socket類來建立,有多個構造函數。

可以通過ServerSocket建立http服務器或者ftp服務器。

 

1.3     應用

在eclipse中建立java工程tomcat_study,具體結構如下:

         src:存放java原文件

         webroot: 存放html文件

         lib:所需庫

         webapps:應用程序

        

這裏實現一個服務器應用,主要實現三個類:

         HttpServer

         Request

         Response

在main方法中創建HttpServer實例,並調用它的await方法,該方法監聽制定端口的Http請求,處理以後返回給客戶端,直到收到shutdown命令。

 

package com.ex01.pyfrmont;

 

import java.io.File;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.InetAddress;

import java.net.ServerSocket;

import java.net.Socket;

 

/**

 *

 * 服務器實現類,await方法,該方法監聽制定端口的Http請求,

 * 處理以後返回給客戶端,直到收到shutdown命令

 * @author peng_yf

 * @version 1.0,2011-08-20

 * @since 1.0

 *

 */

public class HttpServer {

 

    /**

     * WEB_ROOT is the directory where our HTML and other files reside.

     * For this packge,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 invoked.

     */

    public static final String WEB_ROOT =

       System.getProperty("user.dir") + File.separator + "webroot";

   

    /**

     * shutdown command

     */

    private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";

   

    /**

     * the shutdown command received

     */

    private boolean  shutdown = false;

   

    /**

     * @param args

     */

    public static void main(String[] args) {

       HttpServer server = new HttpServer();

       server.await();

    }

 

    private void await() {

       ServerSocket serverSocket = null;

       int port = 8080;

       try{

           serverSocket = new ServerSocket(port,1,InetAddress.getByName("127.0.0.1"));

       }catch (IOException e) {

           e.printStackTrace();

           System.exit(1);

       }

      

       //Loop waiting for a request

        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();

             

              //close the socket

               socket.close();

             

              //check if the previous URI is a shutdown command

              shutdown = request.getUri().equals(SHUTDOWN_COMMAND);

           }catch (Exception e) {

              e.printStackTrace();

              continue;

           }  

       }      

    }

}

 

         Request代表一個HTTP請求,用Socket中與客戶端通信的輸入流來構造,可以通過其中的read方法讀取HTTP格式數據。

package com.ex01.pyfrmont;

 

import java.io.IOException;

import java.io.InputStream;

 

/**

 * 代表一個HTTP請求,用Socket中與客戶端通信的輸入流來構造,可

 * 以通過其中的read方法讀取HTTP格式數據

 * @author Peng_yf

 * @version 1.0,2011-08-20

 * @since 1.0

 */

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 (IOException e) {

           e.printStackTrace();

           i = -1;

       }

       for(int j=0; j < i; j++){

           request.append((char)buffer[j]);

       }

       System.out.println(request.toString());

        uri = parseUri(request.toString());

    }

 

    private String parseUri(String requestString){

       int index1,index2;

       index1 = requestString.indexOf(' ');

       while(index1 != -1){

           index2 = requestString.indexOf(' ', index1+1);

           if(index1 < index2){

              return requestString.substring(index1+1,index2);

           }

       }

       return null;

    }

   

    public String getUri(){

       return this.uri;

    }

   

}

 

                   Response代表HTTP響應。

package com.ex01.pyfrmont;

 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

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 Response-Phrase CRLF

 * @author Peng_yf

 * @version 1.0, 2011-08-20

 * @since 1.0

 *

 */

public class Response {

    private static final int BUFFER_SIZE = 1024;

    OutputStream output;

    Request request;

   

    public Response(OutputStream output) {

       this.output = output;

    }

 

    public void setRequest(Request request) {

       this.request = request;

    }

 

    public void sendStaticResource() {

       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);

              if(ch != -1){

                  output.write(bytes, 0, ch);

                  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) {

           //thrown if cannot instantiate a File object.

           System.out.println(e.getMessage());

           e.printStackTrace();

       }finally{

           if(fis != null){

              try {

                  fis.close();

              } catch (IOException e) {

                  e.printStackTrace();

              }

           }

       }

    }

}

測試運行時,運行HttpServer,在界面輸入:

         http://localhost:8080/index.html

將會在瀏覽器中顯示index.html中的內容。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章