1. 程式人生 > >使用Java實現一個最簡單的Web Server

使用Java實現一個最簡單的Web Server

Hello Web Server

Web Server沒有你想象的那麼難實現(當然要實現一個好的Java Web Server還是很有難度的)。你只要明白基本的HTTP協議,TCP程式設計和IO知識。當然,你也要會最簡單的HTML程式碼。

我們先來一個屌絲版,這個屌絲版能顯示Hello Web Server

package exec.network.webserver;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import
java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class SimpleHttpServer { private final static int TCP_PORT = 9090; public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(TCP_PORT); Socket socket = ss.accept(); BufferedReader br = new
BufferedReader( new InputStreamReader(socket.getInputStream())); String buffer = null; while ((buffer = br.readLine()) != null && !s.equals("")) { System.out.println(buffer); } BufferedWriter bw = new BufferedWriter( new
OutputStreamWriter(socket.getOutputStream())); bw.write("HTTP/1.1 200 OK\n"); bw.write("Content-Type: text/html; charset=UTF-8\n\n"); bw.write("<html>\n" + "<head>\n" + " <title>first page</title>\n" + "</head>\n" + "<body>\n" + " <h1>Hello Web Server!</h1>\n" + "</body>\n" + "</html>\n"); bw.flush(); bw.close(); br.close(); socket.close(); ss.close(); } }

執行這個程式,然後再瀏覽器裡敲:http://localhost:9090/,頁面上會出現一個大大的Hello Web Server。然後,就沒有然後了……

靜態網頁版

看了上面的程式,你可能都會說,太屌絲了,不行,繼續。

我們來加強這個Web Server。

準備示例的靜態頁面檔案

準備一個webroot資料夾,裡面放個index.htm檔案,再準備一個01.jpg檔案,作為圖片放進去。這個是我們準備的index.htm,圖片就不展示了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<h2>HTTP SERVER</h2>
<p>Where there is a will, there is a way.</p>
<img src="01.jpg"  />
</body>
</html>

準備HttpServer和Request,Response程式

  1. HttpServer
package exec.network.webserver;

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

public class HttpServer {
    private static final int SERVER_PORT = 9090;
    public static final String WEB_ROOT = System.getProperty("user.dir")
            + File.separator + "webroot";
    private static final String SHUTDOWN_COMMAND = "/QUIT";

    public static void main(String[] args) {
        HttpServer server = new HttpServer();
        server.await();
    }

    public void await() {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(SERVER_PORT);
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }

        while(true) {
            Socket socket = null;
            InputStream input = null;
            OutputStream output = null;
            try {
                socket = serverSocket.accept();
                input = socket.getInputStream();
                output = socket.getOutputStream();

                // 建立Request物件並解析
                Request request = new Request(input);
                request.parse();
                // 檢查是否是關閉服務命令
                if (request.getUri().equals(SHUTDOWN_COMMAND)) {
                    break;
                }

                // 建立 Response 物件
                Response response = new Response(output);
                response.setRequest(request);
                response.sendStaticResource();

                // 關閉 socket 物件
                socket.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
  1. Request
package exec.network.webserver;

import java.io.InputStream;

public class Request {
    private final static int BUFFER_SIZE = 1024;
    private InputStream input;
    private String uri;

    public Request(InputStream input) {
        this.input = input;
    }

    public void parse() {
        StringBuffer request = new StringBuffer();
        int readLength;
        byte[] buffer = new byte[BUFFER_SIZE];

        try {
            readLength = input.read(buffer);
        } catch (Exception e) {
            e.printStackTrace();
            readLength = -1;
        }
        for(int i = 0; i < readLength; i++) {
            request.append((char)buffer[i]);
        }
        System.out.print(request.toString());
        uri = parseUri(request.toString());
    }

    private 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 uri;
    }
}
  1. Response
package exec.network.webserver;

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

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[] buffer = new byte[BUFFER_SIZE];
        FileInputStream fis = null;
        try {            
            File file = new File(
                    HttpServer.WEB_ROOT, request.getUri());
            if(file.exists()) {
                output.write("HTTP/1.1 200 OK\n".getBytes());
                output.write("Content-Type: text/html; charset=UTF-8\n\n".getBytes());
                fis = new FileInputStream(file);
                int readLength;
                while((readLength = fis.read(buffer, 0, BUFFER_SIZE)) > 0 ) {
                    output.write(buffer, 0, readLength);
                }
            }
            else {
                String errMsg = "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(errMsg.getBytes());
            }
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            if(fis != null) {
                fis.close();
            }
        }
    }
}

好了,最簡單的Web Server我們已經用Java實現了,簡單吧。

參考資料

相關推薦

使用Java實現一個簡單Web Server

Hello Web Server Web Server沒有你想象的那麼難實現(當然要實現一個好的Java Web Server還是很有難度的)。你只要明白基本的HTTP協議,TCP程式設計和IO知識。當然,你也要會最簡單的HTML程式碼。 我們先來一個屌絲版

java實現一個簡單的tomcat服務

連接數 accep print tex soc ins udp web服務 reply 1.如何啟動? main方法是程序的入口,tomcat也不例外,查看tomcat源碼,發現main是在Bootstrap 類中的; 2.如何建立連接? 要通訊,必須要建議so

