引入
相關概念
-
軟件架構
- C/S:客戶端 / 服務器端
- B/S:瀏覽器 / 服務器端
所謂CS是指 Client—Server(CS架構:客戶端和服務器要分離,分別要開發出來客戶端和服務器)
優勢:傳輸的數據是可以自定義的、傳輸的通道時加密的、對於數據具有更好的安全性
缺點:開發成本大、使用成本大(必須要下載客戶端裝上才能用)
Java不適合做CS架構,做出來的用戶界面奇醜無比
所謂的BS是指 Browser—Server
特點:傳輸使用協議一般是HTTP協議(超文本傳輸協議),而HTTP承載層使用TCP協議,而對於開發人員,要做的事情就是去實現一個前端的界面,讓瀏覽器可以解析出來這個界面就可以了,傳輸的數據不是那麼的安全,傳輸數據的格式是既定的。
優點:開發成本低,特別低、使用成本低,也特別低。
-
資源分類
-
靜態資源:所有用戶訪問後,得到的結果都是一樣的,稱爲靜態資源。靜態資源可以直接被瀏覽器解析。
如:HTML、CSS、JavaScript
-
動態資源:每個用戶 訪問相同資源後,得到的結果可能不一樣,稱爲動態資源。動態資源被訪問後,需要先轉換爲靜態資源,在返回給瀏覽器。
如:servlet、jsp、php、asp
-
-
網絡通信三要素
-
IP:電子設備(計算機)在網絡中的唯一標識
-
端口:應用程序在計算機中的唯一標識。0~65535
-
傳輸協議:規定了數據傳輸的規則(就比如瀏覽器和客戶端交流需要用什麼語言,英語?漢語?)
TCP協議:安全,三次握手,速度慢
UDP協議:不安全,速度快
-
一、Web服務器軟件
引入
服務器:安裝了服務器軟件的計算機
服務器軟件:接受用戶的請求,處理請求,做出響應
Web服務器軟件(也稱:Web容器):接受用戶的請求,處理請求,做出響應
- 在Web服務器軟件中,可以部署Web項目,讓用戶通過瀏覽器訪問這個項目
常見的Java相關的網絡容器
- webLogic(Oracle公司)、webSphere(IBM公司)、JBOSS(JBOSS公司):支持所有的JavaEE規範,收費
- Tomcat:Apache基金組織,中小型JavaEE服務器,僅支持少量的JavaEE規範(如:Servlet、JSP)
1. Tomcat
Tomcat:Web容器
1.1 下載、安裝、啓動、配置、部署
官網:https://tomcat.apache.org/download-80.cgi
根據需求,下載zip壓縮包
下載成功後解壓文件夾即安裝成功!
目錄結構:
啓動
- bin/startup.bat:運行即可
- 訪問:瀏覽器輸入:http://localhost:8080
- 可能遇到的問題
- 黑框一閃而過(JAVA_HOME沒有配置)
正確配置方式
startup.bat是批處理文件,裏面寫的就是dos命令。
catalina.bat中有一條dos命令,使用環境變量的JAVA_HOME,找到JDK,然後才能運行Tomcat。Tomcat是純Java編寫的,他的啓動依賴於電腦上安裝的JDK
**修改端口號(默認是8080):**在conf/server.xml中修改
部署:
-
直接將項目放在webapps目錄下即可。
或者:將項目打包成war包,再將war包放在webapps目錄下。(war包會自動解壓縮)
2. 將Tomcat集成到IDEA中,並且創建JavaEE的項目,部署項目
2.1 手動集成Tomcat
Run—>Edit Configurations
接下來點擊apply就成功了
2.2 創建Web項目
一般Tomcat的啓動都伴隨這Web項目的啓動。所以接下來創建Web項目(創建web項目時其實就會自動集成好了Tomcat)
File—>New—>Project
部署:
虛擬路徑指項目的訪問路徑
熱部署:
二、Servlet
概念:server applet:運行在服務器端的小程序
- Servlet就是一個接口,這個接口定義了Java類被瀏覽器訪問到(Tomcat識別)的規則
將來自定義一個類,實現Servlet接口,覆寫方法。
配置Servlet
寫一個Servlet就要配置一個Servlet
web.xml是Tomcat找到其他類的指路標,然後用類加載反射機制加載這些類,所以要在web-app裏寫好路標(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_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>demo1</servlet-name>
<servlet-class>com.home.java.service.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>demo1</servlet-name>
<url-pattern>/demo1.do</url-pattern>
</servlet-mapping>
</web-app>
1. Tomcat執行Servlet的執行原理:
- 當服務器接受到客戶端瀏覽器的請求後,會解析請求URL路徑,獲取訪問的Servlet的資源路徑
- 查找web.xml文件,看是否有對應的標籤體內容
- 如果有,則在找到對應的全類名
- Tomcat會將字節碼文件加載今內存,並創建其對象
- 調用其方法
如圖:
2. Servlet的生命週期
- init():初始化方法,在Servlet被創建時執行。且只會執行一次
- service():提供服務方法,每一次Servlet被訪問時,執行。執行多次
- destroy():銷燬方法,在服務器正常關閉時,纔會執行。執行一次
package com.home.java.service;
/**
* @author ZAQ
* @create 2020-04-05 18:49
*/
public class ServletDemo1 implements Servlet {
public ServletDemo1() {
System.out.println("我是構造方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("我是init方法");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("我是Service");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
Servlet什麼時候被創建?
-
默認情況下,第一次被訪問時,Servlet被創建
-
但是也可以配置執行Servlet的創建時機
在標籤下配置
-
設置第一次被訪問時創建
<load-on-startup>
的值爲負數 -
設置在服務器啓動時創建
<load-on-startup>
的值爲0或正整數
-
執行順序:先執行ServletDemo1()方法創建對象(構造器),然後執行init()方法,然後是Service()方法
Servlet的init方法只執行一次,說明一個Servlet在內存中只存在一個對象,Servlet是單例的
- 多個用戶同時訪問時,可能存在線程安全問題
- 解決:儘量不要在servlet中定義成員變量。即使定義了成員變量,也不要修改其值
destroy()方法在Servlet被銷燬之前執行,一般用於釋放資源(init()用於加載資源)
3. Servlet註解配置
由於每個Servlet都要在xml文件中配置,過於麻煩,所以引入註解配置,方便快捷
註解配置:只需要在類上面寫@WebServlet("/demo1.do")
即可
路徑定義規則:
- /xxx
- *.do(注意沒有 / )
Tomcat真正訪問的是“Tomcat部署的web項目”,“Tomcat部署的web項目”對應着“工作空間項目”的web目錄下的所有資源。
WEB-INF目錄下的資源不能被瀏覽器直接訪問。
4. Servlet的體系結構
Servlet—接口
- GenericServlet—抽象類(實現了Servlet接口)
- HttpServlet—抽象類(繼承GenericServlet)
GenericServlet:將Servlet接口中的其他的方法做了默認空實現,只將service()方法作爲抽象
HttpServlet:對Http協議的一種封裝,簡化操作
- 定義類繼承HttpServlet
- 覆寫doGet/doPost方法
前端通過form表單發送數據到Servlet中,我們可以通過Servlet中的service()裏的一些操作獲取這些數據。所以service()裏的第一件事就是獲取數據,但是在獲取數據之前要判斷form表單的請求方式。這個過程是繁瑣的,並且是每個Servlet都要完成的操作,所以Sun公司提供了一個HttpServlet類,他幫助我們完成了這些操作,以後我們不再需要寫判斷請求方式的過程,只需要重寫doGet()、doPost()方法即可。
HttpServlet源碼:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();//獲取請求方式
long lastModified;
//判斷是那種請求方式,如果是GET就...如果是Post就...
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader("If-Modified-Since");
} catch (IllegalArgumentException var9) {
ifModifiedSince = -1L;
}
if (ifModifiedSince < lastModified / 1000L * 1000L) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);//如果是GET請求,則調用doGet
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);//如果是Post請求,則調用doPost
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
內容持續更新中…