Servlet

1.Tomcat(Http服務器,Http Container)

1.對下,實現了HTTP協議,服務器端,可以通過網絡和客戶端進行通信
2.對上,是實現了java規定的Servlet協議(Java 規定了幾個interface)Tomcat定義了這些接口的實現類

2.Web應用的文件結構(docBase) 404 問題

WEB-INF web應用下的配置,類文件,依賴文件
—web.xml --XML格式的,用於web應用的配置
class\ 用戶自定義類(業務類)的ClassPath
.calss
lib\一類是
.class文件 一類是.jar文件

3.Tomcat(Servlet)中如何區分不同的web應用(webapp)

1.web app | Context | ServletContext

Tomcat通過URL中的第一部份 Http://127.0.0.1:8080/hello/login
Tomcat通過URL中的後面部份 Http://127.0.0.1:8080/hello/login
Servlet對象(動態文檔 | 動態文檔)
1.根據web.xml中的配置去查找
—1.根據url找到對應的servlet-mapping(映射關係)->servlet
—2.根據servlet名字找到對應的Servlet的類
2.靜態文檔
直接在docBase爲相對路徑查找

4.請求是如何從瀏覽器到你的Servlet的代碼的(動態的說是Servlet的對象)
1.結合網絡2.結合Tomcat的分用邏輯
在這裏插入圖片描述
Tomcat和Servlet的其他重要信息:
1.Servlet(interface)(主要用於TCP|UDP業務的)
–Servlet(interface)下的一個HttpServlet(abstract class)
2.Servlet

init()初始化用的
service()每次提供服務是調用的
destroy()銷燬是使用

Servlrt對象的生命週期:

Tomcat:啓動流程

1.讀取conf下的配置文件
2.監聽8080端口(server.xml)
3.掃描目錄(webapps)
讀取並解析zhaoyanlong\WEB-INF\web-xml
4.進行Servlet對象的初始化
(每一個Servlet類在進程運行過程中有且僅有一個對象:單例模式)
調用Servlet對象的init()方法
5.定義了Map<url,Servlet名稱>
Map<Servlet名稱,Servlet對象>
先使用url獲取,名稱然後再換取到對象。
在這裏插入圖片描述
6.Socket socket =ss.accpet();
爲了併發能力,Tomcat使用了多線程處理各個請求
7.每個線程中

1.從socket的inputStream讀取內容
2. 按照HTTP協議,解析請求
3.構造一個HttpServletRequest對象
4.構造一個HttpServletResponse對象
5.根據url找對應的Servlet對象去處理
0.根據url中的第一部分,先確定哪一個context(ROOT)無前綴
1.看是否能根據兩個Map找到對應的Servlet對象
2.再給一個靜態資源的機會,(就是在docBase找文件)
找不到就404了
6.去調用該Servlet對象的service()方法
HttpServlet實現了service方法,根據HTTP方法分別調用
doGET/doPost/doPut/doDelete
7.我們自己做的Servlet中填充response的內容
8.把response按照HTTP協議,發送給socket.outputStream

8.當退出時
遍歷所有的的Servlet對象,調用他們的destroy()方法
總結:對於Servlet對象的生命週期(只有一個Servlet對象)
init()/destroy()只會被調用一次
service()每次服務就會調用一次(會被調用多次)
2.使用service的時候,是在多線程環境下工作(考慮線程安全)

Annotation 註解:@WebServlet()

public @interface MyAnnotation {
}

@MyAnnotation
public class MyMain {
}

使用註解後就可以不需要的web.xml文件中配置,會直接獲取註解中信息。

Servlet API有以下三個java包:

javax.servlet(重點):其中包含定義Servlet和Servlet容器之間的類和接口
javax.servlet.http(重點):其中包含定義HTTP Servlet和Servlet容器之間的類和接口
javax.servlet.annotation:其中包含標註Servlet,Filter,Listener的註解

disable cache 爲了減少服務器的訪問量,會在瀏覽器中有一個緩存池,訪問相同連接,會直接從池中讀信息,需要注意ctrl+F5
如果使用GET方法不能有請求體個人輸入的信息會隨着QueryString一起顯示出來。
使用post的話,會出現在正文中。
測試代碼:
在這裏插入圖片描述

FirstServlet

