JavaWeb核心知識
JavaWeb
1.基本概念
1.1、前言
web開發:
-
web是網頁的意思
-
靜態web
- html,css
- 提供給所有人看的資料始終不會發生變化
-
動態web
- 提供給所有人看的資料會發生變化,每個人在不同的時間和地點看到的資訊各不相同
在Java中,動態web資源開發的技術統稱為JavaWeb
1.2、web應用程式
web應用程式:
-
可以提供瀏覽器訪問的程式
-
一個web應用可以由多個部分組成(靜態web、動態web)
- html、css、js
- jsp、servlet
- Java程式
- jar包
- 配置檔案(properties…)
-
web應用程式編寫完畢之後,若想提供給外界訪問:需要一個伺服器來統一管理
1.3、靜態web
- *.htm、 *.html這些都是網頁的字尾,如果伺服器上一直存在這些東西,我們就可以直接進行讀取(需要網路)
- 靜態web存在的缺點
- Web頁面無法動態更新,所有使用者看到的都是同一個頁面
- 輪播圖,點選特效:偽動態
- JavaScript[實際開發中,它用的最多]
- VBScript
- 它無法和資料庫互動(資料無法持久化,使用者無法互動)
- Web頁面無法動態更新,所有使用者看到的都是同一個頁面
1.4、動態web
頁面會動態展示:“Web的頁面的展示效果會因人而異”
缺點:
- 假如伺服器的動態web資源出現了錯誤,我們需要重新編寫我們的後臺程式,重新發布,需要停機維護。
優點:
- Web頁面可以動態更新,所有使用者看到的都不是同一個頁面
- 它可以和資料庫互動(資料可以持久化,使用者可以互動)
2.web伺服器
2.1、技術講解
ASP:
- 微軟:國內最早流行的就是ASP
- 在HTML中嵌入了VB的指令碼,ASP+COM
- 在ASP開發中,基本都是在一個頁面開就有幾千行程式碼,頁面極其混亂
- 維護成本高
- 主要運用C#語言
- IIS
PHP:
- PHP開發速度很快,功能很強大,跨平臺,程式碼很簡單
- 無法承載大訪問量的情況(有侷限性)
JSP/Servlet:
- sun公司主推的B/S架構
- 基於Java語言的(所有的大公司或者一些開源的元件都是用Java寫的)
- 可以承載三高(高效能、高併發、高可用)問題帶來的影響
- 語法像ASP,方便學ASP的人轉學JSP,加強了市場的競爭度
2.2、web伺服器
伺服器是一種被動的操作,用來處理使用者的請求和給使用者一些響應資訊
IIS:
微軟的,Windows中自帶的
Tomcat:
Tomcat是Apache 軟體基金會(Apache Software Foundation)的Jakarta 專案中的一個核心專案,最新的Servlet 和JSP 規範總是能在Tomcat 中得到體現。因為Tomcat 技術先進、效能穩定,而且免費,因而深受Java 愛好者的喜愛並得到了部分軟體開發商的認可,成為目前比較流行的Web 應用伺服器。
Tomcat 伺服器是一個免費的開放原始碼的Web 應用伺服器,屬於輕量級應用伺服器,在中小型系統和併發訪問使用者不是很多的場合下被普遍使用,是開發和除錯JSP 程式的首選。對於一個Java初學web的人來說,它是最佳的選擇
訣竅是,當配置正確時,Apache 為HTML頁面服務,而Tomcat 實際上執行JSP 頁面和Servlet。另外,Tomcat和IIS等Web伺服器一樣,具有處理HTML頁面的功能,另外它還是一個Servlet和JSP容器,獨立的Servlet容器是Tomcat的預設模式。不過,Tomcat處理靜態HTML的能力不如Apache伺服器。目前Tomcat最新版本為9.0.37。
下載tomcat:
- 安裝或者解壓
- 瞭解配置檔案和目錄結構
- 這個東西的作用
3.Tomcat
3.1、tomcat安裝
tomcat官網:https://tomcat.apache.org/
3.2、tomcat啟動和配置
資料夾作用:
啟動和關閉tomcat
訪問測試:http://localhost:8080/
可能遇到的問題:
- Java的環境變數沒有配置
- 閃退問題:需要配置相容性
- 亂碼問題:配置檔案中設定
3.3、配置
可以配置啟動的埠號
- tomcat預設埠號:8080
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主機的名稱
- 預設的主機名為:localhost(127.0.0.1)
- 預設存放網站的位置是:webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
問題:
請你談談網站是如何進行訪問的?
-
輸入一個域名然後回車
-
檢查本機的C:\Windows\System32\drivers\etc\hosts配置檔案下有沒有這個域名對映
-
有的話直接返回對應的IP地址,這個地址中,有我們需要訪問的web程式,可以直接訪問
-
沒有的話去DNS伺服器找,找到的話就返回,找不到就返回找不到
-
- 可以配置一下環境變數
3.4、釋出一個web網站
- 將自己寫的網站,放到伺服器(tomcat)中指定的web應用的資料夾(webapps)下,就可以訪問了
網站應該有的結構
--webapps:tomcat伺服器的web目錄
-ROOT
-hzy:網站的目錄名
- WEB-INF
-classes:Java程式
-lib:web應用所依賴的jar包
-web.xml:網站的配置檔案
- index.jsp 預設的首頁
- static
-css
-style.css
-js
-img
- ...
4.HTTP
4.1、什麼是HTTP
HTTP(超文字傳輸協議)是一個簡單的請求-響應協議,它通常執行在TCP之上。
- 文字:html,字串,…
- 超文字:圖片,音樂,視訊,定位,地圖,…
- 預設埠是80
HTTPS:是安全的
- 埠號為443
4.2、兩個時代
- http1.0
- HTTP/1.0:客戶端可以與web伺服器連線,只能獲得一個web資源,第二次連線的話會請求不到(斷開連線)
- http2.0
- HTTP/1.1:客戶端可以與web伺服器連線,可以獲得多個web資源
4.3、HTTP請求
- 客戶端發請求(Request)到伺服器
百度:
Request URL: https://www.baidu.com/ 請求地址
Request Method: GET 請求方法
Status Code: 200 OK 請求狀態碼
Remote Address: 180.101.49.11:443 遠端地址
Referrer Policy: no-referrer-when-downgrade 協議
Accept:text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh,en-US;q=0.9,en;q=0.8,zh-TW;q=0.7,zh-CN;q=0.6
Connection: keep-alive
1、請求行
- 請求行中的請求方式:GET
- 請求方式:GET/POST
- GET:請求能攜帶的引數比較少,大小有限制,會在瀏覽器的URL位址列顯示資料內容,不安全但是高效
- POST:請求能夠攜帶的引數沒有限制,大小沒有限制,會在瀏覽器的URL位址列顯示資料內容,不安全但是不高效
2、請求頭
Accept: 告訴瀏覽器它所支援的資料型別
Accept-Encoding: 支援哪種編碼格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 告訴瀏覽器它的語言環境
Cache-Control: 快取控制
Connection: 告訴瀏覽器是斷開還是保持連線
Host: 表示主機
4.4、HTTP響應
- 伺服器發響應到客戶端
百度:
Cache-Control: private 快取控制
Connection: keep-alive 連線:保持連線
Content-Encoding: gzip 編碼
Content-Type: text/html;charset=utf-8 型別
4.4.1、響應體
Accept: 告訴瀏覽器它所支援的資料型別
Accept-Encoding: 支援哪種編碼格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language: 告訴瀏覽器它的語言環境
Cache-Control: 快取控制
Connection: 告訴瀏覽器是斷開還是保持連線
Host: 表示主機
Refresh: 告訴客戶端,多久重新整理一次
Location: 讓網頁重新定位
4.4.2、響應狀態碼
200:請求響應成功
3xx:請求重定向
- 重定向:你重新到我給你的新位置去
4xx:找不到資源
- 404:資源不存在
5xx:伺服器程式碼錯誤
- 502:閘道器錯誤
問題:
當你的瀏覽器中輸入地址並回車的一瞬間到頁面能夠展示回來,經歷了什麼?
5、Maven
我們為什麼要學習這個技術?
- 在JavaWeb開發中,需要使用大量的jar包,我們需要手動去匯入
- 如何能讓一個東西自動幫我們匯入和配置這個jar包
由此,maven誕生了
5.1、maven專案架構管理工具
我們目前用它來方便匯入jar包的
Maven的核心思想:約定大於配置
- 有約束,不要去違反
Maven會規定好你該如何去編寫我們的Java程式碼,必須要按照這個規範來
5.2、下載安裝maven
maven官網:https://maven.apache.org/
下載完成後解壓即可
5.3、配置環境變數
在我們的系統環境變數中
配置如下配置:
- M2_HOME maven目錄下的bin目錄
- MAVEN_HOME maven的目錄
- 在系統的path中配置%MAVEN_HOME%\bin
測試maven是否安裝成功,保證必須配置完畢
5.4、阿里雲映象
-
映象:mirrors
- 作用:加速我們的下載
-
國內建議使用阿里雲的映象
把阿里雲映象的配置配置到maven的配置檔案下面
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
5.5、本地倉庫
**建立一個本地倉庫:**localRepository
<localRepository>E:\apache-maven-3.6.1-bin\apache-maven-3.6.1-bin\repository</localRepository>
5.6、在IDEA中使用Maven
- 啟動IDEA
- 建立一個maven的web專案
- 等待專案初始化完畢
- 觀察maven倉庫中多了什麼
- IDEA中的maven設定
注意:IDEA專案建立成功後要記得看一眼maven的配置
- 到這裡,maven在IDEA中的配置和使用就可以了
5.7、建立一個普通的Maven專案
這個只有在web應用下才會有
5.8、在IDEA中標記資料夾功能
5.9、在IDEA中配置tomcat
解決警告問題:
為什麼會有這個問題:我們訪問一個網站,需要指定一個資料夾的名字
必須要的配置
5.10、pom檔案
pom.xml是maven的核心配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<!--Maven版本和標頭檔案-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 這裡就是我們剛才配置的GAV-->
<groupId>com.czu</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 專案的打包方式-->
<!-- jar:Java應用的打包方式-->
<!-- war:JavaWeb應用的打包方式-->
<packaging>war</packaging>
<name>javaweb-01-maven Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<!-- 配置-->
<properties>
<!-- 預設的專案構建編碼-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 編碼版本-->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<!-- 專案依賴-->
<dependencies>
<!-- 具體依賴的jar包配置檔案-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 專案構建用的東西-->
<build>
<finalName>javaweb-01-maven</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
maven的高階之處在於,maven會幫你匯入這個jar包所依賴的其他jar包
maven由於它的約定大於配置,我們之後可能會遇到我們寫的配置檔案無法被匯出或者生效的問題
<!--在build中配置resources,來防止我們資源匯出失敗的問題-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
6、Servlet
6.1、Servlet簡介
- Servlet就是sun公司開發動態web的一門技術
- Sun公司在這些API中提供了一個介面叫做:Servlet,如果你想開發一個Servlet程式,只需要完成兩個小步驟:
- 編寫一個類,實現Servlet介面
- 把開發好的Java類部署到web伺服器中
把實現了Servlet介面的Java程式叫做Servlet
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ftfQwkn8-1600912482281)(web的基本概念.assets/未命名檔案 (17)].png)
6.2、HelloServlet
Servlet介面Sun公司有兩個預設的實現類:HttpServlet,GenericServlet
-
構建一個普通的maven專案,刪掉裡面的src目錄,之後就在這個裡面建立moudle,這個空的工程就是maven的主工程
-
關於maven父工程的理解:
父專案中會有:
<modules> <module>servlet-01</module> </modules>
子專案中會有:
<parent> <artifactId>javaweb-02-servlet</artifactId> <groupId>com.czu</groupId> <version>1.0-SNAPSHOT</version> </parent>
父專案中的jar包,子專案可以直接使用
-
maven環境優化
- 修改web.xml為最新的
- 將maven的結構搭建完整
-
編寫一個servlet程式
- 編寫一個普通類
- 實現servlet介面,這裡我們直接繼承HttpServlet
package com.czu.servlet;
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;
/**
* @author 87682
*/
public class HelloServlet extends HttpServlet {
/**
* 由於get或者post只是請求實現的方式不同,可以相互呼叫,業務邏輯都一樣
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletInputStream inputStream = req.getInputStream();
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();
writer.print("Hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
-
編寫Servlet的對映
為什麼需要對映:我們寫的是Java程式,但是要通過瀏覽器訪問,而瀏覽器需要連線web伺服器,所以我們需要在web伺服器中註冊我們寫的Servlet,還需要給他一個瀏覽器能夠訪問的路徑
<?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>
<servlet-name>hello</servlet-name>
<servlet-class>com.czu.servlet.HelloServlet</servlet-class>
</servlet>
<!-- Servlet的請求路徑-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
-
配置tomcat
-
啟動測試
6.3、Servlet原理
Servlet是由Web伺服器呼叫,web伺服器在收到瀏覽器請求之後,會:
6.4、Mapping問題
-
一個Servlet可以指定一個對映路徑
<!-- Servlet的請求路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
一個Servlet可以指定多個對映路徑
<!-- Servlet的請求路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello1</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello4</url-pattern> </servlet-mapping>
-
一個Servlet可以指定通用對映路徑
<!-- Servlet的請求路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
-
預設請求路徑
<!-- Servlet的請求路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
-
指定一些字首或者字尾等等
<!-- 可以自定義字尾實現請求對映,注意*前面不能加專案對映的路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
-
優先順序問題
指定了固有的對映路徑優先順序最高,如果找不到就會走預設的處理請求
6.5、ServletContext
web容器在啟動的時候,它會為每一個web程式都建立一個對應的ServletContext物件,它代表了當前的web應用
1.共享資料
我在這個Servlet中儲存的資料,可以在另外一個Servlet中拿到
package com.czu.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 87682
*/
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter() 初始化引數
//this.getServletConfig() Servlet配置
//this.getServletContext() Servlet上下文
ServletContext servletContext = this.getServletContext();
String username = "印潤章";
//將一個資料儲存在了ServletContext中,名字為username,值為username
servletContext.setAttribute("username",username);
System.out.println("hello");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
package com.czu.servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 87682
*/
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String username = (String) servletContext.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("名字" + username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
<?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>hello</servlet-name>
<servlet-class>com.czu.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getContext</servlet-name>
<servlet-class>com.czu.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getContext</servlet-name>
<url-pattern>/getContext</url-pattern>
</servlet-mapping>
</web-app>
2.獲取初始化引數
<!-- 配置一些web應用初始化引數-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
resp.getWriter().print(url);
}
3.請求轉發
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
// //獲取轉發的請求路徑
// RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher("/getParams");
// //呼叫forward方法實現請求轉發
// requestDispatcher.forward(req,resp);
servletContext.getRequestDispatcher("/getParams").forward(req,resp);
}
4.讀取資原始檔
Properties
- 在java目錄下新建properties
- 在resources目錄下新建properties
發現:都被打包到了同一個路徑下:classes,我們俗稱這個路徑為classpath
思路:需要一個檔案流
username=root
password=123456
package com.czu.servlet;
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.InputStream;
import java.util.Properties;
/**
* @author 87682
*/
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().print(username + ":" + password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
訪問測試即可
6.6、HttpServletResponse
web伺服器接收客戶端的http請求,針對這個請求分別建立一個代表請求的HttpServletRequest物件,代表響應的HttpServletResponse物件
- 如果要獲取我們客戶端請求過來的引數:找HttpServletRequest
- 如果要給客戶端響應一些資訊:找HttpServletResponse
1、簡單分類
負責向瀏覽器傳送資料的方法:
-
ServletOutputStream getOutputStream() throws IOException; PrintWriter getWriter() throws IOException;
負責向瀏覽器傳送響應頭的方法:
-
void setCharacterEncoding(String var1); void setContentLength(int var1); void setContentLengthLong(long var1); void setContentType(String var1); void setDateHeader(String var1, long var2); void addDateHeader(String var1, long var2); void setHeader(String var1, String var2); void addHeader(String var1, String var2); void setIntHeader(String var1, int var2); void addIntHeader(String var1, int var2);
響應的狀態碼:
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
2、下載檔案
- 向瀏覽器輸出訊息
- 下載檔案
- 要獲取下載檔案的路徑
- 下載的檔名是啥?
- 設定想辦法讓瀏覽器能夠支援下載我們需要的東西
- 獲取下載檔案的輸入流
- 建立緩衝區
- 獲取OutputStream物件
- 將FileOutputStream流寫入到buffer緩衝區
- 使用OutputStream將緩衝區中的資料輸出到客戶端
package com.czu.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
/**
* @author 87682
*/
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 要獲取下載檔案的路徑
String realPath = "F:\\javaweb02servlet\\response\\target\\classes\\1.png";
System.out.println("獲取到的要下載檔案的路徑:" + realPath);
// 2. 下載的檔名是啥?
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3. 設定想辦法讓瀏覽器能夠支援下載我們需要的東西,讓URLEncoder.encode去編碼中文
resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
// 4. 獲取下載檔案的輸入流
FileInputStream fis = new FileInputStream(realPath);
// 5. 建立緩衝區
int len = 0;
byte[] buffer = new byte[1024];
// 6. 獲取OutputStream物件
ServletOutputStream os = resp.getOutputStream();
// 7. 將FileOutputStream流寫入到buffer緩衝區
// 8. 使用OutputStream將緩衝區中的資料輸出到客戶端
while ((len = fis.read(buffer)) >0) {
os.write(buffer, 0, len);
}
os.close();
fis.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
3、驗證碼功能
驗證碼怎麼來的?
- 前端實現
- 後端實現,需要用到Java的圖片類,生成一個圖片
package com.czu.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* @author 87682
*/
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何讓瀏覽器3s自動重新整理一次
resp.setHeader("refresh", "3");
//在記憶體中建立一個圖片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//得到圖片
Graphics2D graphics = (Graphics2D) image.getGraphics();
//設定圖片的背景顏色
graphics.setColor(Color.white);
graphics.fillRect(0, 0, 80, 20);
//給圖片寫資料
graphics.setColor(Color.blue);
graphics.setFont(new Font(null, Font.BOLD, 20));
graphics.drawString(makeNum(), 0, 20);
//告訴瀏覽器這個請求用圖片的方式開啟
resp.setContentType("image/jpeg");
//網站存在快取,不讓瀏覽器快取
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
//把圖片寫給瀏覽器
ImageIO.write(image, "jpg", resp.getOutputStream());
}
private String makeNum() {
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
stringBuffer.append("0");
}
num = stringBuffer.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4、實現重定向
一個web資源收到客戶端請求後,他會通知客戶端去訪問另外一個web資源,這個過程叫重定向
void sendRedirect(String var1) throws IOException;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Location", "/r/image");
resp.setStatus(302);
resp.sendRedirect("/r/image");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
面試題:請你聊聊重定向和轉發的區別?
相同點:
- 頁面都會實現跳轉
不同點:
- 請求轉發的時候,url不會發生變化
- 重定向時候,url位址列會發生變化
6.7、HttpServletRequest
HttpServletRequest代表客戶端的請求,使用者通過Http協議訪問伺服器,Http請求中的所有資訊會被封裝到HttpServletRequest中,通過HttpServletRequest中的方法可以獲取客戶端的所有資訊
1、獲取前端傳遞的引數
7、Cookie、Session
7.1、會話
**會話:**使用者開啟一個瀏覽器,點選了很多超連結,訪問了多個web資源,關閉瀏覽器,這個過程可以稱之為會話
**有狀態會話:**一個人訪問過這個瀏覽器,下次再訪問這個瀏覽器,瀏覽器會知道做個人曾經訪問過這個網頁,稱之為有狀態會話
一個網站,怎麼證明你來過?
客戶端 服務端
- 服務端給客戶端一個信件,客戶端下次訪問帶上信件就可以了,這個信件就是cookie
- 服務端登記你來過了,下次你來的時候再匹配你,這個登記的資訊就是session
7.2、儲存會話的兩種技術
cookie
- 一種客戶端技術(響應、請求)
session
- 伺服器技術,利用這個技術,可以儲存使用者的會話資訊,我們可以把資料或者資訊放在session中
7.3、Cookie
- 從請求中拿到cookie資訊
- 伺服器響應給客戶端cookie
//獲得cookie
Cookie[] cookies = req.getCookies();
//獲得cookie中的key
cookie.getName()
//獲得cookie中的value
cookie.getValue()
//新建一個cookie
new Cookie("lastLoginTime", System.currentTimeMillis() + "")
//設定cookie的有效期
cookie.setMaxAge(24 * 60 * 60);
//響應給客戶端一個cookie
resp.addCookie(cookie);
cookie:一般會儲存在本地的使用者目錄下appdata
一個網站cookie是否存在上限
- 一個Cookie只能儲存一個資訊
- 一個web站點可以給瀏覽器傳送多個Cookie,最多存放20個cookie
- Cooke大小有限制為4kb
- 瀏覽器Cookie上限大概為300個
刪除Cookie:
- 不設定有效期,關閉瀏覽器,自動失效
- 設定有效時間為0
7.4、Session(重點)
什麼是session:
- 伺服器會給每一個使用者(瀏覽器)建立一個session
- 一個session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個session就存在
- 使用者登入之後,整個網站都可以訪問 --> 儲存使用者的資訊;儲存購物車的資訊
cookie和session的區別:
- Cookie是把使用者的資料寫給使用者的瀏覽器,瀏覽器儲存,可以儲存多個
- Session把使用者的資料寫到使用者獨佔的session中,伺服器端儲存,儲存重要的資訊,減少伺服器資源的浪費
- Session物件由伺服器建立
使用場景:
- 儲存一個登入使用者的資訊
- 購物車資訊
- 整個網站中經常使用的資料,我們會把它儲存在session中
使用session:
package com.czu;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @author 87682
*/
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解決亂碼問題
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html:charset=utf-8");
//得到session
HttpSession session = req.getSession();
//給session中存東西
session.setAttribute("name", "hzy");
//獲取session的id
String sessionId = session.getId();
//判斷session是不是新建立的
if (session.isNew()) {
resp.getWriter().write("session建立成功,id為:" + sessionId);
}else {
resp.getWriter().write("session已經在伺服器中存在了" + sessionId);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
//得到session
HttpSession session = req.getSession();
Person person = (Person)session.getAttribute("name");
//移除session中的資料
session.removeAttribute("name");
//手動登出session
session.invalidate();
會話自動過期:web.xml配置
<!-- 設定session的預設失效時間-->
<session-config>
<!-- 15分鐘後session自動失效,以分鐘為單位-->
<session-timeout>15</session-timeout>
</session-config>
相關文章
- flask核心知識Flask
- JavaSE核心知識Java
- 初識JavaWEBJavaWeb
- Objective-C 核心知識Object
- Java 核心知識點整理Java
- RabbitMQ必備核心知識MQ
- Docker 核心知識回顧Docker
- javaweb基本知識JavaWeb
- JavaWeb知識梳理JavaWeb
- JavaWeb知識點JavaWeb
- ES6核心知識總結
- 理解JavaScript的核心知識點:作用域JavaScript
- 一文吃透Tomcat核心知識點Tomcat
- 詳解 MySQL 面試核心知識點MySql面試
- Nginx 實戰核心知識點整理(上)Nginx
- JavaWeb基礎知識點JavaWeb
- Cocos Creator 3.8.x bundle核心知識點
- 初識Javaweb之Servlet以及TomcatJavaWebServletTomcat
- Vue核心知識-Vue的元件之render函式Vue元件函式
- Java核心知識體系6:集合框架詳解Java框架
- 專案管理PRINCE2核心知識點整理專案管理
- Java核心知識1:泛型機制詳解Java泛型
- 走進JavaWeb技術世界1:JavaWeb的由來和基礎知識JavaWeb
- 【Redis核心知識】實現秒殺的三種方案Redis
- 值得收藏的:Mysql資料庫核心知識彙總MySql資料庫
- Nginx核心知識100講-陶輝-極客時間Nginx
- javaweb-ajax和json基礎知識JavaWebJSON
- 對JAVAWEB相關知識的學些JavaWeb
- Vue核心知識-computed和watch的使用場景和方法Vue
- 2019年Spring核心知識點整理,看看你掌握了多少?Spring
- PHP 核心知識點(一)異常和錯誤處理PHP
- c++11-17 模板核心知識(二)—— 類别範本C++
- c++11-17 模板核心知識(八)—— enable_if<>與SFINAEC++
- FPGA的時鐘IP核知識點FPGA
- 長沙Java培訓:Java架構師核心知識點分享Java架構
- Redis 麵霸篇:高頻問題橫掃核心知識點Redis
- c++11-17 模板核心知識(九)—— 理解decltype與decltype(auto)C++
- Java核心知識體系7:執行緒安全性討論Java執行緒