300行ABAP代碼實現一個簡單的區塊鏈原型

指向 repo 方法調用 輸入參數 transacti ui控件 挖礦 太多的 work 不知從什麽時候起,區塊鏈在網上一下子就火了。 這裏Jerry就不班門弄斧了,網上有太多的區塊鏈介紹文章。我的這篇文章沒有任何高大上的術語,就是300行ABAP代碼,實現一個最簡單的區

python只使用Queue和Thread自己實現一個簡單的執行緒池

        我的思路就是就是寫一個TifCutting類繼承自Thread,這個類裡有個屬性Queue;有一個addTask新增任務的方法,這個方法是把需要執行的函式放到Queue裡;因為繼承自Thread類,一定有一個重寫的run方法,這個方法是從自己的Queue屬性裡

Python實現一個簡單的MapReduce程式設計模型WordCount

MapReduce程式設計模型: Map:對映過程 Reduce:合併過程 import operator from functools import reduce # 需要處理的資料 lst = [ "Tom", "Jack",

實現一個簡單的flask應用程式

首先先將flask包匯入,建立flask物件,然後使用flask路由器指定網址和控制器。最後使用程式入口將flask應用啟動,port引數用來調整埠號,flask模組預設埠號為5000 程式碼如下: from flask import Flask app = Flask(_

live555 實現一個簡單的RTSP伺服器

用live555中的庫寫了一個最簡單的RTSPServer程式,僅用於學習目的。從下例的程式碼中,可以清析的明白RTSPServer的函式呼叫流程。[cpp] view plaincopyprint?#include <BasicUsageEnvironment.h

巧用 Drawable 之實現一個簡單的自定義電池圖示

在 Android 中自定義一個電池圖示,一般是採用自定義 View,在 onDraw 中採用 Canvas 去繪製 Bitmap 或者各種幾何圖形。但是自定義 View 對初學者來說可能會有一點難度,那麼有沒有更簡單的辦法來實現自定義電池圖示呢? 實現電

C語言實現一個簡單的佇列

1、佇列.h #include<stdio.h> #include<stdlib.h> #define N 100 //定義佇列最大多少個 #define datatype char //定義佇列的資料型別 struct

一個Python通過select實現簡單web框架

127.0.0.1 log put lec func select odi block pos 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 import socket 5 import selec

Java實現簡單web server

小背景 在《計算機網路-自頂向下方法》這本書中,第二章應用層有個小的程式設計作業,今天將其實驗並記錄下來。 簡介 在計算機網路應用層中最重要的幾個協議有:HTTP,SMTP,FTP,D

java dynamic web project的一個簡單的例子

環境條件: eclipse Version: Mars.2 Release (4.5.2) tomcat7.0.70 1.eclipse--file--new--other--找到 Dynamic web project 給專案取個名字,比如nova。再選擇配置的serv

java實現一個簡單Web伺服器

Web伺服器也稱為超文字傳輸協議伺服器,使用http與其客戶端進行通訊,基於java的web伺服器會使用兩個重要的類, java.net.Socket類和java.net.ServerSocket類,並基於傳送http訊息進行通訊。 這個簡單的Web伺服器會有以下三個類:

java實現一個簡單的單用戶登陸功能的思路

get 單用戶 這樣的 簡單的 lock ref 數據庫 清除 一個 引用 所謂“單用戶單賬戶登錄”是指:在同一系統中,一個用戶名不能在兩個地方同時登錄。 我們參照 QQ 實現效果:當某賬號在 A 處登錄後,在未退出的情況下,如果再到 B 處登錄,那麽,系統會擠下 A 處

PHP分頁初探 一個簡單的PHP分頁代碼的簡單實現

too 查詢 use img 多少 contain 網站 實現 ice PHP分頁代碼在各種程序開發中都是必須要用到的,在網站開發中更是必選的一項。 要想寫出分頁代碼,首先你要理解SQL查詢語句:select * from goods limit 2,7。PHP分頁代碼核心

Java實現一個簡單的事件監聽器

tro 模型 when rgs sdf span 傳遞 inter pre 關於事件監聽我們需要知道的一些基礎知識。 a)事件三要素: source -- 事件源 when -- 事件發生時間 message -- 事件主題消息

java實現一個簡單的計數器

random imp num count 簡單的 [] dom .com bnu package com.fengunion.sf;import org.junit.platform.commons.util.StringUtils;import java.util.Has

JavaJava實現一個簡單的“檢視檔案的二進位制碼瀏覽器”

一、檢視檔案的二進位制碼     想檢視一個檔案的二進位制碼有很多工具可以用HEX的方式讀檔案,例如:Notepad++、UltraEdit、HexViewer等等。 Notepad++的HEX-Editor:   二、DIY瀏覽器 1.初步實現的瀏覽功能: 軟體採用命

java實現一個簡單的驗證碼生成器

  最近看了網上很多大佬們寫的驗證碼生成,尋思著自己也寫一個,話不多說,程式碼如下:                                &

VC++6.0下用60行程式寫成一個簡單WEB伺服器

文章目錄 一個最簡單的WEB伺服器 HTTP 工作原理概述 HTTP協議通訊過程 源程式分析 過程 原始碼分析 原始碼60行(simplehttpserver.cpp) 編碼過程和