package com.zhaoyanlong;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<table>");
        out.println("<thead>");
        out.println("<tr>");
        out.println("<th>名稱</th>");
        out.println("<th>值</th>");
        out.println("</tr>");
        out.println("</thead>");
        out.println("<tbody>");
        String method=req.getMethod();
        tr(out, "Method", method);
        String pathInfo = req.getPathInfo();
        tr(out, "PathInfo",pathInfo);
        String pathTranslated = req.getPathTranslated();
        tr(out, "PathTranslated",pathTranslated);
        String contextPath = req.getContextPath();
        tr(out, "ContextPath",contextPath);
        String queryString = req.getQueryString();
        tr(out,"QueryString" ,queryString);
        String requestURI = req.getRequestURI();
        tr(out,"RequestURL" ,requestURI );
        Map<String, String[]> parameterMap = req.getParameterMap();
        for (Map.Entry<String,String[]> entry:parameterMap.entrySet()) {
            for (String val:entry.getValue()) {
                tr(out, entry.getKey(),val);
            }
        }
        System.out.println(req.getParameter("你好"));
        System.out.println(Arrays.toString(req.getParameterValues("你好")));

        Enumeration<String> headerNames = req.getHeaderNames();
        //只要有更多元素就去遍歷
        while (headerNames.hasMoreElements()){
            //我們可以拿到name
            String name=headerNames.nextElement();
            //通過name拿到val  現在拿到的還是數組
            Enumeration<String>heads=req.getHeaders(name);
            while (heads.hasMoreElements()){
                //拿到每一個val
                String val=heads.nextElement();
                tr(out, name,val);
            }
        }
        out.println("</tbody>");
        out.println("</table>");
    }
    private void tr(PrintWriter out,String name,String val){
        out.println("<tr>");
        out.printf("<td>%s</td>",name);
        out.printf("<td>%s</td>",val);
        out.println("</tr>");
    }
}

LoginServlet

package com.zhaoyanlong;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicInteger;
public class LoginServlet extends HttpServlet {
    //統計接口被調用此時
    //結合Servlet的生命週期理解多線程中存在共享變量
    //private int count=0;錯誤

    private AtomicInteger count=new AtomicInteger();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        //請求就是告訴編碼返回時以同類型返回
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out=resp.getWriter();
        out.println("<h1>2020</h1>");
        out.printf("<p>被訪問次數:%d</p>",count.getAndIncrement());
    }
}

SecondServlet

package com.zhaoyanlong;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
    //通過表單來提交
    private void run(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out=resp.getWriter();
        String username=req.getParameter("username");
        String password=req.getParameter("password");
        out.println("<h1>"+req.getMethod()+"</h1>");
        out.println("<p>用戶名:"+username+"</p>");
        out.println("<p>密碼:"+password+"</p>");
    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        run(req,resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        run(req,resp);
    }
}

index.css

h1{
    font-size: 50px;
    color: aqua;
    background: blue;
}

index.js

alert("wansui")

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>LoginServlet</servlet-name>
        <servlet-class>com.zhaoyanlong.LoginServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>LoginServlet</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>
</web-app>

index.html

<!DOCTYPE html>
<html>
<head>
    <title>中華人民</title>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html: char; charset=utf-8"/>
    <script src="js/index.js"charset="UTF-8"></script>
    <link rel="stylesheet"type="text/css"href="css/index.css">
</head>
<body>
<h1>成立l</h1>
<a href="login">站起來</a>
</body>
</html>

Login.html

<!DOCTYPE html>
<html lang="zh-hans">
<head>
    <meta charset="UTF-8">
    <title>登錄</title>
</head>
<body>
<form method="post"action="/second">
    <label for="username">用戶名:</label>
    <input type="text"name="username" placeholder="請填寫用戶名"/>
    <label for="password">密碼:</label>
    <input type="password" name="password" placeholder="請輸入密碼"/>
    <input type="submit"value="登錄"/>
</form>
</body>
</html>

table.html

<meta charset="UTF-8"/>
<table>
    <thead>
    <tr>
        <th>姓名</th>
        <th></th>
    </tr>
    </thead>
    <tbody>
    <tr>
        <td>年齡</td>
        <td>18</td>
    </tr>
    <tr>
        <td>生日</td>
        <td>0101</td>
    </tr>
    <tr>
        <td>愛好</td>
        <td>籃球</td>
    </tr>
    </tbody>
</table>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章