web到service簡單原理例子

露水上的青蛙發表於2017-09-23

這是目前的理解

附上服務端原始碼

package com.lsw.server;

import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
/*
 * 關於伺服器,除了httpServer1類,還定義了一個Servlet介面,這個介面有一個init()和一個service()方法
 * init()方法為初始化方法,當HTTPServer1類建立了該介面的類的一個例項後,就會立即呼叫該例項的init()方法
 * service()方法:使用者響應HTTP的請求,產生具體的HTTP響應結果。
 * HTTPServer1伺服器在響應HTTP請求時會呼叫servlet介面的特定類的service()方法
 * 所謂web伺服器動態執行程式程式碼。在這個例子中就是指httpServer1在執行時動態載入Servlet介面的實現類,建立他的例項。然後呼叫他的相關方法。
 * HTTPServer1在其實現中利用了java語言的動態載入類的功能
 */
//動態執行
public class HTTPServer1 {
    //存放selvlet例項的快取
    private static Map servletCache = new HashMap();
    
    public static void main(String[] args){
        int port;
        ServerSocket serverSocket;
        
        try{
            port = Integer.parseInt(args[0]);
            System.out.println("預設埠是: " + port);
        }
        catch(Exception e){
            System.out.println("預設埠8080");
            port = 8080;
        }
        
        try{
            //建立監聽埠
            serverSocket = new ServerSocket(port);
            System.out.println("伺服器正在監聽埠: " + serverSocket.getLocalPort());
            while(true){
                try{
                    //等待客戶的連結請求
                    final Socket socket = serverSocket.accept();
                    System.out.println("建立了一個與客戶的新的TCP連線,該客戶的地址為: " + socket.getInetAddress()
                            + " 埠為 : " + socket.getPort());
                    //響應客戶請求
                    service(socket);
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }   
            
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public static void service(Socket socket) throws Exception{
        //讀取HTTP請求資訊
        InputStream socketIn = socket.getInputStream(); //獲得輸入流
        //睡眠500毫秒,等待http請求
        Thread.sleep(500);
        int size = socketIn.available();
        byte[] buffer = new byte[size];
        socketIn.read(buffer);
        String request = new String(buffer);
        //列印http請求資料
        System.out.println("客戶端請求的資料為: " +request);
        
        //解析http請求
        //獲得http請求第一行
        String firstLineOfRequest = request.substring(0,request.indexOf("\r\n"));
        System.out.println("firstLineOfRequest= " +firstLineOfRequest);
        //解析http請求的第一行
        String[] parts = firstLineOfRequest.split(" ");
        //解析http請求這種的uri
        String uri = parts[1];
        System.out.println("解析http請求這種的uri=" + uri);
        System.out.println("截圖的值為=" + uri.substring(0, 1).toString());
        String flag = uri.substring(0, 1).toString();
        if(flag.equals("/")){
            System.out.println("此請求是從瀏覽器發起的請求");
            uri = uri.substring(1).toString();
        }
           
        System.out.println("解析http請求這種的uri=" + uri);
        
        //如果請求呼叫servlet,則動態呼叫servlet的service方法
        if(uri.indexOf("HttpTest") != -1){
            //獲得servlet的名字
            String servletName = null;
            if(uri.indexOf("?") != -1)
                servletName = uri.substring(uri.indexOf("HttpTest/")+8, uri.indexOf("?"));
            else
                servletName = uri.substring(uri.indexOf("HttpTest/")+8, uri.length());
            flag = "";
            flag = servletName.substring(0, 1).toString();
            if(flag.equals("/")){
                servletName = servletName.substring(1).toString();
            }
            //嘗試從servlet快取中回去servlet物件
            Servlet servlet = (Servlet)servletCache.get(servletName);
            //如果servlet快取在這種不存在servlet物件,則建立他,並把他放在servlet快取中
            if(servlet == null){
                servlet = (Servlet)Class.forName("com.lsw.server."+servletName).newInstance();
                servlet.init();
                servletCache.put(servletName, servlet);
            }
            
            //呼叫servlet的service()方法
            servlet.service(buffer, socket.getOutputStream());
            
            //睡眠1秒等待接收http響應結果
            Thread.sleep(1000);
            socket.close();
            return ;
        }
        
    }

}

介面原始碼

package com.lsw.server;

import java.io.OutputStream;

public interface Servlet {
    public void init() throws Exception;
    public void service(byte[] requestBuffer,OutputStream out) throws Exception;

}

實現類原始碼

package com.lsw.server;

import java.io.OutputStream;

public class HelloServlet implements Servlet {

    @Override
    public void init() throws Exception {
        System.out.println("HelloServlet is inited");

    }

    @Override
    public void service(byte[] requestBuffer, OutputStream out)
            throws Exception {
        String request = new String(requestBuffer);
        //列印http請求資料
        System.out.println("客戶端請求的資料為: " +request);
        
        //解析http請求
        //獲得http請求第一行
        String firstLineOfRequest = request.substring(0,request.indexOf("\r\n"));
        System.out.println("firstLineOfRequest= " +firstLineOfRequest);
        //解析http請求的第一行
        String[] parts = firstLineOfRequest.split(" ");
        //獲得http請求中的請求方式
        String method = parts[0];
        System.out.println("解析http請求方式method=" + method);
        //解析http請求這種的uri
        String uri = parts[1];
        System.out.println("解析http請求這種的uri=" + uri);
        System.out.println("截圖的值為=" + uri.substring(0, 1).toString());
        String flag = uri.substring(0, 1).toString();
        if(flag.equals("/")){
            System.out.println("此請求是從瀏覽器發起的請求");
            uri = uri.substring(1).toString();
        }
           
        System.out.println("解析http請求這種的uri=" + uri);
        
        //獲得請求引數username
        String username = null;
        //如果請求方式為get,則請求引數緊跟http請求的第一行的uri的後面
        if(method.equalsIgnoreCase("get") && uri.indexOf("username=")!=-1){
            //假定uri="servlet/HelloServlet?username=Tom&password=1234"
            //parameters="username=Tom&password=1234"
            String parameters = uri.substring(uri.indexOf("?"),uri.length());
            //parts={"username=Tom","password=1234"}
            parts = parameters.split("&");
            //parts={"username","Tom"}
            parts = parts[0].split("=");
            username = parts[1];
        }
        
        //如果請求方式為POST,則請求引數位於http請求的正文中
        if(method.equalsIgnoreCase("post")){
            int locate = request.indexOf("\r\n\r\n");
            //獲得響應正文
            String content = request.substring(locate+4,request.length());
            if(content.indexOf("username=")!=-1){
                //假定content="username=Tom&password=1234"
                //parts="username=Tom&password=1234"
                parts = content.split("&");
                parts = parts[0].split("=");
                username = parts[1];
            }            
        }
        
        //建立傳送響應的http響應
        //傳送http響應第一行"
        out.write("HTTP/1.1 200 OK\r\n".getBytes());
        //傳送http響應頭
        out.write("Content-Type:text/html\r\n\r\n".getBytes());
        //傳送http響應正文
        out.write("<html><head><title>HelloWorld</title></head></body>".getBytes());
        out.write(new String("<h1>Hello:" + username + "</h1></body></head></html>").getBytes());
    }

}

 

相關文章