中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Apache軟件基金會核心項目Tomcat的那些事

發布時間:2020-08-04 05:19:03 來源:網絡 閱讀:156 作者:qq593e097eaab3c 欄目:開發技術

Tomcat 服務器是一個免費的開放源代碼的Web 應用服務器,屬于輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和調試JSP 程序的首選。今天就來為大家介紹一下關于Tomcat的詳細內容。

Apache軟件基金會核心項目Tomcat的那些事
聲明:
1:本系列僅記錄本人讀<<深入剖析Tomcat>>此書的一些感悟,不足之處,留言指正,不勝感激。2:本系列所有代碼參照<<深入剖析Tomcat>>,不對之處,留言指正,不勝感激。
概念:傳送門:tomcat百度百科,這里說一個點,tomcat是輕量級的javaweb服務器,用于處理servlet/jsp等動態網頁,雖說也可以處理靜態網頁,但相比apache而言還是遜色不少。有興趣的朋友可以另行了解一下 nginx, iis,apache等其他較為流行的web服務器。
使用過tomcat的朋友應該知道,當java web項目部署到tomcat后,在瀏覽器地址欄里輸入:http://localhost:8080/資源路徑,便可以訪問項目資源。在這一過程中,tomcat扮演調度中心的角色,接收瀏覽器發起資源請求并解析,根據解析結果分發給指定web項目處理,然后根據處理結果,對瀏覽器響應。對此,我們來研究一下,tomcat是怎么做到的。
項目結構:

MyTomcat
接收請求(Request)
想接收瀏覽發起的請求,需要做幾手準備, 1:監聽端口(8080), 2:接收瀏覽器連接(socket連接) 3:解析HTTP請求數據。下面是代碼模擬:

第一第二步: 使用httpServer模擬tomcat調度中心
/**
 * 模擬tomcat的核心類
 */public class HttpServer {
    //tomcat項目絕對路徑, 所有web項目都丟在webapps目錄下
    public static final String WEB_ROOT =
            System.getProperty("user.dir") + File.separator  + "webapps";
    // 模擬tomcat關閉命令
    private static final String SHUTDOWN_CMD = "/SHUTDOWN";
    private boolean shutdown = false;
    //持續監聽端口
    @SuppressWarnings("resource")
    public void accept() {
        ServerSocket serverSocket = null;
        try {
            // 啟動socket服務, 監聽8080端口,
            serverSocket =  new ServerSocket(8080, 1, InetAddress.getByName("127.0.0.1"));
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("啟動myTomcat服務器失敗:" + e.getMessage(), e);
        }
        // 沒接收到關閉命令前一直監聽
        while (!shutdown) {
            Socket socket = null;
            InputStream in = null;
            OutputStream out = null;
            try {
                // 接收請求
                socket = serverSocket.accept();
                in = socket.getInputStream();
                out = socket.getOutputStream();
                // 將瀏覽器發送的請求信息封裝成請求對象
                Request request = new Request(in);
                request.parseRequest();
                // 將相應信息封裝相應對象
                //此處簡單響應一個靜態資源文件
                Response response = new Response(out);
                //模擬頁面跳轉
                response.sendRedircet(request.getUri());
                socket.close();
                //如果是使用關閉命令,停止監聽退出
                shutdown = request.getUri().equals(SHUTDOWN_CMD);
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
        }
    }
    public static void main(String[] args) {
        new HttpServer().accept();
    }
}
第三步,使用HttpReqeust封裝請求相關信息
/**
 * 請求信息封裝對象
 */public class Request {
    // 瀏覽器socket連接的讀流
    private InputStream in;
    //請求行信息信息中的uri
    private String uri;
    public Request(InputStream in) {
        this.in = in;
    }
    // 解析瀏覽器發起的請求
    public void parseRequest() {
        // 暫時忽略文件上傳的請求,假設都字符型請求
        byte[] buff = new byte[2048];
        StringBuffer sb = new StringBuffer(2048);
        int len = 0;
        //請求內容
        try {
            len = in.read(buff);
            sb.append(new String(buff, 0, len));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.print(sb.toString());
        //解析請求行中uri信息
        uri = this.parseUri(sb.toString());
    }

    /**tomcat接收瀏覽器發起的請求是居于http協議的,請求內容格式:*/
    /**請求行:請求方式   請求uri 協議版本*/
    //GET /index HTTP/1.1    
    /**請求頭:以key-value形式存在*/
    //Host: localhost:8080
    //Connection: keep-alive
    //Upgrade-Insecure-Requests: 1
    //User-Agent: Mozilla/5.0 .........
    //Accept: text/html,application/xhtml+xml......
    //Accept-Encoding: gzip, deflate, br
    //Accept-Language: zh-CN,zh;q=0.9
    //Cookie: .....
    /**請求體: 請求頭回車格一行就是請求體,get方式請求體為空*/
    public String parseUri(String httpContent) {
        //傳入的內容解析第一行的請求行即可:
        //請求行格式:  請求方式   請求uri 協議版本     3個內容以空格隔開
        int beginIndex = httpContent.indexOf(" ");
        int endIndex;
        if(beginIndex > -1) {
            endIndex = httpContent.indexOf(" ", beginIndex + 1);
            if(endIndex > beginIndex) {
                return httpContent.substring(beginIndex, endIndex).trim();
            }
        }
        return null;
    }

    public String getUri() {
        return uri;
    }
}
假設,瀏覽器發起請求:http://localhost:8080/hello/index.html HttpServer中socket通過輸入流獲取到的數據是:
GET /hello/index.html HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: Hm_lvt_aa5c701f4f646931bf78b6f40b234ef5=1516445118,1516604544,1518416964,1518497222; JSESSIONID=79367FD9A55B9B442C4ED112D10FDAC5
HttpServer 將上述的數據交于HttpRequest對象處理,該對象調用parseRequest解析,獲取請求行中的uri 數據, 分析該數據, 得到上下文路徑,項目名,資源名。統稱資源路徑。
上面數據得到: hello 項目下, index.html 資源(沒有上下文路徑)
響應請求
當從請求信息中獲取uri后,進而獲取到hello 項目, index.html資源, 響應請求就可以簡單認為根據資源路徑查找資源,如果找到,使用socket output流直接輸出資源數據即可,如果找不到,輸出404信息。

 * 處理響應請求對象
public class Response {
    // 瀏覽器socket連接的寫流
    private OutputStream out;

    public Response(OutputStream out) {
        this.out = out;
    }
    public OutputStream getOutputStream() {
        return out;
    }
    //跳轉
    public void sendRedircet(String uri) {

        File webPage = new File(HttpServer.WEB_ROOT, uri);
        FileInputStream fis = null;
        StringBuffer sb = new StringBuffer();
        try {
            //找得到頁面是
            if(webPage.exists()&& webPage.isFile()) {
                String respHeader = "HTTP/1.1 200 OK\r\n" +
                  "Content-Type: text/html\r\n" +
                  "Content-Length: #{count}\r\n" +
                  "\r\n";
                fis = new FileInputStream(webPage);
                byte[] buff = new byte[2048];
                int len = 0;
                while( (len = fis.read(buff))!= -1) {
                    sb.append(new String(buff, 0, len));
                }
                respHeader=respHeader.replace("#{count}", sb.length()+"");
                System.out.println(respHeader + sb);
                out.write((respHeader + sb).getBytes());

            }else {
                 //頁面找不到時
                String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
                  "Content-Type: text/html\r\n" +
                  "Content-Length: 23\r\n" +
                  "\r\n" +
                  "<h2>File Not Found</h2>";
                out.write(errorMessage.getBytes());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

此處注意, 響應請求數據也必須遵循http協議。
對于Tomcat,還有很多內容需要研究,如果大家對此感興趣的話,不妨和我們一起,繼續探索。現在就關注我們,我們繼續深入探索Tomcat。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大庆市| 扶余县| 平顶山市| 洛南县| 怀安县| 宁陕县| 温宿县| 瑞昌市| 重庆市| 阜南县| 保靖县| 黔西| 金华市| 双流县| 甘德县| 古交市| 鲁山县| 汝州市| 梁平县| 呼图壁县| 陵川县| 府谷县| 从江县| 西畴县| 西和县| 荣昌县| 当阳市| 海宁市| 肃宁县| 边坝县| 双峰县| 交城县| 皋兰县| 益阳市| 崇礼县| 石棉县| 兰溪市| 墨脱县| 广宗县| 安远县| 汉源县|