一、Http 1.什麼事Http Http(超文本傳輸協議)是一個簡單的請求-響應協議,它通常運行在TCP之上 文本:html,字元串,~.. 超文本:圖片,音樂,視屏,定位,地圖... 埠為80 Https:安全的,埠號443 2.兩個時代 http1.0 HTTP/1.0:客戶端可以與web ...
一、Http
1.什麼事Http
Http(超文本傳輸協議)是一個簡單的請求-響應協議,它通常運行在TCP之上-
文本:html,字元串,~..
-
超文本:圖片,音樂,視屏,定位,地圖...
-
埠為80
Https:安全的,埠號443
2.兩個時代
-
http1.0
- HTTP/1.0:客戶端可以與web伺服器連接後,只能獲得一個web資源,斷開連接
-
http2.0
- HTTP/1.1:客戶端可以與web伺服器連接後,可以獲得多個web資源
3.Http請求
- 客戶端--發請求(requset)--伺服器
百度:
Request URL: https://www.baidu.com/ 請求地址
Request Method: GET get方法/post方法
Status Code: 200 OK 狀態碼:200
Remote(遠程地址) Address: 39.156.66.14:443
Accept: text/html
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
(1)請求行
-
請求行中的請求方式:get
-
請求方式:Get,Post
- Get:請求能夠攜帶的參數比較少,大小有限制,會在瀏覽器的URL地址欄顯示數據內容,不安全,但高效
- Postget:請求能夠攜帶的參數沒有限制,大小沒有限制,不會在瀏覽器的URL地址欄顯示數據內容,安全,但不高效
(2)消息頭
Accept: 告訴瀏覽器,他所支持的數據類型
Accept-Language: zh-CN,zh;q=0.9,告訴瀏覽器,它的語言環境
Cache-Control: max-age=0: 緩存控制
Connection: keep-alive:告訴瀏覽器,請求完成是斷開還是保持連接
HOST:主機
4.Http響應
- 伺服器--響應--客戶端
百度:
Cache-Control: private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
(1)響應體
Accept: 告訴瀏覽器,他所支持的數據類型
Accept-Language: zh-CN,zh;q=0.9,告訴瀏覽器,它的語言環境
Cache-Control: max-age=0: 緩存控制
Connection: keep-alive:告訴瀏覽器,請求完成是斷開還是保持連接
HOST:主機
Refresh:告訴客戶端,多久刷新一次;
Location:讓網頁重新定位
(2)響應狀態碼
200:請求響應成功3xx:請求重定向
- 重定向:你重新到我給你新位置去;
4xx:找不到資源
- 資源不存在
5xx:伺服器代碼錯誤 500 ,502:網關錯誤
常見面試題:
當你的瀏覽器中地址欄輸入地址並回車的一瞬間到頁面能夠展示回來,經歷了什麼?
二、Maven
為什麼要學習這個技術?-
在Javaweb開發中,需要使用大量的jar包,我們手動去導入
-
如何能夠讓一個東西自動幫我導入和配置這個jar包,由此,Maven誕生了
1.Maven項目架構管理工具
我們目前用來就是方便導入jar包的 Maven的核心思想:約定大於配置- 有約束,不要去違反
Maven會規定好你該如何去編寫我們的Java代碼,必須要按照這個規範來;
2.下載安裝Maven
下載鏈接https://maven.apache.org/download.cgi
3.配置Maven環境變數
Mac終端輸入vim ~/.bash_profile
然後將以下配置加入裡面
MAVEN_HOME=/Users/twq/Downloads/apache-maven-3.8.6
PATH=$MAVEN_HOME/bin:$PATH
M2_HOME=/Users/twq/Downloads/apache-maven-3.8.6/bin
export MAVEN_HOME
export PATH
export M2_HOME
最後輸入 mvn -v
出現如下圖表名配置成功
Windows:
在環境變數中添加M2_home和MAVEN_HOME兩個路徑
並繼續添加PATH的路徑
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>
將此配置放入setting.xml的mirrors中即可
5.設置本地倉庫
創建一個本地倉庫<localRepository>/Users/twq/Downloads/apache-maven-3.8.6/maven-repo</localRepository
6.在IDEA中操作Maven
進來後可能還會顯示pom.xml(Unknown)
我的第一次進來是這樣,不知道為啥我的pom.xml里是空白的
最後自己手動添加瞭如下
<?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>org.example </groupId>
<!--項目名-->
<artifactId>tang</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
進入後如果沒有自動下載maven依賴,則可以自己在IDEA的終端輸入以下命令下載
mvn dependency:resolve-plugins
最後出現如下圖所示則表明下載成功
成功後,自己建的maven倉庫里就有了很多文件
(1)新建src相關目錄
而且還沒有src目錄在,找了很多解決方法,最後發現如下解決辦法 ①點擊項目右鍵新建目錄
這裡會自動顯示你想要的src以及test文件
創建完成如下圖所示
(2)新建webapp目錄
(3)將IDEA中的文件標記為指定樣式的文件
方法一:
方法二:
(4)配置Tomcat
①解決警告問題
為什麼會有這個警告:我們訪問一個網站需要指定一個文件夾名字啟動Tomcat會直接顯示webapp裡面的index.jsp文件里的內容
(5)pom.xml文件
<?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>
<groupId>org.example </groupId>
<artifactId>tang</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.8</maven.compiler.source>-->
<!-- <maven.compiler.target>1.8</maven.compiler.target>-->
<!-- </properties>-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
</dependencies>
<!-- 在build中配置resource,防止我們資源導出失敗的問題-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
(6)maven的jar包結構圖
三、Servlet
1.Servlet簡介
-
Servlet就是sun公司開發動態web的一門技術
-
Sun在這些API中提供一個介面叫做:Servelt,如果你想開發一個Servlet程式,只需要完成兩個小步驟:
- 編寫一個類,實現servlet介面
- 把開發好的Java類部署到web伺服器中
把實現了Servlet介面的Java程式叫做Servlet
2.關於Maven父子工程的理解
父項目中會有<!--指明該父類下的子模塊-->
<modules>
<module>Servlet-01</module>
</modules>
子項目中會有
<!-- 子類必須指明父類-->
<parent>
<artifactId>javaweb-02-Servlet</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父項目中的Java,子項目可以直接使用
註意:
父項目的打包方式必須為pom且必須要定義打包方式,子項目的打包方式必須為jar,否則會報錯:Invalid packaging for parent POM org.example:javaweb-02-Servlet:1.0-SNAPSHOT (/Users/twq/Downloads/javaweb-02-Servlet/pom.xml), must be "pom" but is "jar"
3.編寫HelloServlet
(1).Maven倉庫的使用
官網地址 https://mvnrepository.com/Tomcat中Servlet的使用樣例鏈接
http://localhost:8080/examples/servlets/
上圖若沒有搜索到,則可去Maven倉庫中尋找
一搜發現搜到一堆沒用的,心想既然在Tomcat上能使用肯定是導入了某一個與HttpServlet相關的jar包,於是乎又來到Tomcat的lib目錄(存放各種jar包的地方)下查找
發現lib目錄下與servlet相關的jar包只有一個,於是再次回到maven倉庫中尋找該jar包
我選擇的是導入maven依賴,複製上圖方框里的依賴代碼,依賴里的
然後將Tomcat中Servlet下的hello樣例代碼粘貼過來,就是如下代碼
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
(2).編寫web.xml
建一個包①編寫servlet的映射
為什麼需要映射:我們寫的是Java程式,但是要通過瀏覽器訪問,而瀏覽器需要連接web伺服器,所以我們需要在web服務中註冊我們寫的Servlet,還需要給他一個瀏覽器能夠訪問的路徑<!--註冊servlet-->
<servlet>
<!--隨便起個名字-->
<servlet-name>hello</servlet-name>
<servlet-class>com.tang.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<!--請求路徑 -->
<url-pattern>/Twq</url-pattern>
</servlet-mapping>
②Servlet映射原理
可以根據輸入的指定路徑如我的指定的Twq路徑http://localhost:8080/Servlet_01_war/Twq,然後根據Twq請求路徑在Servlet-mapping中找到servlet-name也即是hello,然後在根據註冊的servlet-name找到要執行的Java程式,最後運行Java程式
自定義前尾碼映射
①指定首碼,尾碼隨意
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--請求路徑 -->
<url-pattern>/Twq/*</url-pattern>
</servlet-mapping>
測試數據:
http://localhost:8080/Servlet_01_war/Twq/fafsdafgsfvdsfsdgg
測試結果:
②指定尾碼,首碼隨意
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--請求路徑 -->
<!--註意點 .*前面不能加項目映射的路徑否則會啟動Tomcat報錯 -->
<url-pattern>*.Twq</url-pattern>
</servlet-mapping>
測試數據:
http://localhost:8080/Servlet_01_war/sdfadfvfsgsddfrqw.Twq
測試結果:
發現只要尾碼是.Twq結尾前面是什麼無所謂
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_4_0.xsd"
version="4.0">
<!-- web.xml中是配置我們web的核心應用-->
<!--註冊servlet-->
<servlet>
<!--隨便起個名字-->
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.tang.HelloServlet</servlet-class>
</servlet>
<!--一個servlet對應一個mapping:映射-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--請求路徑 -->
<url-pattern>/Twq</url-pattern>
</servlet-mapping>
</web-app>
4.運行Tomcat
(1)解決啟動報錯
然後運行Tomcat可能會報 java: 錯誤: 不支持發行版本 5這個錯誤(之前還能用的,不知道怎麼回事突然報了這個錯誤,說實在的這兩天解決這些奇怪的報錯,真是讓人頭疼!!!) 解決方法(沒辦法,還是得笑對人生繼續改錯)完成上面幾步之後可以解決此問題,Tomcat就可以正常啟動了
運行結果圖
(2)解決中文亂碼
亂碼的原因及解決方法解決方法:
設置瀏覽器的響應的編碼格式即可
HelloServlet代碼
package com.tang;
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;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
//響應的類型:html
response.setContentType("text/html");
//設置瀏覽器響應的編碼格式
response.setCharacterEncoding("UTF-8");
//獲取響應的輸出流
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>唐昊!!</h1>");
out.println("</body>");
out.println("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
5.ServletContext對象
web容器在啟動的時候,它會為每個web程式都創建一個對應的ServletContext對象,它代表了當前的web應用;(1).共用數據
-
在這個Servlet中保存的數據,可以咋另外一個Servlet中拿到;
存放數據的類public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //響應的類型:html 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.setHeader("text/html","UTF-8"); resp.getWriter().println("姓名:"+username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
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_4_0.xsd" version="4.0"> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.tang.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/Twq1</url-pattern> </servlet-mapping> <servlet> <servlet-name>get</servlet-name> <servlet-class>com.tang.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>get</servlet-name> <url-pattern>/Twq2</url-pattern> </servlet-mapping> </web-app>
測試訪問結果:
(2)獲取初始化參數
web.xml代碼如下<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306</param-value>
</context-param>
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.tang.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
ServletDemo03中代碼如下
package com.tang;
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;
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().println(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
(3)請求轉發
ServletDemo04代碼
package com.tang;
import javax.servlet.RequestDispatcher;
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;
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("進入了ServletDemo04");
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//轉發的請求路徑
requestDispatcher.forward(req,resp);//調用forward實現請求轉發
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml 代碼
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.tang.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
運行結果圖
轉發的大致思想:
比如有A,B,C,現在有一個需求是A想要拿到C的資源,但是A又無法直接調用C,且只能連接到B,就只能B找C拿,然後C在返回給B,最後B在將C返回的數據交給A,這個過程中,A和C始終沒有見到C,所以上圖路徑沒有變化(用sd4的路徑去訪問jp路徑裡面的內容),圖形化過程如下:
(4)讀取資源文件
Properties-
在Java目錄下新建Properties
-
在resource目錄下新建Properties
發現:都被打包到了同一個路徑下:classes,我麽俗稱這個路徑為classpath:
當在java目錄下寫資源文件時,並不會被打包,可以通過如下方法解決,將以下代碼放入當前模塊的pom.xml中即可
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<!-- 這裡就是將在Java目錄下的資源文件也給打包-->
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
加上之後再重新打包,就會生成資源文件
開始讀取該資源文件的流
aa.properties文件里的內容如下:
username=root
password=123456
web.xml代碼
<servlet>
<servlet-name>sd5</servlet-name>
<servlet-class>com.tang.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd5</servlet-name>
<url-pattern>/sd5</url-pattern>
</servlet-mapping>
ServletDemo05代碼如下:
package com.tang;
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;
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream resource = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/tang/aa.properties");
Properties properties = new Properties();
properties.load(resource);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().println(username+":"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
當前項目路徑
運行結果圖
6.HttpServletResponse
響應:web伺服器就收到客戶端的Http請求,針對這個請求,分別創建一個代表請求的HttpServletRequest對象,代表響應的一個HttpServletResponse;-
如果要獲取客戶端請求過來的參數:找HttpSerletRequest
-
如果要給客戶端響應一些信息:找HttpServletResponse
(1)簡單分類
①負責像瀏覽器發送數據的方法ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
②負責向瀏覽器發送響應頭的方法
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);
(2)常見應用
①下載文件(瞭解)
-
要獲取下載文件的路徑
-
下載的文件名是啥?
-
設置想辦法讓瀏覽器能夠支持下載我們需要的東西
-
獲取下載文件的輸入流
-
輸出獲取到的輸入流
- 創建緩衝區
- 獲取OutputStream對象
- 將FileOutputStream流寫入到buffer緩衝區中
- 使用OutputStream將緩衝區中的數據輸出到客戶端
web.xml代碼如下:
<servlet>
<servlet-name>fileDown</servlet-name>
<servlet-class>com.tang.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fileDown</servlet-name>
<url-pattern>/down</url-pattern>
</servlet-mapping>
該模塊的pom.xml中儘量加上如下代碼:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
FileServlet代碼如下
package com.tang;
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;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp){
FileInputStream in = null;//將文件變成流
ServletOutputStream outputStream = null;
try {
//1.要獲取下載文件的路徑
String realPath = "/Users/twq/Downloads/javaweb-02-Servlet/out/artifacts/Servlet_03_war_exploded/WEB-INF/classes/唐三.jpg";
System.out.println("下載的文件的路徑為:"+ realPath);
//2.下載的文件名是啥?
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);// 因為一個/需要轉義,所以寫兩個表示截取到最後一個/,然後加1就表示最後一個/後面的名字,也即是文件名
//3.設置想辦法讓瀏覽器能夠支持下載我們需要的東西
//Content-disposition:表示web下載文件的頭消息,也是用其來支持下載我們需要的東西;中文文件名使用URLEncoder.encode編碼,否則可能會亂碼
resp.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(fileName,"UtF-8"));
//4.獲取下載文件的輸入流
in = new FileInputStream(realPath);
//5.輸出獲取到的輸入流
//6.創建緩衝區
int len = 0;
byte[] buffer = new byte[1024];
//7.獲取OutputStream對象
outputStream = resp.getOutputStream();
//8.將FileOutputStream流寫入到buffer緩衝區中,使用OutputStream將緩衝區中的數據輸出到客戶端
while((len=in.read(buffer)) != -1){
outputStream.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//關閉流
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
填寫文件的絕對路徑時,可以再out目錄下去複製對應文件的絕對路徑
運行結果圖
②驗證碼功能(瞭解)
驗證實現方法-
前端實現
-
後端實現,需要用到Java的圖片類,生成一個圖片
web.xml註冊代碼
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>com.tang.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/img</url-pattern>
</servlet-mapping>
ImageServlet代碼
package com.tang;
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;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//讓瀏覽器3秒自動刷新一次
resp.setHeader("refresh","2");
//在記憶體中創建一個圖片
BufferedImage image = new BufferedImage(100, 20, BufferedImage.TYPE_INT_RGB);
//得到圖片,用一個2D的筆
Graphics2D g = (Graphics2D)image.getGraphics();
//設置圖片的背景顏色
g.setColor(Color.white);
//fillRect:填充一個矩形,從(0,0)點開始到(80,20)結束填充一個背景為白色矩形
g.fillRect(0,0,100,20);
//給圖片寫數據
g.setColor(Color.red);//設置畫筆顏色
g.setFont(new Font(null,Font.BOLD,20));//設置字體
g.drawString(makeNum(),0,20);//在(0,20)這個位置將隨機數給畫上去
//告訴瀏覽器,這個請求用圖片的方式打開
resp.setContentType("image/jpg");
//網站存在緩存,設置不讓瀏覽器緩存
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();
//7個9表示一個七位數,一個整數加上一個空串之後變為一個字元串
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
//保證生成的數為七位的,不足七位補零
for(int i =0; i < 7-num.length();i++){
sb.append("0");
}
num = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
運行結果圖
③重定向(重點)
一個web資源(B)收到客戶端(A)請求,他(B)會通知客戶端(A)去訪問另一個web資源(C),這個過程叫重定向
常見場景:
- 用戶登錄
web.xml代碼
<servlet>
<servlet-name>Redirect</servlet-name>
<servlet-class>com.tang.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Redirect</servlet-name>
<url-pattern>/red</url-pattern>
</servlet-mapping>
RedirectServlet代碼
package com.tang;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
由運行結果下麵結果圖知下麵這行代碼等價於
resp.setHeader("Location","/Servlet_03_war/img");
resp.setStatus(302);
*/
resp.sendRedirect("/Servlet_03_war/img");//重定向
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
運行結果圖
註意:重定向的路徑要添加如下圖所示的東西
重定向和轉發的區別(面試題)
相同點:- 頁面都會實現跳轉
不同點:
-
請求轉發的時候,轉發的url不會發生變化
-
重定向的時候,url地址欄會發生變化
7.HttpServletRequest
HttpServletRequest代表客戶端的請求,用戶通過Http協議訪問伺服器,HTTP請求中的所有信息會被封裝到HttServletRequest,通過這個HttpServletRequest的方法獲得客戶端的所有信息(1)獲取參數,請求轉發
RequestTest代碼如下:
package com.tang;
import javax.naming.Context;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("有請求進來");
//處理請求
String username = req.getParameter("username");//獲取請求參數的值
String password = req.getParameter("password");
System.out.println(username + ":" +password);
//重定向的時候一定添加web應用的路徑,否則404
//resp.sendRedirect("/Servlet_03_war/Success.jsp");
/*轉發的時候web應用的路徑就不用寫了,否則也會報404
因為這裡的 / 代表的就是當前的web應用,在寫就重覆了*/
req.getRequestDispatcher("/Success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml代碼
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.tang.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
index.jsp代碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--這裡提交的路經,需要尋找到項目的路徑--%>
<%--${pageContext.request.contextPath}代表當前的項目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用戶名:<input type="text" name="username"><br>
密碼:<input type="text" name="password"><br>
<input type="submit">
</form>
</body>
</html>
Success.jsp代碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
運行結果
8.Cookie、Session
(1)會話
會話:用戶從打開一個瀏覽器->點擊了很多超鏈接->訪問多個web資源->關閉瀏覽器,這個過程可以稱之為會話。有狀態的會話:一個同學來過教室下次再來教室,我們會知道這個同學曾經來過,稱之為有狀態會話
一個網站,怎麼證明你來過?
-
服務端給客戶端一個信件,客戶端下次訪問服務端帶上信件就可以了;cookie
-
伺服器登記你來過了,下次你來的時候我來匹配你;session
(2)保存會話的兩種技術
①cookie
- 客戶端技術(伺服器通過響應將數據發給客戶端,客戶端通過請求將數據帶到伺服器上)
②session
- 伺服器技術,利用這個技術,可以保存用戶的會話信息,我們可以吧信息或者數據放在Session中