JavaWeb
java web
1、基本概念
1.1前言
web開發:
- web,網頁的意思 ,www.baidu.com
- 靜态web
- html css
- 提供給所有人看的資料始終不會發生變化!
- 動态web
- 提供給所有人看的資料始終會發生變化!每個人在不同時間不同地點看到的東西,各不相同。-
- 淘寶 ,幾乎所有的網站
- 技術棧:servlet/JSP ASP PHP
在java中,動态資源開發的技術統稱為Javaweb;
1.2web應用程式
web應用程式:指的是可以提供浏覽器通路的。
- a.html b.html....多個web資源,這些web資源可以被外界通路,對外界提供服務
- 你們能通路到的任何一個頁面或者資源,都存在于這個世界的某一個角落的計算機上
- URL
- 這個統一的web資源會被放在同一個檔案夾下,web應用程式-->Tomcat:伺服器
- 一個web應用由多部分組成(靜态web、動态web)
- 。html, CSS, is
- jsp, senvlet
- Java程式
- jar包
- 配置檔案(Properties)
web應用程式編寫完畢後,若想提供給外界通路需要一個伺服器來統一管理:
1.3靜态web
- *.htm *html 這些都是網頁的字尾,如果伺服器上一直存在這些東西,我們就可以直接進行讀取。
JavaWeb - 靜态web存在的缺點
- web頁面無法動态更新,所有使用者看到的都是同一個頁面
- 輪播圖,點選特效:微動态
- JavaScript[實際開發中,他用的最多]
- VBScript
- 他無法與資料庫互動(資料無法持久化,使用者無法互動)
- web頁面無法動态更新,所有使用者看到的都是同一個頁面
1.4動态web
頁面回動态展示:“Web展示的效果因人而異”;
缺點
- 假如伺服器的動态web資源出現了錯誤,我們需要重新編寫我們的背景程式,重新釋出;
- 停機維護
優點:
- web頁面可以動态更新,所有使用者看到的都不是同一個頁面
- 他可以與資料庫互動(資料無法持久化,使用者無法互動)
2、web伺服器
2.1技術講解
ASP
- 微軟:國内最早流行的就是ASP
- 在HTML中嵌入了VB的腳本,ASP + COM;
- 在ASP開發中,基本上一個頁面都有幾千行的業務代碼,頁面機器混亂
<h1> <h1> <h1> <% System.out.println("hello") %> </h1> </h1> </h1>
- 維護成本高
- c#
php
- PHP開發速度很快,功能強大,跨平台,代碼很簡單(70%)
- 無法承載大通路量的情況(局限性)
JSP(servlet):
- sun公司主推的B/S架構
- 基于java語言(所有的大公司,或者一些開源的元件都是用java寫的)
- 可以承載三高(高并發,高可用,高性能)帶來的影響
- 文法像ASP,友善讓ASP轉JSP,加強市場強度;
2.2 web伺服器
伺服器是一種被動的操作,用來處理使用者的一些請求和給使用者一些響應。
lls
微軟的;ASP...Windows中自帶的
tomcat
面向百度程式設計
Tomcat是Apache 軟體基金會(Apache Software Foundation)的Jakarta 項目中的一個核心項目,由Apache、Sun 和其他一些公司及個人共同開發而成。由于有了Sun 的參與和支援,最新的Servlet 和JSP 規範總是能在Tomcat 中得到展現,Tomcat 5支援最新的Servlet 2.4 和JSP 2.0 規範。因為Tomcat 技術先進、性能穩定,而且免費,因而深受Java 愛好者的喜愛并得到了部分軟體開發商的認可,成為目前比較流行的Web 應用伺服器。
Tomcat 伺服器是一個免費的開放源代碼的Web 應用伺服器,屬于輕量級應用伺服器,在中小型系統和并發通路使用者不是很多的場合下被普遍使用,是開發和調試JSP 程式的首選。對于一個java初學web初學者來說,是最佳選擇
Tomcat 實際上運作JSP 頁面和Servlet。
......
工作3-5年之後,可以嘗試手寫tomcat
下載下傳tomcat:
- 安裝or解壓
- 了解配置檔案及目錄結構
- 這個東西的作用
3、Tomcat
3.1安裝tomcat
tomcat官網 :https://tomcat.apache.org/download-10.cgi
解壓安裝
3.2Tomcat 啟動和配置
檔案夾作用:
啟動tomcat
可能遇到的問題:
這裡發現我之前電腦中有,是以删掉了原來的重新配置
注意:要根據自己的JDK版本選擇Tomcat的版本。
建立系統環境變量:
CATALINA_HOME:D:\soft\apache-tomcat-10.0.10
在path中添加
%CATALINA_HOME%\bin;
本文的解決方法是剛安裝好tomcat後就無法正常運作的情況。不涉及項目
安裝tomcat有兩種方式,一個是解壓縮版本,一個是安裝版,當出現這個問題時一般為解壓縮版本才出現
提示錯誤如下:localhost:8080 java.lang.IllegalStateException: No output folder
原因:沒有讀寫的權限
解決方案:找到你tomcat的目錄,右鍵“屬性--->安全--->編輯”,找到Users,将“完全控制”選項“允許”打鈎,應用。
然後http://localhost:8080/,這樣就可以了。
3.3配置
可以配置啟動的端口号
- tomcat的預設端口号為: 8080
- mysql: 3306
- http: 80
- https: 443
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主機的名稱,或者通路的檔案夾webapps
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
- 預設的主機名為:localhost-> 127.0.0.0
- 預設網站應用的存放位置:webapps
- 如果要改localhost還需要去C:\Windows\System32\drivers\etc這個檔案夾下寫一下
高難度面試題:
請你談談網站是如何進行通路的!
- 輸入一個域名;回車
-
檢查本機的C:\Windows\System32\drivers\etc\hosts配置檔案下有沒有被這個域名映射;
1.有:直接傳回對應的ip位址,這個位址中,有我們需要通路的web程式,是以可以直接通路
2.沒有:去DNS伺服器,找到就傳回127.0.0.1 www.qinjiang.com
JavaWeb
3.4釋出一個web網站
不會就先模仿
- 将自己寫的網站,放到伺服器tomcat中指定的web 應用的檔案夾(webapps)
網站應該有的結構
--webapps: tomcat伺服器的web目錄
--root
--kuangstudy :網站的目錄名
- WEB-INF
-classes:java程式
-lib:web應用所依賴的jar包
-web.xml
-index.html預設的首頁
- static
-css
-style.css
-js
-image
-......
4、http
4.1什麼是http
HTTP:超文本傳輸協定(Hyper Text Transfer Protocol)是一個簡單的請求-響應協定,它通常運作在TCP之上。
- 文本:html,字元串,...
- 超文本:圖檔,音樂,視訊,定位,地圖......
- 預設端口 80
Https:安全的
- 端口443
4.2兩個時代
- http1.0
- http/1.0:用戶端可以與web伺服器連接配接後,隻能獲得一個web資源,斷開連接配接
- http 2.0
- http/1.1:用戶端可以與web伺服器連接配接後,隻能獲得多個web資源
4.3http請求
- 用戶端 -- 發請求--伺服器
百度:
Request URL: https://www.baidu.com 請求位址
Request Method: GET get和post方法
Status Code: 200 OK (from memory cache) 狀态碼
Remote Address: 110.242.68.4:443 遠端位址
1、請求行
- 請求行中的請求方式:get
- 請求方式get/post,head,delete,put
- get :請求能夠攜帶的參數比較少,大小有限制,會在浏覽器的URL位址欄顯示資料内容,不安全,但高效
- post :請求能夠攜帶的參數沒有限制,大小沒有限制,不會在浏覽器的URL位址欄顯示資料内容,安全,但不高效
2、請求頭
Accept:告訴浏覽器,它所支援的資料類型
Accept-Encoding:支援哪種編碼格式GBK UTF-8 GB2312 ISO8859-1
Accept-language:告訴浏覽器,它的語言環境
Cache -Control:緩存控制
Connection:告訴浏覽器,請求完成是斷開還是保持連接配接
HOST:主機..../.
4.4http響應
- 伺服器 -- 發請求--用戶端
百度:
Cache-Contro1 :private 緩存控制
Connection :Keep-Alive 連接配接
Content- Encoding:gzip 編碼
Content -Type : text/htm1類型
1.響應體
Accept:告訴浏覽器,它所支援的資料類型
Accept-Encoding:支援哪種編碼格式GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告訴浏覽器,它的語言環境
Cache-Control:緩存控制
Connection:告訴浏覽器,請求完成是斷開還是保持連接配接
HOST:主機..../.
Refresh:告訴用戶端,多久重新整理一次:
Location:讓網頁重新定位
2.響應狀态碼
200:請求響應成功 200
3xx:請求重定向
- 重定向:你重新到我給你新位置去;
4xx:找不到資源 404
- 資源不存在;
5xx: 伺服器代碼錯誤500 502:網關錯誤
常見面試題:
當你的浏覽器中位址欄輸入位址并回車的一瞬間到頁面能夠展示的回來,經曆了什麼?
5、maven
我為什麼要學習這個技術?
- 在javaweb開發中,需要使用大量的jar包,我們手動去導入
-
如何能夠讓一個東西幫我們導入和配置這個jar包
由此,maven誕生了!
5.1maven項目架構管理工具
目前 用來就是友善導入jar包的!
maven的核心思想:約定大于配置
- 有限制,不要去違反
maven會規定你該如何編寫我們的java代碼,必須按照這個規範來
5.2下載下傳Maven
官網:https://maven.apache.org/download.cgi
5.3配置環境變量
在我們的系統環境變量中
配置如下配置:
- M2_HOME maven目錄下的bin目錄
- MAVEN_HOME maven的目錄
- 在系統的path中配置%MAVEN _HOME%\bin
測試maven是否安裝成功,保證必須配置完畢!
5.4阿裡雲鏡像
- 鏡像: mirrors
- 作用:由于國外的鏡像比較慢,為了加速我們的下載下傳
- 國内建議使用阿裡雲的鏡像
<mirror> <id>nexus-aliyun</id> <mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror>
shift + tab 格式化代碼
5.5本地倉庫
在本地的倉庫,遠端倉庫;
預設的本地倉庫
建立一個倉庫:localRepository,在conf/settings檔案下添加
<localRepository>D:\soft\apache-maven-3.6.3\maven-repo</localRepository>
5.6在idea中使用maven
- 啟動idea
- 建立一個mavenWeb項目
-
JavaWeb -
JavaWeb
這時候idea 建立maven項目報錯: Failed to create parent directories for tracking file,我到了D盤的maven那個檔案給它完全控制權限
然後重新載入,發現正在下載下傳
- 觀察maven倉庫中多了什麼東西?
JavaWeb - idea中的maven,idea項目建立成功後,看一眼配置
JavaWeb 到這裡,maven在idea中的配置和使用就OK了JavaWeb 5.7建立一個普通的maven項目
這個隻有在web應用下才會有!
5.8标記檔案夾功能
建立java檔案夾,将其設定為源碼目錄
同時建立resources目錄,将其設定為資源目錄
5.9在idea中配置tomcat
解決警告問題
為什麼會有這個問題?我們通路一個網站,需要指定一個檔案夾名字
5.10pom檔案
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.kuang</groupId>
<artifactId>javaweb-01-maven</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- package項目的打包方式
jar :java應用
war:javaweb應用
-->
<packaging>war</packaging>
<!--配置-->
<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>
</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>
<?xml version="1.0" encoding="UTF-8"?>
<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>
<groupId>com.kuang</groupId>
<artifactId>javaweb-01-maven02</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!-- maven的進階之處在于,他會幫你導入這個jar包所依賴的其他jar-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
</dependencies>
</project>
依賴如果爆紅的話
後經排查問題出在建立工程後maven本地倉庫自動設定為了預設.m2\repository倉庫,如果自己在配置maven時更改過本地倉庫,要再次在設定裡更改為修改後的本地倉庫位址。
maven由于他的約定大于配置,我們之後可能會遇到我們寫的配置檔案,無法被導出或者生效的問題,解決方案:
<!-- 在build中配置resources,來防止我們資源導出的問題-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<!-- 讓src/main/java可以包含.properties、.xml檔案-->
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
5.11目錄樹
5.12解決遇到的問題
-
Maven 3.6.2
Unable to import maven project: See logs for details
解決方法:降級為3.6.1
- tomcat閃退
- idea中每次都要配置maven
在idea中的啟動頁面(如果不是點選close project跳轉到這個頁面)
或者1.打開Settings for New Projects視窗
File > Other Settings > Settings for New Projects...
2.設定maven的安裝路徑(maven home directory、user settings file、local repository)
注意這個标題不是Settings,而是Settings for New Projects
- maven項目中tomcat無法配置
- maven中預設的web項目中的web.xml版本問題
JavaWeb JavaWeb <?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" metadata-complete="true"> </web-app>
-
maven 倉庫的使用
位址:https://mvnrepository.com/
-
tomcat10有些bug是以我又換回了9
更改的時候隻需要更改環境變量裡面的
CATALINA_HOME:D:\soft\apache-tomcat-9.0.52
并且需要給apache-tomcat-9.0.52這個檔案完全控制權限,要不然會報錯500
然後将tomcat10的那個删除重建一個
6、servlet
6.1servlet簡介
- servlet就是sun公司用于開發動态web的一門技術
- sun公司在這些api中提供了一個接口叫做:servlet,如果你想要開發一個Servlet程式,隻需要完成兩個小步驟
- 編寫一個類,實作Servlet接口
- 把開發好的java類部署到web伺服器中
把實作了Servlet接口的java程式叫做servlet
6.2HelloServlet
servlet接口在sun公司有兩個預設的實作類HttpServlet ,GenericServlet
- 建構一個普通Maven項目,删掉裡面的src,以後我們的學習就在這個項目裡面建立Model,這個空的工程就是maven的主工程
-
關于maven父子關系的了解
父項目中pom檔案中會有一個
子項目中會有<modules> <module>servlet-01</module> </modules>
父項目的java子項目可以直接使用<parent> <artifactId>javaweb-02-servlet</artifactId> <groupId>com.kuang</groupId> <version>1.0-SNAPSHOT</version> </parent>
son extends father
-
Maven環境優化
1.修改web.xml為最新的
2.将maven的結構搭建完整
-
編寫一個servlet程式
1.編寫一個普通類
2.實作servlet接口
JavaWeb package com.kuang.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.IOException; import java.io.PrintWriter; public class HelloServlet extends HttpServlet { //由于get或者post隻是請求實作不同的方式,可以互相調用,因為業務邏輯都一樣 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 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); } }
5.編寫servlet的映射
為什麼需要映射:我們寫的是java程式,但是需要通過浏覽器通路,而浏覽器需要連接配接web伺服器,是以我們需要在web服務中注冊我們寫的一個servlet,還需要給它一個浏覽器能夠通路的路徑
<!-- 注冊servlet--> <servlet> <servlet-name>helloServlet</servlet-name> <servlet-class>com.kuang.servlet.HelloServlet</servlet-class> </servlet> <!-- servlet的請求路徑--> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
6.配置tomcat
點選run 裡面的edit configuration
JavaWeb JavaWeb -
啟動測試
報一個錯:
JavaWeb 重新選擇顯示配置JavaWeb JavaWeb JavaWeb
6.3 、Servlet原理
servlet是由web伺服器調用,web伺服器在收到浏覽器請求之後會
6.4Mapping
- 一個servlet可以指定一個映射路徑
<!-- servlet的請求路徑--> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
- 一個servlet可以指定多個映射路徑
<servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello3</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello4</url-pattern> </servlet-mapping>
- 一個servlet可以指定通用映射路徑
<servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
JavaWeb -
預設請求路徑
什麼都不寫,他會比index.html優先級高
<servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
JavaWeb - 指定一些字尾或者字首等等...
<!-- 可以自定義字尾實作請求映射 注意點.*前面不能加項目映射的路徑 hello/sjnjavnaskfn.qinjiang --> <servlet-mapping> <servlet-name>helloServlet</servlet-name> <url-pattern>*.qinjiang</url-pattern> </servlet-mapping>
JavaWeb -
優先級問題
指定了固有的映射路徑優先級最高,如果找不到就會走預設的處理請求;
<!--404--> <servlet> <servlet-name>error</servlet-name> <servlet-class>com.kuang.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
6.5
然後建立了servlet2出現了ignore pom
由于相同名稱的module在之前被建立過,是以在IDEA中留有痕迹。重新建立一個新的同名module會讓IDEA誤以為是之前被删除掉的module,是以才自動将這個pom.xml檔案忽略了。
解決方案:
1. 點選file > Setting進入設定
2. 找到lgnored file,把右邊已選中的選項取消勾選,然後點選 ok
3. 建議再點選右上角Maven中的重新整理一下,這樣pom.xml 檔案就被變回來了
輸出亂碼:
這種情況是tomcat的日志配置檔案的編碼需要修改,找到tomcat安裝目錄,找到conf下的logging.properties檔案,将其中的encoding = UTF-8的部分全部修改為encoding = GBK,如圖:
修改之後儲存重新開機題目cat
6.5servletContext
web容器在啟動的時候,它會為每個web程式建立一個servletContext對象,他代表了目前的web應用;
1.共享資料
我在這個servlet中儲存的資料,可以在另一個servlet中拿到
先存再取,先set後get
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 context = this.getServletContext();
String username = "秦疆"; // 資料
context.setAttribute("username",username);//将一個資料儲存在了servletContext中,名字為:username 值:username
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
resp.getWriter().print("名字" + username);
}
}
<?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"
metadata-complete="true">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
<!-- <init-param>-->
<!-- <param-name></param-name>-->
<!-- <param-value></param-value>-->
<!-- </init-param>-->
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.kuang.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
</web-app>
測試通路結果:
先輸入http://localhost:8080/servlet_02_war/hello
再輸入http://localhost:8080/servlet_02_war/getc
2.擷取初始化參數
<!-- 配置web應用的初始化參數-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc::mysql://localhost:3306/mybatis/param-value</param-value>
</context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
3.請求轉發
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("進入了servletDemo04");
ServletContext context = this.getServletContext();
// RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//轉發的請求路徑
// requestDispatcher.forward(req,resp);//調用forward實作請求轉發
context.getRequestDispatcher("/gp").forward(req,resp);
}
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.kuang.servlet.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
4.讀取資源檔案
properties
- 在java目錄下建立properties
- 在resources目錄下建立properties
發現:都被打包到了同一個路徑下:classes,我們俗稱這個路徑為classpath
思路:需要一個檔案流
username = root12345
password = 123456121123213
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");
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aaa.properties");
Properties prop = new Properties();
prop.load(is);
String user= prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user+":"+pwd);
}
}
通路測試即可
6.6HttpServletResponse
響應:web伺服器接收到用戶端的http請求,針對這個請求,分别建立一個代表請求的HttpServletRequest對象,代表響應的一個HttpServletResponse;
- 如果要擷取用戶端請求過來的參數:找HttpServletRequest
- 如果要給用戶端響應一些資訊:找HttpServletResponse
1.簡單分類
負責向浏覽器發送資料的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
負責向浏覽器發送響應頭的方法
//extends ServletResponse
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
//HttpServletResponse
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将緩沖區中的資料輸出到用戶端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 要擷取下載下傳檔案的路徑 // D:\soft\apache-tomcat-9.0.52\webapps\response_war\1.png // D:\山建\大二下暑假\軟賽\javaweb-02-servlet\response\target\classes\1.png String realPath = "D:\\山建\\大二下暑假\\軟賽\\javaweb-02-servlet\\response\\target\\classes\\秦疆.png"; // String realPath = this.getServletContext().getRealPath("/1.png"); System.out.println("下載下傳檔案的路徑:"+realPath); // 2. 下載下傳的檔案名是啥? /* * 就是取一個檔案完整路徑中的檔案名,譬如 D:\img\abc.jpg,我們要得到abc.jpg. 如果不+1,得到的就包括\本身,成了 \abc.jpg * str.LastIndexOf("\\")--最後一個\的位置 * */ String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); // 3. 設定想辦法讓浏覽器能夠支援下載下傳(Content-Disposition)我們需要的東西 /*Content-Disposition 就是當使用者想把請求所得的内容存為一個檔案的時候提供一個預設的檔案名。 Content-Disposition: attachment; filename="filename.jpg"*/ resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"utf-8")); // 4. 擷取下載下傳檔案的輸入流 FileInputStream in = new FileInputStream(realPath); // 5. 建立緩沖區 int len = 0; byte[] buffer = new byte[1024]; // 6. 擷取OutPutStream對象 ServletOutputStream out = resp.getOutputStream(); // 7. 将FileOutPutStream流寫入到buffer緩沖區,使用 OutPutStream将緩沖區中的資料輸出到用戶端 while ((len = in.read(buffer))>0){ out.write(buffer,0,len); } in.close(); out.close(); }
3.驗證碼功能
驗證怎麼來的?
- 前端實作
- 後端實作,需要用到java的圖檔類,生成一個圖檔
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何讓浏覽器3秒自動重新整理一次
resp.setHeader("refresh","3s");
//在記憶體中建立一個圖檔
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到圖檔
Graphics2D g = (Graphics2D) image.getGraphics();//筆
//設定圖檔的背景顔色
g.setColor(Color.white);
g.fillRect(0,0,80,20);
//給圖檔寫資料
g.setColor(Color.BLUE);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNumber(),0,20);
//告訴浏覽器這個請求用圖檔的 方式打開
resp.setContentType("image/jepg");
//網站存在緩存,不讓浏覽器緩存
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把圖檔寫給浏覽器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随機數
private String makeNumber(){
Random random = new Random();
String num = random.nextInt(9999999)/*生成一個7位的随機數*/+"";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7-num.length(); i++) {
sb.append("0");
}
//下面這句話的意思是,如果生成不到7位數的話剩下的字元用0去填充
num = sb.toString()+num;
return num;//這樣能保證他必定是7位數
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
4、B一個web 資源受到用戶端A請求後,B會通知A用戶端去通路另外一個web資源C,這個過程叫重定向
常見場景:
- 使用者登入
void sendRedirect(String var1) throws IOException;
測試:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
* resp.setHeader("Location","/r/img");
resp.setStatus(302);
* */
resp.sendRedirect("/response_war/img");//重定向
}
面試題:請你聊聊重定向和轉發的差別?
相同點:
- 頁面都會跳轉
不同點
- 請求轉發的時候,url不會産生變化
- 重定向時候,url位址欄會發生變化
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//處理請求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
resp.sendRedirect("/response_war/success.jsp");
//重定向時候一定要注意路徑問題,否則就會404
System.out.println("進入這個請求");
}
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.kuang.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<html>
<body>
<h2>Hello World!</h2>
<%--這裡送出的路徑旭=需要尋找到項目的路徑--%>
<%--{pageContext.request.contextPath}代表目前項目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
使用者名:<input type="text" name = "username">
密碼:<input type="password" name = "password">
<input type="submit">
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>success</h1>
</body>
</html>
6.7HttpServletRequest
HttpServletRequest代表用戶端的請求,使用者通過Http協定通路伺服器,http中的所有資訊會被封裝到HttpServletRequest,通過這個HttpServletRequest的方法我們就可以獲得用戶端的所有資訊;
1、擷取前端傳遞的參數
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
// 背景接收中文亂碼問題
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println("==============");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println("=================");
//通過請求轉發
System.out.println(req.getContextPath());
//轉發是伺服器内部的資料流轉是以前面不應帶目前的web應用的/request_war路徑
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
請求轉發不需要項目名,重定向要加
- 請求轉發的時候,url不會産生變化 307
- 重定向時候,url位址欄會發生變化 302
7 、Cookie 、 Session
7.1會話
會話:使用者打開了一個浏覽器,點選了很多超連結,通路多個web資源,關閉浏覽器,這個過程可以稱之為會話。
有狀态會話:一個同學來過教師,下次再來教師,我們就會知道這個學生,曾經來過,稱之為有狀态會話
你能怎麼證明你是西開的學生?
你 西開
- 發票 西開給你發票
- 學校登記 西開标記你來過了
一個網站怎麼證明你來過?
用戶端 服務端
- 服務端給用戶端一個信件,服務端下次通路服務端帶上信件就可以了 ;cookie
- 伺服器登記你來過了,下次你來的時候我來比對你;session
7.2儲存會話的兩種技術
cookie
- 用戶端技術 (響應,請求)
session
- 伺服器技術,利用這個技術,可以儲存使用者的會話資訊?我們可以把資訊或者資料放在Session中
常見場景:網站登入之後,你不用再登入,第二次通路就直接上去了
7.3cookie
- 從請求中拿到cookie資訊
- 伺服器響應給用戶端cookie
Cookie[] cookies = req.getCookies();//這裡傳回數組,說明Cookie可能存在多個 cookies.getName();//獲得cookie中的key cookie.getValue();//獲得cookie中的value new Cookie("lastLoginTime",System.currentTimeMillis()+"");//建立一個cookie cookie.setMaxAge(24*60*60);//設定cookie有效期 resp.addCookie(cookie);//響應給客戶瑞一個cookie
cookie:一般會儲存在本地的使用者目錄下面的APPdata
一個網站的cookie是否存在上限!
- 一個cookie隻能儲存一個資訊
- 一個web可以給浏覽器發送多個cookie,浏覽器大概有300kie,每個站點大概存放20個cookie
- cookie的大小有限制4kb
删除Cookie;
- 不設定有效期,關閉浏覽器自動失效
- 設定有效期的時間為0
編碼解碼:
URLDecoder.decode(cookie.getValue(),"utf-8");
URLEncoder.encode("秦疆","utf-8")
7.4Session(重點)
什麼是Session:
- 伺服器會給每一個使用者建立一個Session對象
- 一個Session獨占一個浏覽器,隻要浏覽器沒有關閉這個Session就存在
- 使用者登入之 後整個網站跳到這個網站的其他頁面都可以通路! --->儲存購物車的資訊
Session和Cookie的差別
- Cookie是把使用者的資料寫給使用者的浏覽器,浏覽器儲存(可以儲存多個)
- Session是把使用者的資料寫到使用者獨占的Session中,伺服器端儲存(儲存重要的資訊,減少伺服器資源浪費)
- Session對象由服務建立
使用場景:
- 儲存一個登入使用者的資訊
- 購物車資訊
- 在整個網站中經常會使用的資料,我們将它儲存在Session中;
使用Session
package com.kuang.servlet;
import com.kuang.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
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",new Person("秦疆",1));
//擷取session的id
String sessionId = session.getId();
// 判斷session是不是新建立的
if (session.isNew()){
resp.getWriter().write("session建立成功~ID為:" +sessionId);
}else{
resp.getWriter().write("session已經在伺服器存在~ID為" +sessionId);
}
//session建立的時候做了什麼事情:
// Cookie cookie = new Cookie("JSESSIONID", sessionId);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
得到Session
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();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
}
手動登出session
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();//登出sessionid
}
設定session預設的失效時間,會話自動過期
<session-config>
<!-- 1分鐘後session自動失效,以分鐘為機關-->
<session-timeout>1</session-timeout>
</session-config>
遇到的問題:
每個浏覽器都有自己的session:
8、JSP
8.1什麼是JSP
java server pages : java端頁面,也和Servlet一樣,用于動态Web技術!
最大的特點:
- 寫jsp就像在寫HTML
- 差別:
- HTML隻給使用者提供靜态的資料
- jsp頁面中可以嵌入java代碼,為使用者提供動态資料
8.2JSP原理
思路:jsp到底如何執行的?
- 代碼層面沒有任何問題,就類似與HTML的頁面代碼
-
伺服器内部工作
tomcat中有一個work目錄;
在idea中使用tomcat的會在idea的tomcat目錄中産生一個work目錄
我電腦的位址:
發現頁面轉變為了java程式C:\Users\sgc\AppData\Local\JetBrains\IntelliJIdea2020.2\tomcat\Tomcat_9_javaweb-02-servlet\work\Catalina\localhost\javaweb_session_cookie_war\org\apache\jsp
JavaWeb 浏覽器向伺服器發送請求,不管通路什麼資源,其實都是在通路servlet
JSP也會被轉換成為java類
我們寫的jsp轉換為java程式,他手動幫我們做了原來程式員做的一些繁瑣的事情,而我們隻需要去寫簡單的HTML頁面就可以了
jsp本質就是一個serveletJavaWeb JavaWeb //初始化 public void _jspInit() { } //銷毀 public void _jspDestroy() { } //JSP的service public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
- 判斷請求
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { final java.lang.String _jspx_method = request.getMethod(); if ("OPTIONS".equals(_jspx_method)) { response.setHeader("Allow","GET, HEAD, POST, OPTIONS"); return; } if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) { response.setHeader("Allow","GET, HEAD, POST, OPTIONS"); response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 隻允許 GET、POST 或 HEAD。Jasper 還允許 OPTIONS"); return; }
-
final javax.servlet.jsp.PageContext pageContext;//頁面上下文 javax.servlet.http.HttpSession session = null;//session final javax.servlet.ServletContext application;//application final javax.servlet.ServletConfig config;//config javax.servlet.jsp.JspWriter out = null;//out final java.lang.Object page = this;//page:目前頁面 HttpServletRequest request //請求 HttpServletResponse response //響應
- 輸出頁面前增加的代碼
response.setContentType("text/html");//設定文本響應類型為html pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out;
- 以上的這些個對象我們可以在jsp頁面中直接使用
JavaWeb 在jsp頁面中:
隻要是java代碼,就會原封不動的輸出
如果是HTML代碼會被轉換為
這樣的格式輸出到前端out.write("<html>\n");
- 判斷請求
8.3JSP基礎文法
任何語言的都有自己的文法,Java中有,jsp作為java技術的一種應用,他擁有自己擴充的一些文法(了解,知道即可!)java所有文法都支援!
jsp表達式
<%--JSP表達式
作用:用來将程式的輸出,輸出到用戶端
<%=變量或者表達式%>
--%>
<%=new java.util.Date()%>
jsp腳本片段
<%--jsp腳本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
out.println("<h1>Sum="+sum+"</h1>");
%>
腳本片段的再實作
<%
int x = 10;
out.print(x);
%>
<p>這是一個jsp文檔</p>
<%
out.print(x);
%>
<hr>
<%-- 在代碼中嵌入HTML元素--%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>hello,world <%=i%></h1>
<%
}
%>
jsp聲明
<%!
static{
System.out.println("Loading Servlet!");
}
private int globalVar = 0;
public void kuang(){
System.out.println("進入了方法kuang");
}
%>
jsp聲明:會被編譯到jsp生成的java的類中!其他的,就會被生成到_jspService方法中!
<%%>
<%=%>
<%!%>
<%--注釋--%>
8.4JSP指令
<%@page args... %>
<%include file=""%>
<%--@include會将兩個頁面合二為一--%>
<%@include file="common/header.jsp" %>
<h1>網頁主體</h1>
<%@include file="common/footer.jsp" %>
<%--jsp标簽--
jsp:include:拼接頁面本質還是三個
--%>
<jsp:include page="common/header.jsp"/>
<h1>網頁主體</h1>
<jsp:include page="common/footer.jsp"/>
8.5、9大内置對象
- PageContext 存東西
- Request 存東西
- Response
- Session 存東西
- Application【ServletContext】存東西
- config【ServletConfig】
- out
- page
- excepetion