JavaWeb
1、基本概念
1.1、前言
web開發:
- web,網頁的意思
- 靜態web
- html,css
- 提供給所有人看的資料始終不會發生變化
- 動態web
- 幾乎所有的網站都是動態的
- 提供給所有人看的資料始侄訓發生變化,每個人在不同的時間,不同的地點看到的資訊各不相同
- 技術堆疊:Servlet/JSP,ASP,PHP
在Java中,動態web資源開發的技術統稱為JavaWeb
1.2、web應用程式
web應用程式:可以提供瀏覽器訪問的程式
- index.html、login.html......多個web資源,這些web資源可以唄外界訪問,對外界提供服務
- 我們能訪問到的任何一個頁面或者資源,都存在于這個世界的某個角落的計算機上
- URL
- 這個統一的web資源會被放在同一個檔案夾下,web應用程式-->Tomcat:服務器
- 一個web應用由多部分組成(靜態web、動態web)
- html、css、js
- jsp、Servlet
- Java程式
- jar包
- 組態檔(Properties)
web應用程式撰寫完畢后,若想要提供給外界訪問,需要一個服務器來統一管理
1.3、靜態web
-
*.htm,*.html,這些都是網頁的后綴,如果服務器上一直存在存在這些東西,我們就可以直接進行讀取,通信
flowchart LR c[客戶端]--一次請求:Request-->s[web Service]--一次回應:Response-->c subgraph 服務器 s-->I(((index.html)))-->s end subgraph 客戶端 c end -
靜態web存在的缺點
- web頁面無法動態更新,所有用戶看到都是同一個頁面
- 輪播圖,點擊特效:偽動態
- JavaScript【實際開發中,它用的最多】
- VBScript
- 它無法和資料庫互動(資料無法持久化,用戶無法互動)
- web頁面無法動態更新,所有用戶看到都是同一個頁面
1.4、動態web
頁面會動態展示:“web的頁面展示的效果因人而異”
flowchart c[客戶端]--一次請求:Request-->w[Web Server Plugin] ws[Web Server]--一次回應:Response-->c subgraph 服務器 w--動態資源-->動態web資源JSP/Servlet-->ws-->fs[File System] end subgraph 客戶端 c end缺點:
- 假如服務器的動態web資源出現了錯誤,我們需要重新撰寫我們的后臺程式,重新發布
- 停機維護
優點:
- Web頁面可以動態更新,所有用戶看都都不是同一個頁面
- 它可以與資料庫互動(資料持久化:注冊,商品資訊,用戶資訊.....)
2、web服務器
2.1、技術講解
ASP
- 微軟:國內最早流行的就是ASP
- 在HTML中嵌入了VB腳本,ASP+COM
- 在ASP開發中,基于一個頁面都有幾千行的業務代碼,頁面極其混亂
- 維護成本高
- C#
- IIS
PHP
- PHP開發速度很快,功能很強大,跨平臺,代碼很簡單(國內70%)
- 無法承載大量訪問的情況(局限性)
JSP/Servlet
B/S:瀏覽器和服務器
C/S:客戶端和服務器
- sun公司主推的B/S架構
- 基于Java語言(所有的大公司,或者一些開源組件,都是用Java寫的)
- 可以承載三高問題帶來的影響(高并發、高可用、高性能)
- 語法像ASP,ASP轉JSP,加強市場強度
2.2、wen服務器
服務器是一種被動的操作,用來處理用戶的一些請求和給用戶一些回應資訊
IIS
微軟的,ASP...Windows中自帶
Tomcat
Tomcat是Apache 軟體基金會(Apache Software Foundation)的Jakarta 專案中的一個核心專案,最新的Servlet 和JSP 規范總是能在Tomcat 中得到體現,因為Tomcat 技術先進、性能穩定,而且免費,因而深受Java 愛好者的喜愛并得到了部分軟體開發商的認可,成為比較流行的Web 應用服務器,
Tomcat 服務器是一個免費的開放源代碼的Web應用服務器,屬于輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和除錯JSP 程式的首選,對于一個初學者來說,它是最佳的選擇
Tomcat 實際上運行JSP 頁面和Servlet,
3、Tomcat
3.1、安裝Tomcat
Tomcat官網??https://tomcat.apache.org/
下載——>解壓
- Core:
- zip (pgp, sha512)
- tar.gz (pgp, sha512) Linux安裝包
- 32-bit Windows zip (pgp, sha512)
- 64-bit Windows zip (pgp, sha512) 64位安裝包
- 32-bit/64-bit Windows Service Installer (pgp, sha512)
3.2、Tomcat啟動和配置
檔案夾目錄下??apache-tomcat-9.0.55
??bin 啟動、關閉的腳本檔案夾
??conf 組態檔夾
??lib 依賴的jar包
??logs 日志
??webapps 存放網址的
啟動,關閉Tomcat
??bin目錄下的
startup.bat檔案
shutdown.bat檔案
訪問測驗:http://localhost:8080
可能遇到的問題:
- Java環境變數沒有配置
- 閃退問題:需要配置兼容性
- 亂碼問題:組態檔中設定
3.3、配置
??conf目錄下的
server.xml 服務器核心組態檔
可以配置啟動的埠號
- Tomcat的默認埠號為:8080
- MySQL的默認埠號為:3306
- http的默認埠號為:80
- https的默認埠號為:443
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主機的名稱
- 默認的主機名為:localhost(127.0.0.1)
- 默認網站應用存放的位置為:webapps
<Host name="www.amusing.com" 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
-amusingoh : 網站的目錄名
-WEB-INF
-classes : Java程式
-lib : web應用說依賴的jar包
-web.xml : 網站組態檔
index.html 默認的首頁
-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 get方法/post方法
Status Code:200 OK 狀態碼:200
Remote(遠程) Address:14.215.177.39:443
Accept:text/html
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.9 語言
Cache-Control:max-age=0
Connection:keep-alive
4.3.1、請求行
- 請求行中的請求方式:GET
- 請求方式:Get,Post,HEAD,DELETE,PUT,TRACT....
- GET:請求能夠攜帶的產生較少,大小有現在,會在瀏覽器的URL地址顯示資料內容,不安全,但高效
- POST:請求能夠攜帶的產生沒有限制,大小沒有限制,不會再瀏覽器的URL地址欄顯示資料內容,安全,但不高效
4.3.2、訊息頭
Accept:text/html 告訴瀏覽器,它支持的資料型別
Accept-Encoding:gzip, deflate, br 支持的編碼格式 GBK UTF-8 GB2312
Accept-Language:zh-CN,zh;q=0.9 告訴瀏覽器它的語言環境
Cache-Control:max-age=0 快取控制
Connection:keep-alive 告訴瀏覽器,請求完成是否斷開還是保持連接
HOST: 主機....
4.4、Http回應
- 服務器--回應--客戶端
Cache-Control:private 換成控制
Connection:Keep-Alive 連接
Content-Encoding:gzip 編碼
Content-Type:text/html 型別
4.4.1、回應體
Accept:text/html 告訴瀏覽器,它支持的資料型別
Accept-Encoding:gzip, deflate, br 支持的編碼格式 GBK UTF-8 GB2312
Accept-Language:zh-CN,zh;q=0.9 告訴瀏覽器它的語言環境
Cache-Control:max-age=0 快取控制
Connection:keep-alive 告訴瀏覽器,請求完成是否斷開還是保持連接
HOST: 主機....
Refresh: 告訴客戶端多久重繪一次
Location: 讓網頁重新定位
4.4.2、回應狀態碼
200:請求回應成功
3xx:請求重定向
- 重定向:你重新到我給你的新地址去
4xx:找不到資源 404
- 資源不存在
5xx:服務器代碼錯誤 500 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
- 作用:加上jar包的下載
- 國內建議使用阿里云的鏡像
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共倉庫</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
5.5、本地倉庫
在本地的倉庫
建立一個本地倉庫:localRepository
<localRepository>D:\maven\apache-maven-3.6.3\repository</localRepository>
6、Servlet
6.1、Servlet 簡介
- Servlet 就是sun公司開發的動態web的一門技術
- sun在這些API中提供一個介面叫做:Servlet,如果你想開發一個Servlet程式,只需要完成兩個小步驟:
- 撰寫一個類,實作Servlet介面
- 把開發好的Java類部署到web服務器中,
把實作了Servlet介面的Java程式叫做 Servlet
6.2、HelloServlet
Servlet介面Sun公司又有兩個默認的實作類:HttpServlet,
-
構建一個普通的Maven專案,刪掉里面的src目錄,以后就在這個專案里面建立Module;這個工程就是Maven主工程
-
關于Maven父子工程的理解:
父專案中會有
<modules> <module>servlet-01</module> </modules>
子專案會有
<parent> <artifactId>javaweb-02-servlet</artifactId> <groupId>com.amusingoh</groupId> <version>1.0-SNAPSHOT</version> </parent>
父專案中的Java子專案可以直接使用
son extends father
-
Maven環境優化
- 修改web.xml為最新的
- 將Maven的結果搭建完整
-
撰寫一個Servlet程式
-
撰寫一個普通類
-
實作Servlet介面,這里我們直接繼承HttpServlet,GenericServlet
public class HelloServlet extends HttpServlet { //由于get或者post只是請求實作的不同方式,可以互相呼叫,業務邏輯都一樣 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //ServletOutputStram 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,還需要給他一個瀏覽器能夠訪問的路徑
<!--注冊Servlet--> <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.amusingoh.servlet.HelloServlet</servlet-class> </servlet> <!--Servlet的請求路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping>
-
配置Tomcat
注意:配置專案發布的路徑就ok
-
啟動測驗
-
6.3、Servlet
Servlet是由Web服務器呼叫,Web服務器在收到瀏覽器請求之后,會
graph 瀏覽器--發送Http請求-->Web容器--首次訪問-->A[Servlet]; Web容器-->res[請求:請求頭,請求體] & resp[回應:回應頭,回應體]--呼叫Servlet的Service方法-->Servlet-->END[我們自己些寫的實作類,重寫這些方法1.接收并處理請求2.給出回應的資訊]; Web容器--讀取回應資訊-->resp6.4、Mapping問題
-
一個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>/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可以指定通用映射路徑
<servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
-
默認請求路徑
<!--默認請求路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
-
指定一些后綴或者前綴等等
<!--可以自定義后綴實作請求映射 注意 * 前面不能加專案映射路徑 hello/ddd.amusin --> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.hell</url-pattern> </servlet-mapping>
-
優先級問題
指定了固有的映射路徑優先級最高,如果找不到就會走默認的處理請求
<!--404--> <servlet> <servlet-name>error</servlet-name> <servlet-class>com.amusingoh.servlet.ErrorServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping>
6.5、ServletContext
web容器在啟動的時候,他會為每個web程式都創建一個ServletContext物件,它代表了當前的web應用
6.5.1、 共享資料
在這個Servlet中保存的資料,可也在另外的Servlet中拿到
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 = "頂癮喔"; //資料
//將資料保存在ServletContext中
context.setAttribute("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;charset=utf-8");
resp.getWriter().print("名: " + username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.amusingoh.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>getc</servlet-name>
<servlet-class>com.amusingoh.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>getc</servlet-name>
<url-pattern>/getc</url-pattern>
</servlet-mapping>
6.5.2、獲取初始化引數
<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 context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print(url);
}
6.5.3、請求轉發
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("success");
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//轉發的請求路徑
requestDispatcher.forward(req,resp); //呼叫forward實作請求轉發
}
graph LR
a-->b-->c-->b-->a;
6.5.4、讀取資源檔案
Properties
- 在Java目錄下新建properties
- 在resources目錄下新建properties
發現:都唄打包到了同一個路徑下:classes,我們俗稱這個路徑為classpath;
思路:需要一個檔案流
db.properties
username= test
password=123456
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user+":"+pwd);
}
6.6、HttpServletResponse
web服務器接收到客戶的http請求,針對這個請求,分別創建一個代表請求的HttpServletRequest物件,代表回應的一個HttpServletResponse
- 如果由獲取客戶端請求過來的引數:找HttpServletRequest
- 如果要給客戶端回應一些資訊:找HttpServletResponse
6.6.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);
void setStatus(int var1);
回應的狀態碼
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;
6.6.2、下載檔案
-
向瀏覽器輸出訊息
-
下載檔案
1??要獲取下載檔案的路徑
2??下載的檔案名是啥
3??設定想辦法讓瀏覽器能夠支持下載我們需要的東西
4??獲取下載檔案的輸入流
5??創建緩沖區
6??獲取OutputStream物件
7??將FileOutputStream流寫入到buffer緩沖區
8??使用OutputStream將緩沖區中的資料輸出到客戶端
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.獲取下載檔案的路徑
String realPath = this.getServletContext().getRealPath("/WEB-INF/classes/哈哈、.png");
// String realPath="D:\\Picture\\Receipt4.png";
System.out.println("路徑:"+realPath);
// 2.知道下載的檔案名
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3.設定想辦法讓瀏覽器能夠支持(Context-Disposition)下載,中文檔案名要用URLEncoder.encode編碼,否則可能亂碼
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"utf-8"));
// 4.獲取下載檔案的輸入流
FileInputStream fileInputStream = new FileInputStream(realPath);
// 5.創建緩沖區
int len=0;
byte[] buffer = new byte[1024];
// 6.獲取OutputStream
ServletOutputStream outputStream = resp.getOutputStream();
// 7.將FileOutputStream流寫入buffer緩沖區,
// 使用OutputStream將緩沖區中的資料流輸出到客戶端
while ((len = fileInputStream.read(buffer)) > 0) {
outputStream.write(buffer,0,len);
}
// 8.關閉流
fileInputStream.close();
outputStream.close();
}
6.6.3、驗證碼功能
驗證碼怎么來的
- 前端實作
- 后端實作,需要用到Java的影像類,產生一個圖片
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//讓瀏覽器3秒自動重繪一次
resp.setHeader("refresh", "3");
//在記憶體中創建一個圖片
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(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) + "";
StringBuilder sb = new StringBuilder();
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);
}
}
請求轉發
graph LR a-->b-->c-->b-->a;6.6.4、實作重定向
graph LR a--1.向b請求web資源-->b--2.通知a訪問c-->a; a--3.發送請求-->c一個web資源b收到客戶端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", "/response/image");
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
*/
resp.sendRedirect("/response/image"); //重定向
}
重定向和請求轉發的區別:
相同點
- 頁面都會實作跳轉
不同點
- 請求轉發時,url 不會產生變化
- 重定向時,url 地址欄會發生變化
6.6.5、簡單實作登錄重定向
<%--這里提交的路徑,需要尋找到專案的路徑--%>
<%--${pageCentext.request.contextPath}代表當前的專案--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用戶名:<input type="text" name="username"> <br>
密碼:<input type="password" name="password"> <br>
<input type="submit">
</form>
@Override
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);
//重定向時一定要注意,路勁問題,否則404,req.getContextPath()獲取當前專案的path
resp.sendRedirect("/response/success.jsp");
}
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.amusingoh.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>success</title>
</head>
<body>
<h1>SUCCESS</h1>
</body>
</html>
6.7、HttpServletRequest
HttpServletRequest代表客戶端的請求,用戶通過HTTP協議訪問服務器,HTTP請求中的所有資訊會被封裝到HttpServletRequest,通過HttpServletRequest的方法,獲得客戶端的所有資訊
6.7.1、獲取前端傳遞的引數,請求轉發
String getParameter(String var1);
String[] getParameterValues(String var1);
EnumerationgetParameterNames();
Map<String, String[]> getParameterMap();
@Override
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[] hobbies = req.getParameterValues("hobbies");
System.out.println("======================");
//后臺接受中文亂碼問題
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbies));
System.out.println("===========================");
System.out.println(req.getContextPath());
//通過請求轉發
//這里的 / 代表當前的web應用
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
相同點
- 頁面都會實作跳轉
不同點
- 請求轉發時,url 不會產生變化 307
- 重定向時,url 地址欄會發生變化 302
7、Cookie、Session
7.1、會話
會話:用戶打開一個瀏覽器,點擊了超鏈接,訪問多個web資源,關閉瀏覽器,這個程序稱之為會話
有狀態會話:訪問web資源會留下記錄,記錄用戶訪問過此web資源
一個網站,怎么證明用戶來過
客戶端 服務端
- 服務端給客戶端一個信件,客戶端下次訪問服務端帶上信件就可以了;cookie
- 服務器登記用戶來過了,下次用戶再來時服務器匹配用戶;session
7.2、保存會話的兩種技術
cookie
- 客戶端技術(回應,請求)
session
- 服務器技術,利用這個技術,可以保存用戶的會話資訊,可以把資訊或資料放在Session中
7.3、Cookie
- 從請求中拿到cookie資訊
- 服務器回應給客戶端cookie
Cookie[] cookies = req.getCookies(); //獲得Cookie
cookie.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,最多存放20哥cookie;
- Cookie大小限制4kb;
- cookie瀏覽器上限300個
洗掉Cookie
- 不設定有效期,關閉瀏覽器自動失效
- 設定有效時間為0
編碼解碼:
URLEncoder.encode("頂癮喔","utf-8")
URLDecoder.decode(cookie.getValue(),"utf-8")
7.4、Session(重點)
什么是Session:
- 服務器會給每個用戶(瀏覽器)創建一個Session物件;
- 一個Session獨占一個瀏覽器,只要瀏覽器沒有關閉,這個Session就存在;
- 用戶登錄之后,整個網站它都可以訪問!-->保存用戶的資訊……
Session和Cookie的區別:
Session和Cookie的區別:
- Cookie是把用戶的資料寫給用戶的瀏覽器,瀏覽器保存
- Session把用戶的資料寫到用戶獨占的Session中,服務器保存(保存重要的資訊,減少服務器資源的浪費)
- Session物件由服務器創建
使用場景:
- 保存一個登錄用戶的資訊
- 購物車資訊
- 在整個網站中經常會使用的資料,我們將它保存在Session中
使用Session
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解決亂碼問題
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//給Session中存東西
session.setAttribute("name", new Person("頂癮喔",20));
//獲取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("JSESSION", "sessionId");
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
//得到Session
HttpSession session = req.getSession();
Person name = (Person) session.getAttribute("name");
System.out.println(name);
//得到Session
HttpSession session = req.getSession();
session.removeAttribute("name");
//手動注銷Session
session.invalidate();
會話自動過期:web.xml配置
<!--設定Session默認失效時間-->
<session-config>
<!--1分鐘后Session自動失效,以分鐘為單位-->
<session-timeout>1</session-timeout>
</session-config>
8、JSP
8.1、什么是JSP
Java Servlet Pages:Java服務器端頁面,也和Servlet一樣,用于動態Web技術
最大特點:
- 寫JSP就像在寫HTML
- 區別:
- HTML只給用戶提供靜態的資料
- JSP頁面中可以嵌入Java代碼,為用戶提供動態資料
8.2、JSP原理
思路:JSP是如何執行的
- 代碼層面沒有任何問題
- 服務器內部作業
tomcat中有一個work目錄
IDEA中使用tomcat,會在IDEA的tomcat中產生一個work目錄
瀏覽器向服務器發送請求,不管訪問什么資源,其實都是在訪問Servlet
JSP最終也會轉換成為一個Java類
JSP本質就是Servlet
//初始化
public void _jspInit(){
}
//銷毀
public void _jspDestroy(){
}
//JSPServlet
public void _jspServlet(.HttpServletRequest request,HttpServletResponse response)
- 判斷請求
- 內置的一些物件
final javax.servlet.jsp.PageContext pageContext; //頁面背景關系
javax.servlet.http.HttpSession session = null; //Session
final javax.servlet.ServletContext application; //applicationContext
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;charset=UTF-8"); //設定回應的頁面型別
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頁面中直接使用
在JSP頁面中:
只要是Java代碼就會原封不動的輸出
如果是HTML代碼,就會被轉換為:
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>title</title>\r\n");
out.write("</head>\t\n");
out.write("<body>\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
這樣的格式,輸出到前端
8.3、JSP基礎語法
任何語言都有字跡的語法,JSP作為Java技術的一種應用,它擁有自己的擴充語法(了解即可),Java所以語法都支持
8.3.1、JSP運算式
<%--JSP運算式
作用:用來將程式的輸出,輸出到客戶端
<%= 變數或運算式%>
--%>
<%= new java.util.Date()%>
8.3.2、JSP腳本片段
<%--JSP腳本片段--%>
<%
int num=0;
for (int i = 0; i < 100; i++) {
num+=i;
}
out.print("<h1>num="+num+"</h1>");
%>
腳本片段的再實作
<%
int x=10;
out.print(x);
%>
<p>this is JSP text</p>
<%
int y=20;
out.print("x="+x);
out.print("y="+y);
%>
<hr>
<%--在代碼嵌入HTML元素--%>
<%
for (int i = 0; i < 3; i++) {
%>
<h1>Hello world <%=i%></h1>
<%
}
%>
8.3.3、JSP宣告
<%--JSP宣告--%>
<%!
static {
System.out.println("Loading servlet");
}
private int global_var = 0;
public void amu{
System.out.println("進入了方法amu");
}
%>
JSP宣告:會被編譯到JSP生成Java的類中!其他的,就會被生成到_jspServlet方法中
在JSP嵌入Java代碼即可
<%%>
<%=%>
<%!%>
<%--注釋--%>
JSP的注釋不會在客戶端顯示,HTML就會
8.4、JSP指令
<%--@include 會將兩個頁面合二為一
頁面之間的變數會受影響
--%>
<%@include file="common/header.jsp" %>
<h1>網頁主體</h1>
<%@include file="common/footer.jsp" %>
<hr>
<%--jsp標簽
jsp:include 拼接頁面,本質還是三個頁面
頁面之間的變數不受影響
--%>
<jsp:include page="common/header.jsp"/>
<h1>網頁主體</h1>
<jsp:include page="common/footer.jsp"/>
8.5、四大作用域,九大內置物件
- PageContext 存東西
- Request 存東西
- Response
- Session 存東西
- Application 【ServletContext】 存東西
- Config 【ServletConfig】
- Out
- Page 不用了解
- Exception
pageContext.setAttribute("name1","頂癮喔1"); //保存的資料只在一個頁面中有效
request.setAttribute("name2","頂癮喔2"); //保存的資料只在一次請求中有效,請求轉發會攜帶這個資料
session.setAttribute("name3","頂癮喔3"); //保存的資料只在一次會話中有效,從打開瀏覽器到關閉瀏覽器
application.setAttribute("name4","頂癮喔4"); //保存的資料只在服務器中有效,從打開服務器到關閉服務器
request:客戶端向服務器發送請求,產生的資料,用戶看完就沒用了,比如:新聞、用戶看完沒用的
session:客戶端向服務器發送請求,產生的資料,用戶用完有會兒還有用,比如:購物測
application:客戶端向服務器發送請求,產生的資料,一個用戶用完了,其他用戶還可能使用,比如:聊天資料
8.6、JSP標簽、JSTL標簽、EL標簽
<!--JSTL運算式的依賴-->
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp.jstl/jstl-api -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--standard標簽庫-->
<!-- https://mvnrepository.com/artifact/taglibs/standard -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL運算式: ${}
- 獲取資料
- 執行運算
- 獲取web開發的常用物件
呼叫Java方法
jsp標簽
<%--jsp:include--%>
<%--
http://localhost:8080/jsptag.jsp?name=頂癮喔&age=20
--%>
<jsp:forward page="/jsptag2.jsp">
<jsp:param name="name" value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/頂癮喔"/>
<jsp:param name="age" value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/20"/>
</jsp:forward>
JSTL運算式
JSTL標簽庫的使用就是為了彌補HTML標簽的不足,它自定義了許多標簽來提供使用,標簽的功能和和Java代碼一樣
格式化標簽
SQL標簽
XML標簽
核心標簽(掌握部分)
JSTL標簽庫使用步驟
- 引入對應的 taglib
- 使用其中的方法
- 在Tomcat中也需要引入 jstl 的包,否則會報錯:JSTL決議希錯誤
c:if
<body>
<h4>if測驗</h4>
<hr>
<form action="coreif.jsp" method="get">
<%--
EL運算式獲取表單中的資料
${param.引數名}
--%>
<input type="text" name="username" value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/${param.username}">
<input type="submit" value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/登錄">
</form>
<%--判斷如果提交的用戶是管理員,著登錄成功--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
<c:out value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/管理員welcome"/>
</c:if>
<c:out value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/${isAdmin}"/>
</body>
c:choose c:when
<body>
<%--定義一個變數score,值為84--%>
<c:set var="score" value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/84"/>
<c:choose>
<c:when test="${score>=90}">
優秀
</c:when>
<c:when test="${score>=80}">
良好
</c:when>
<c:when test="${score>=70}">
一般
</c:when>
<c:when test="${score>=60}">
及格
</c:when>
<c:when test="${score<60}">
no及格
</c:when>
</c:choose>
</body>
c:forEach
<body>
<%
ArrayList<String> people = new ArrayList<>();
people.add(0, "張三");
people.add(1, "李四");
people.add(2, "王五");
people.add(3, "趙六");
people.add(4, "田七");
request.setAttribute("list",people);
%>
<%--
var, 每次遍歷出來的變數
items, 要遍歷的物件
begin, 開始位置
end, 結束位置
step, 步長
--%>
<c:forEach var="people1" items="${list}">
<c:out value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/${people1}"/> <br>
</c:forEach>
<hr>
<c:forEach var="people1" items="${list}" begin="2" end="4" step="2">
<c:out value="https://www.cnblogs.com/amusingoh/archive/2023/05/30/${people1}"/> <br>
</c:forEach>
</body>
9、JavaBean
物體類
JavaBean有特定的寫法:
- 必須要有一個無參構造
- 屬性必須私有化
- 必須有對應的 get/set 方法
一般用來和資料庫的欄位做映射 ORM;
ORM:物件關系映射
- 表-->類
- 欄位-->屬性
- 行記錄-->物件
id | name | age | address |
---|---|---|---|
1 | 頂癮喔1 | 10 | 城中 |
2 | 頂癮喔2 | 20 | 魚峰 |
3 | 頂癮喔3 | 30 | 柳東 |
class People{
private int id;
private String name;
private in age;
private String address;
}
class A{
new People(1,"頂癮喔1",10,"城中");
new People(2,"頂癮喔2",20,"魚峰");
new People(3,"頂癮喔3",30,"柳東");
}
- 過濾器
- 檔案上傳
- 郵件發送
- JDBC復習:如何使用JDBC,JDBC crud,jdbc事務
10、MVC三層架構
什么是MVC:Model View Controller 模型、試圖、控制器
10.1、早些年
用戶直接訪問控制層,控制層就可以直接操作資料庫
servlet--CRUD-->資料庫
弊端:程式十分臃腫,不利于維護
servlet的代碼中:處理請求、回應、試圖跳轉、處理JDBC、處理業務代碼、處理邏輯代碼架構:沒有什么是加已成解決不了的
10.2、MVC三層架構
Model
- 業務處理:業務邏輯(Service)
- 資料持久層:CRUD(Dao)
View
- 展示資料
- 提供鏈接發起Servlet請求(a,form,img...)
Controller (Servlet)
-
接收用戶的請求:(req:請求引數、Session資訊...)
-
交給業務層處理對應的代碼
-
控制視圖的跳轉
登錄--->接收用戶的登錄請求--->處理用戶的請求(獲取用戶登錄的引數,username,password)--->交給業務層處理登錄業務(判斷用戶名密碼是否正確:事務)--->Dao層查詢用戶名和密碼是否正確--->資料庫
11、Filter(重點)
Filter:過濾器,用來過濾網站的資料
- 處理中文亂碼
- 登錄驗證
Filter開發步驟:
-
導包
導包不要導錯
import javax.servlet.Filter
-
撰寫過濾器
public class CharacterEncodingFilter implements Filter { //初始化:web服務器啟動,就已經初始化了,隨時等待過濾物件的出現 @Override public void init(FilterConfig filterConfig) throws ServletException { System.out.println("CharacterEncodingFilter初始化"); } /** * Chain: 鏈 * 過濾中的所有代碼,在過濾特定請求的時候都會執行 * 必須要讓過濾器繼續同行 */ @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { servletResponse.setContentType("text/html;charset=utf-8"); System.out.println("CharacterEncodingFilter執行前,,,"); //讓我們的請求繼續走,如果不屑,程式到這里就會被攔截停止 filterChain.doFilter(servletRequest,servletResponse); System.out.println("CharacterEncodingFilter執行后,,,"); } //銷毀:web服務器關閉時,過濾器會銷毀 @Override public void destroy() { System.out.println("CharacterEncodingFilter銷毀"); } }
-
在web.xml中配置Filter
<filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>com.amusingoh.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <!--只要是/servlet的任何請求,會經過這個過濾器--> <url-pattern>/servlet/*</url-pattern> </filter-mapping>
12、監聽器
實作一個監聽器的介面
-
撰寫一個監聽器
實作監聽器的介面
public class OnlineCounterListener implements HttpSessionListener { /** * 創建session監聽 * 一旦創建Session就會觸發一次這個事件 */ @Override public void sessionCreated(HttpSessionEvent se) { ServletContext servletContext = se.getSession().getServletContext(); System.out.println(se.getSession().getId()); Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount"); if (onlineCount == null) { onlineCount = new Integer(1); } else { int count = onlineCount.intValue(); onlineCount = new Integer(count + 1); } servletContext.setAttribute("OnlineCount",onlineCount); } /** * 銷毀session監聽 * 一旦銷毀Session就會觸發一次這個事件 * Session銷毀: * 1.手動銷毀 getSession().invalidate(); * 2.自動銷毀 */ @Override public void sessionDestroyed(HttpSessionEvent se) { ServletContext servletContext = se.getSession().getServletContext(); Integer onlineCount = (Integer) servletContext.getAttribute("OnlineCount"); if (onlineCount == null) { onlineCount = new Integer(0); } else { int count = onlineCount.intValue(); onlineCount = new Integer(count - 1); } servletContext.setAttribute("OnlineCount",onlineCount); } }
-
web.xml中注冊監聽器
<!--注冊監聽器--> <listener> <listener-class>com.amusingoh.listener.OnlineCounterListener</listener-class> </listener>
-
查看使用情況
13、過濾器、監聽器常見應用
監聽器:GUI編程中經常使用
用戶登錄之后才能進入主頁,用戶注銷后就不能進入主頁了
- 用戶登錄之后,向session中放入用戶的資料
- 進入主頁的時候要判斷用戶是否已經登錄, 要求:在過濾器中實作
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
if (request.getSession().getAttribute(Constant.USER_SESSION) == null) {
response.sendRedirect("/javaweb_filter/error.jsp");
}
filterChain.doFilter(servletRequest,servletResponse);
14、JDBC
什么是JDBC:Java連接資料庫
需要jar的包支持
- java.sql
- javax.sql
- mysql-conneter-java...連接驅動(必須要匯入)
建表陳述句
use test;
create table users(
id int primary key,
`name` varchar(30),
`password` varchar(40),
email varchar(40),
birthday date
) engine=innodb, character set =utf8,collate=utf8_general_ci;
insert into users(id, `name`, `password`, email, birthday)
values (1, '張三', '123456', '[email protected]', '2000-01-01'),
(2, '李四', '123456', '[email protected]', '2000-01-02'),
(3, '王五', '123455', '[email protected]', '2000-01-03');
select * from users;
匯入資料庫依賴
<!--mysql的驅動-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
JDBC固定操作
- 加載驅動
- 連接資料庫
- 向資料庫發送SQL的物件Statement:CRUD
- 撰寫SQL(根據業務,不同的SQL)
- 執行生氣了
- 關閉連接
資源檔案 db.properties
driver=com.mysql.cj.jdbc.Driver
# useUnicode=true&characterEncoding=utf-8 解決中文亂碼問題
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
username=test
password=123456
JDBC工具類JdbcUtils.java
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(inputStream);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
System.out.println(url);
username = properties.getProperty("username");
password = properties.getProperty("password");
//驅動只用加載一次
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取鏈接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
//釋放鏈接資源
public static void release(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
TestJdbc.java
public class TestJdbc {
public static void main(String[] args) {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
//加載驅動
//連接資料庫
conn = JdbcUtils.getConnection();
//向資料庫發送SQL的物件Statement : CRUD
st = conn.createStatement();
//撰寫SQL
String sql = "select * from users;";
//執行查詢SQL,回傳一個ResultSet : 結果集
rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("birthday="+rs.getObject("birthday"));
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//關閉連接,釋放資源(一定要做) 先開后關
JdbcUtils.release(conn,st,rs);
}
}
}
預編譯SQL
public class TestJdbc2 {
public static void main(String[] args) throws Exception {
//配置資訊
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=UTC";
String username = "test";
String password = "123456";
//1.加載驅動
Class.forName("com.mysql.cj.jdbc.Driver");
//2.連接資料庫
Connection connection = DriverManager.getConnection(url, username, password);
//3.撰寫SQL
String sql = "insert into users(id,`name`,`password`,email,birthday) values(?,?,?,?,?);";
//4.預編譯
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,4);
preparedStatement.setString(2,"頂癮喔");
preparedStatement.setString(3,"123456");
preparedStatement.setString(4,"[email protected]");
preparedStatement.setDate(5, new Date(new java.util.Date().getTime()));
//5.執行SQL
int i = preparedStatement.executeUpdate();
if (i > 0) {
System.out.println("inset success");
}
//6.關閉連接
preparedStatement.close();
connection.close();
}
}
事務
要么都成功,要么都失敗
ACID原則:保證資料的安全
開啟事務
事務提交 commit()
事務回滾 rollback()
事務關閉
Junit單元測驗
依賴
<!--單元測驗-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
簡單使用
@Test注解只有在方法上有效,只要加了這個注解的方法,就可以直接運行
@Test
public void test() {
System.out.println("Hello");
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/553825.html
標籤:其他
上一篇:新版idea快捷鍵總結學習----(用于java開發模式)
下一篇:返回列表