JavaWeb
靜態web資源(如html 頁面):指web頁面中供人們瀏覽的資料始終是不變。
動態web資源:指web頁面中供人們瀏覽的資料是由程式產生的,不同時間點訪問web頁面看到的內容各不相同。
靜態web資源開發技術:HTML、CSS、JavaScript。
動態web資源開發技術:JSP/Servlet、ASP、PHP等。在Java中,動態web資源開發技術統稱為Java Web。
Web伺服器
技術講解
ASP:微軟,國內最早流行的是ASP,在HTML中嵌入了VB的指令碼,ASP+COM,維護成本高。
PHP:開發速度很快,功能很強大,跨平臺,程式碼簡單,但是無法承載大訪問量的情況(侷限性)。
JSP/Servlet:sun公司主推的B/S架構,基於java語言,可以承載三高問題(高併發,高可用,高效能)。
B/S:瀏覽器和伺服器;C/S:客戶端和伺服器。
Web伺服器
伺服器用來處理使用者的一些請求,響應給使用者一些資料。
IIS:微軟的,主要用於ASP,Windows中自帶的伺服器。
Tomcat:Tomcat是Apache 軟體基金會(Apache Software Foundation)的Jakarta 專案中的一個核心專案,最新的Servlet 和JSP 規範總是能在Tomcat 中得到體現,Tomcat 5支援最新的Servlet 2.4 和JSP 2.0 規範。因為Tomcat 技術先進、效能穩定,而且免費,因而深受Java 愛好者的喜愛並得到了部分軟體開發商的認可,成為目前比較流行的Web 應用伺服器。
Tomcat 伺服器是一個免費的開放原始碼的Web 應用伺服器,屬於輕量級應用伺服器,在中小型系統和併發訪問使用者不是很多的場合下被普遍使用,是開發和除錯JSP 程式的首選。對於一個JavWeb初學者來說,是最好的選擇。
Tomcat 實際上執行JSP 頁面和Servlet。
Tomcat
安裝Tomcat:官網下載(http://tomcat.apache.org/)壓縮包,解壓至指定目錄(可選:配置環境變數)。
在bin目錄下點選startup.bat啟動,在瀏覽器網址欄輸入localhost:8080測試。
網站是如何進行訪問的:
- 輸入使用者名稱,回車
- 檢查本機的C:\Windows\System32\drivers\etc\hosts配置檔案有沒有這個域名的對映
- 有就直接返回對應的ip地址
- 沒有就去DNS(全世界的域名管理)伺服器上尋找,找到就返回
Http
Http(超文字傳輸協議):http是一個簡單的請求-響應協議,它通常執行在TCP之上。(預設埠:80)
Https:443
- Http1.0:客戶端可以與web伺服器連線後,只能獲得一個web資源,斷開連線。
- Http1.1:客戶端可以與web伺服器連線後,可以獲得多個web資源。
Http請求
- 客戶端----發請求----伺服器
百度為例:
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
Http響應
- 伺服器----發請求----客戶端
百度響應:
Cache-Control: private 快取控制
Connection: keep-alive 保持連線
Content-Encoding: gzip 編碼
Content-Type: text/html;charset=utf-8 型別
請求方式:
get:請求能夠攜帶的引數比較少,大小有限制,會在瀏覽器位址列顯示引數的內容,不安全,但是高效。
post:請求能夠攜帶的引數沒有限制,大小沒有限制,不會再瀏覽器位址列顯示引數的內容,安全,但不高效。
響應狀態碼:
200:請求響應成功
3**:請求重定向
404:找不到資源
500:伺服器程式碼錯誤,502:閘道器錯誤
Maven
Maven:專案架構管理工具,自動匯入jar包(約定大於配置)。
下載Maven後解壓,配置環境變數,將bin目錄的路徑配置到path中,在cmd中輸入mvn-version,檢視是否配置成功
在conf目錄下setting的
在conf目錄下setting的
<!-- 設定阿里雲映象-->
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>https://maven.aliyun.com/repository/public/</url>
</mirror>
pom.xml
pom.xml:maven的核心配置檔案
由於maven的約定大於配置,我們之後寫的配置檔案可能無法匯出或者無法生效,就需要在maven配置下面配置resouce。
Servlet
servlet就是sun公司開發動態web的一門技術,sun公司在API中提供了一個介面叫Servlet,如果需要開發一個Servlet程式,需要編寫一個類去實現Servlet介面,再把開發好的java類部署到web伺服器中。
HelloServlet
sun公司有兩個Servlet介面的預設實現類:HttpServlet和GenericServlet
-
構建一個maven專案,刪除裡面的src專案,以後就直接新建model,這個空的工程就是Maven的主工程。
-
關於Maven父子工程的理解:
父專案中會有
<modules>
<module>servlet-01</module>
</modules>
子專案中有
<parent>
<artifactId>javaweb-02-servlet</artifactId>
<groupId>com.zr</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
-
Maven環境優化:修改web.xml為最新的,將Maven的結構搭建完整。
-
編寫一個普通類,實現Servlet介面,繼承HttpServlet。
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter(); //響應流
writer.println("Hello Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
- 編寫Servlet的對映:我們寫的是java程式,但是要通過瀏覽器訪問,而瀏覽器要連線web伺服器,所以我們要在web伺服器註冊我們寫的Servlet,還需要給它一個瀏覽器能夠訪問的路徑。
<!--註冊Servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.zr.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet請求路徑-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 配置Tomcat
- 啟動測試
Servlet原理
Servlet是由Web伺服器呼叫,web伺服器收到請求後,會:
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>/hello2</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello3</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>
-
一個Servlet可以指定一些字尾或者字首對映路徑
<!--*前面不能加任何對映的路徑--> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>*.zzr</url-pattern> </servlet-mapping>
優先順序問題:
指定了固有的對映路徑,優先順序最高,找不到就會走預設的處理請求。
處理404頁面
<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.zr.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
ServletContext
web容器在啟動的時候,它會為每一個web程式都建立一個ServletContext物件,它代表了當前的 web應用。
-
共享資料
我在這個Servle中儲存的資料可以在另外一個Servle中拿到
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("hello"); //this.getInitParameter(); 初始化引數 //this.getServletConfig(); Servlet的配置 //this.getServletContext(); Servlet上下文 ServletContext context = this.getServletContext(); String username = "週週"; context.setAttribute("username",username);//將一個資料儲存在ServletContext中 } }
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.setCharacterEncoding("utf-8"); resp.setContentType("text/html"); resp.getWriter().println("名字:"+username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } }
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.zr.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>get</servlet-name> <servlet-class>com.zr.servlet.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>get</servlet-name> <url-pattern>/get</url-pattern> </servlet-mapping>
測試訪問結果
-
獲取初始化引數
<!--配置一個web應用的初始化引數--> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybaits</param-value> </context-param> <servlet> <servlet-name>gp</servlet-name> <servlet-class>com.zr.servlet.ServletDemo03</servlet-class> </servlet> <servlet-mapping> <servlet-name>gp</servlet-name> <url-pattern>/gp</url-pattern> </servlet-mapping>
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.getWriter().println(url); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
-
請求轉發
public class ServletDemo04 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//轉發的請求路徑 requestDispatcher.forward(req,resp);//轉發 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doPost(req, resp); } }
<servlet> <servlet-name>sd4</servlet-name> <servlet-class>com.zr.servlet.ServletDemo04</servlet-class> </servlet> <servlet-mapping> <servlet-name>sd4</servlet-name> <url-pattern>/sd4</url-pattern> </servlet-mapping>
-
讀取資原始檔
properties
- 在Java目錄下新建propreties(需要在pom.xml下配置resources)
- 在resources目錄下新建properties
發現都被打包到了target下的class目錄下,我們稱這個路徑為類路徑classpath。
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().println("username:"+username); resp.getWriter().println("password:"+password); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
<servlet> <servlet-name>sd5</servlet-name> <servlet-class>com.zr.servlet.ServletDemo05</servlet-class> </servlet> <servlet-mapping> <servlet-name>sd5</servlet-name> <url-pattern>/sd5</url-pattern> </servlet-mapping>
<build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <exclude>**/*.properties</exclude> <exclude>**/*.xml</exclude> </excludes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
//檔案 db.properties username=root password=123456
HttpServletResponse
web伺服器接收到客戶端的http請求,針對這個請求,分別建立一個代表請求的HttpServletRequest物件,代表響應一個HttpServletResponse。
- 如果要獲取客戶端請求過來的引數:HttpServletRequest
- 如果要給客戶端響應一些資訊:HttpServletResponse
簡單分類
負責向瀏覽器傳送資料的方法
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_OK = 200;
...
int SC_MULTIPLE_CHOICES = 300;
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_INTERNAL_SERVER_ERROR = 500;
int SC_BAD_GATEWAY = 502;
下載檔案
-
向瀏覽器輸出訊息
-
下載檔案
- 獲取下載檔案的路徑
- 下載的檔名
- 讓瀏覽器支援下載我們需要的東西
- 獲取下載檔案的輸入流
- 建立緩衝區
- 獲得OutputStream物件
- 將FileOutputStream流寫入到buffer緩衝區
- 將OutputStream緩衝區中的物件輸出到客戶端
public class FileServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //1. 獲取下載檔案的路徑 String realPath = "D:\\IDEACode\\javaweb-02-servlet\\response\\src\\main\\resources\\1.PNG"; System.out.println("下載檔案的路徑:"+realPath); //2. 下載的檔名 String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); //3. 讓瀏覽器支援下載我們需要的東西 resp.setHeader("Content-Disposition","attachment;filename="+fileName); //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(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
驗證碼功能
如何生成驗證碼:
- 前端
- 後端:需要用Java的圖片類,生成一個圖片
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//讓瀏覽器5秒重新整理一次
resp.setHeader("refresh","5");
//建立圖片
BufferedImage image = new BufferedImage(300,60,BufferedImage.TYPE_INT_RGB);
//得到圖片
Graphics g = image.getGraphics(); //筆
//設定圖片的背景顏色
g.setColor(Color.green);
g.fillRect(0,0,300,60);
//給圖片寫資料
g.setColor(Color.magenta);
g.setFont(new Font(null,Font.BOLD,70));
g.drawString(makeNum(),0,60);
//瀏覽器以圖片的形式開啟
resp.setContentType("image/png");
//網站存在快取。不讓瀏覽器快取
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把圖片顯示出來
boolean write = ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成隨機數
private String makeNum(){
Random random = new Random();
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);
}
}
<!--註冊Servlet-->
<servlet>
<servlet-name>image</servlet-name>
<servlet-class>com.zr.servlet.ImageServlet</servlet-class>
</servlet>
<!--Servlet請求路徑-->
<servlet-mapping>
<servlet-name>image</servlet-name>
<url-pattern>/image</url-pattern>
</servlet-mapping>
實現重定向
void sendRedirect(String var1) throws IOException;//重定向
public class RedirectServlet extends HttpServlet {
@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);
}
}
配置web.xml測試
重定向和轉發的區別:
相同點:頁面都會發生跳轉
不同點:
- 請求轉發的時候,url不會改變 307
- 重定向的時候,url位址列會發生變化 302
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<h2>Hello World!</h2>
<%--提交的路徑需要尋找到當前專案的路徑--%>
<form action="${pageContext.request.contextPath}/login" method="post">
使用者名稱:<input type="text" name="username"><br>
密碼 :<input type="password" 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>
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:"+username);
System.out.println("password:"+password);
resp.sendRedirect("/r/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!--註冊Servlet-->
<servlet>
<servlet-name>test</servlet-name>
<servlet-class>com.zr.servlet.RequestTest</servlet-class>
</servlet>
<!--Servlet請求路徑-->
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
HttpServletRequest
HttpServletRequest代表客戶端的請求,使用者通過http協議訪問伺服器,http請求中的所有的資訊會被封裝到HttpServletRequest,通過這個HttpServletRequest的方法,獲得客戶端的所有資訊。
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(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));
//請求轉發
//這裡的/代表當前的web應用
req.getRequestDispatcher("/success.jsp").forward(req,resp);
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登入</title>
</head>
<body>
<h1>登入</h1>
<div style="text-align: center">
<form action="${pageContext.request.contextPath}/login" method="post">
使用者名稱:<input type="text" name="username"><br>
密碼:<input type="password" name="password"><br>
愛好:
<input type="checkbox" name="hobbys" value="唱歌">唱歌
<input type="checkbox" name="hobbys" value="女孩">女孩
<input type="checkbox" name="hobbys" value="寫字">寫字
<input type="checkbox" name="hobbys" value="程式碼">程式碼
<br>
<input type="submit">
</form>
</div>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登入成功</h1>
</body>
</html>
web.xml
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>com.zr.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
Cookie, Session
cookie
- 客戶端技術(響應,請求)
session
- 伺服器技術,可以儲存使用者的會話資訊,我們可以把資訊或資料放在session中
常見應用:網站登入一次後,下次可以直接進入。
Cookie
從請求中拿到cookie資訊
伺服器響應給客戶端cookie
//儲存使用者上一次訪問的時間
public class CookieDemo01 extends HttpServlet {
@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");
PrintWriter out= resp.getWriter();
//cookie,伺服器端從客戶端獲取
Cookie[] cookies = req.getCookies();//返回陣列,cookie可能存在多個
//判斷cookie是否存在
if (cookies!=null){
//如果存在
out.write("你上一次訪問的時間是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//獲取cookie的名字
if (cookie.getName().equals("lastlogintime")){
//獲取cookie中的值
long lastlogintime = Long.parseLong(cookie.getValue());
Date date = new Date(lastlogintime);
out.write(date.toLocaleString());
}
}
}else{
out.write("這是你第一次訪問本站!");
}
//伺服器給客戶端發一個cookie
Cookie cookie = new Cookie("lastlogintime", System.currentTimeMillis()+"");
//有效期為1天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<servlet>
<servlet-name>CookieDemo01</servlet-name>
<servlet-class>com.zr.servlet.CookieDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo01</servlet-name>
<url-pattern>/c1</url-pattern>
</servlet-mapping>
cookie:一般會儲存在本地的使用者目錄下appdata;
- 一個cookie只能儲存一個資訊
- 一個web站點可以給瀏覽器傳送多個cookie,最多存放20個cookie
- cookie的大小有限制4kb
- cookie瀏覽器上限300個
刪除cookie
- 不設定有效期,關閉瀏覽器,自動失效
- 設定有效期時間為0
Session
session:
-
伺服器會給每一個使用者(瀏覽器)建立一個session物件
-
一個session獨佔一個瀏覽器,只要瀏覽器沒有關閉,這個session就存在
-
使用者登入之後,整個網站都可以訪問,-->儲存使用者的資訊
session和cookie的區別:
- cookie是把使用者的資料寫給使用者的瀏覽器,瀏覽器儲存(可以儲存多個)
- session是把資料寫到使用者獨佔的session中,伺服器儲存(儲存重要的資訊,減少資源的浪費)
- session物件由伺服器建立
session儲存資料
package com.zr.pojo;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class SessionDemo01 extends HttpServlet {
@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("週週",1));
//獲得session的id
String id = session.getId();
//判斷session是不是新建立的
if(session.isNew()){
resp.getWriter().write("session建立成功,ID:"+ id);
}else {
resp.getWriter().write("session已經存在,ID:"+ id);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class SessionDemo02 extends HttpServlet {
@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();
Person person = (Person) session.getAttribute("name");
System.out.println(person);
}
@Overridejava
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>SessionDemo01</servlet-name>
<servlet-class>com.zr.servlet.SessionDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo01</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SessionDemo02</servlet-name>
<servlet-class>com.zr.servlet.SessionDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo02</servlet-name>
<url-pattern>/s2</url-pattern>
</servlet-mapping>
session手動登出
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手動登出session
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
session自動登出
<!--設定session登出時間-->
<session-config>
<!--1分鐘後自動失效-->
<session-timeout>1</session-timeout>
</session-config>
JSP
什麼是JSP
jsp:java server pages,Java伺服器端介面,和servlet一樣,用於開發動態web技術。
特點
- 寫jsp就像寫html
- 區別
- html只給使用者提供靜態的資料
- jsp頁面可以嵌入Java程式碼,為使用者提供動態資料
jsp原理
在伺服器內部,tomcat中有一個work目錄,jsp最終被轉化成了Java類, jsp本質就是一個servlet。
index_jsp.java原始碼
//初始化
public void _jspInit() {
}
//銷燬
public void _jspDestroy() {
}
//jspService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.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 respons //響應
輸出頁面前增加的程式碼
response.setContentType("text/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中直接使用
在jsp頁面中,java程式碼會原封不動的輸出,如果是html程式碼就會被轉化為out.write(".....");
JSP基礎語法
任何語言都有自己的語法 ,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>
<%
int y=20;
out.print(y);
%>
<%--在程式碼中嵌入html元素--%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>helloworld<%=i%></h1>
<%
}
%>
jsp宣告
<%!
static {
System.out.println("loding...");
}
private int globalvar=0;
public void jspInit(){
System.out.println("進入了方法");
}
%>
JSP宣告:會被編譯到jsp生成的Java類中。其它的會被生成到jspServer方法中。
JSP的註釋不會在客戶端原始碼顯示,HTML的註釋會在哭護短原始碼顯示。
定製錯誤頁面
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<img src="img/500.jpg" alt="500">
</body>
</html>
JSP指令
<%@page% args...>
<%@include file=""%>
<%--會將頁面合二為一--%>
<%@include file="common/header.jsp"%>
<h1>主體</h1>
<%@include file="common/footer.jsp"%>
<hr>
<%--jsp標籤 拼接頁面--%>
<jsp:include page="common/header.jsp"/>
<h1>主體</h1>
<jsp:include page="common/footer.jsp"/>
九大內建物件
- 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");//儲存的資料在伺服器中有效,開啟伺服器到關閉伺服器
%>
<%--通過pageContext取值--%>
<%
//通過尋找的方式
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
String name5 = (String) pageContext.findAttribute("name5");//不存在
%>
<%--使用EL表示式輸出 ${}--%>
<h1>取出的值為:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
<hr>
<%=name5%>
request:客戶端向伺服器傳送資料,產生的資料,使用者看完就沒用了,比如:新聞
session:客戶端向伺服器傳送資料,產生的資料,使用者用完一會還會用,比如:購物車
application:客戶端向伺服器傳送資料,產生的資料,一個使用者使用完了,其它使用者可能還用,比如:聊天記錄
JSP標籤,JSTL標籤,EL表示式
<!-- jstl表示式的依賴 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard標籤庫 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
EL表示式:${}
- 獲取資料
- 執行運算
- 獲取web開發的常用物件
JSP標籤:
<%--jsp:include--%>
<%--轉發時候攜帶引數--%>
<jsp:forward page="/jsptag2.jsp">
<jsp:param name="name" value="zr"/>
<jsp:param name="age" value="22"/>
</jsp:forward>
JSTL表示式
JSTL標籤庫的使用就是為了彌補HTML標籤的不足;它自定義了許多的標籤,可以供我們使用,標籤的功能和Java程式碼一樣。
核心標籤(掌握),格式化標籤,SQL標籤,XML標籤
<%--引入JSTL核心標籤庫--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
JSTL標籤使用步驟
- 引入對應的taglib
- 使用其中的方法
- tomcat中需要引入JSTL的包,否則會報JSTL解析錯誤
c:if
<body>
<h1>if測試</h1>
<hr>
<form action="coreif.jsp" method="get">
<%-- EL表示式獲取表單中的資料
${param.引數名}
--%>
<input type="text" name="username" value="${param.username}"/>
<input type="submit" name="登入">
</form>
<%-- 判斷如果提交的使用者是管理員,則登入成功--%>
<c:if test="${param.username=='admin'}" var="isadmin">
<c:out value="管理員歡迎你!"/>
</c:if>
<c:out value="${isadmin}"/>
</body>
c:choose
<body>
<%--定義一個變數score 值為88--%>
<c:set var="score" value="88"/>
<c:choose>
<c:when test="${score>=90}">
你的成績優秀!
</c:when>
<c:when test="${score>=80}">
你的成績良好!
</c:when>
<c:when test="${score>=60}">
你的成績一般!
</c:when>
<c:when test="${score<=60}">
你的成績不合格!
</c:when>
</c:choose>
</body>
c:forEach
<body>
<%
ArrayList<String> people = new ArrayList<String>();
people.add(0,"張三");
people.add(1,"李四");
people.add(2,"王五");
people.add(3,"趙六");
people.add(4,"田七");
request.setAttribute("list",people);
%>
<%-- var 每一次遍歷的變數 items每次遍歷的物件--%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"/><br>
</c:forEach>
<hr>
<%--開始 結束 步長--%>
<c:forEach var="people" items="${list}" begin="2" end="4" step="2">
<c:out value="${people}"/><br>
</c:forEach>
</body>
JavaBean
實體類
JavaBean有特定的寫法:
- 必須要有一個無參構造
- 屬性必須私有化
- 必須有對應的get/set方法
一般用來和資料庫的欄位做對映 ORM;
ORM物件關係對映
- 表--->類
- 欄位--->屬性
- 行記錄--->物件
people表
id | name | age | address |
---|---|---|---|
1 | 周1 | 18 | 武漢 |
2 | 周2 | 22 | 廣州 |
3 | 周3 | 100 | 佛山 |
建立資料庫相應的欄位後建立java實體類
package com.zr.pojo;
//實體類 一般是和資料庫中的表結構一一對應的
public class People {
private int id;
private String name;
private int age;
private String address;
public People() {
}
public People(int id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
<%@ page import="com.zr.pojo.People" %><%--
Created by IntelliJ IDEA.
User: zr
Date: 2020/10/11
Time: 22:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
// People people = new People();
// people.setAddress();
// people.setId();
// people.setAge();
// people.setName();
//和下面的等價
%>
<jsp:useBean id="people" class="com.zr.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="武漢"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="18"/>
<jsp:setProperty name="people" property="name" value="小周"/>
姓名:<jsp:getProperty name="people" property="name"/>
id:<jsp:getProperty name="people" property="id"/>
年齡:<jsp:getProperty name="people" property="age"/>
地址:<jsp:getProperty name="people" property="address"/>
</body>
</html>
MVC三層架構
MVC:model,view,controller 模型檢視控制器
Model
- 業務處理,業務邏輯(Service)
- 資料持久層,CRUD(Dao)
View
- 展示資料
- 提供操作發起Servlet請求(a,form,img ....)
Controller(Servlet)
- 接收請求,(req:請求引數,session資訊...)
- 交給業務層處理相應的程式碼
- 控制檢視的跳轉
登入--->接收使用者的登入請求--->處理使用者的請求(獲得使用者登入的引數 username password)--->交給業務層處理登入的業務(判斷使用者名稱密碼是否正確)--->Dao層查詢使用者密碼是否正確--->資料庫
過濾器
Filter:過濾器,用來過濾網站的資料:
- 處理中文亂碼
- 登入驗證...
Filter編寫:先配置Servlet,jsp依賴
實現Filter(Servlet下的)介面,重寫對應的方法
public class CharacterEncodingFilter implements Filter {
//初始化 web伺服器啟動就初始化了,隨時等待監聽物件出現
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
//Chain :鏈
/*
1,過濾器中的所有程式碼,在過濾特定請求時都會執行
2,必須要讓過濾器過濾同行
chain.doFilter(request,response);
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;character=UTF-8");
System.out.println("CharacterEncodingFilter執行前....");
chain.doFilter(request,response);//讓我們的請求繼續走 如果不寫,程式被攔截停止
System.out.println("CharacterEncodingFilter執行後....");
}
//銷燬 web伺服器關閉的時候,過濾器銷燬
public void destroy() {
System.out.println("CharacterEncodingFilter銷燬");
}
}
servlet顯示亂碼
public class ShowServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//resp.setCharacterEncoding("utf-8");
//resp.setContentType("text/html");
resp.getWriter().write("你好世界");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
配置web.xml
<servlet>
<servlet-name>showServlet</servlet-name>
<servlet-class>com.zr.servlet.ShowServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>showServlet</servlet-name>
<url-pattern>/servlet/show</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>showServlet</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncoding</filter-name>
<filter-class>com.zr.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncoding</filter-name>
<!--只要是/servlet的任何請求,都會經過這個過濾器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
監聽器
統計網站線上人數:
實現一個監聽器的介面
//統計網站線上人數,統計Session
public class OnlineCountListener implements HttpSessionListener {
//建立Session監聽
//一旦建立一個Session就會觸發一次這個事件
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(1);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//銷燬Session監聽
//一旦銷燬一個Session就會觸發一次這個事件
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if (onlineCount==null){
onlineCount = new Integer(0);
}else {
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
}
/*
Session銷燬
1.手動銷燬 se.getSession().invalidate();
2.自動銷燬 xml中配置<session-config>
*/
顯示線上人數
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>當前有<span style="color: hotpink"><%=this.getServletConfig().getServletContext().getAttribute("OnlineCount")%></span>人線上</h1>
</body>
</html>
配置web.xml
<!--註冊監聽器-->
<listener>
<listener-class>com.zr.listener.OnlineCountListener</listener-class>
</listener>
過濾器,監聽器常見應用
監聽器GUI程式設計中經常使用
GUI應用
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame("中秋快樂!"); //新建一個窗體
Panel panel = new Panel(null); //皮膚
frame.setLayout(null); //設定窗體的佈局
frame.setBounds(300,300,500,500); //座標
frame.setBackground(new Color(0,0,255)); //背景顏色
panel.setBounds(50,50,300,300);
panel.setBackground(new Color(0,255,255));
frame.add(panel);
frame.setVisible(true);
//監聽事件,監聽關閉事件
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
使用者登入後才能進入主頁,登出後不能進入主頁
1.使用者登入之後向session中放入使用者的資料
2.進入主頁的時候判斷使用者是否登入,要求在過濾器中實現login.jsp
login.jsp(web包下)
<body>
<h1>登入</h1>
<form action=" /servlet/login" method="post">
<input type="text" name="username">
<input type="submit">
</form>
</body>
success.jsp(web/sys包下)
<body>
<h1>主頁</h1>
<a href="/servlet/loginout">登出</a>
</body>
error.jsp(web包下)
<body>
<h1>錯誤</h1>
<h3>使用者名稱錯誤</h3>
<a href="/login.jsp">返回登入頁面</a>
</body>
Login
public class login extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//獲取前端請求的引數
String username = req.getParameter("username");
if (username.equals("admin")){
req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
}else {
resp.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
LoginOut
public class LoginOut extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute("USER_SESSION");
if (user_session!=null){
req.getSession().removeAttribute("USER_SESSION");
resp.sendRedirect("/login.jsp");
}else {
resp.sendRedirect("/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
SysFilter:過濾器
public class SysFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
filterChain.doFilter(request, response);
if (req.getSession().getAttribute("USER_SESSION")==null){
resp.sendRedirect("/error.jsp");
}
}
public void destroy() {
}
}
web.xml
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.zr.servlet.login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/servlet/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>loginOut</servlet-name>
<servlet-class>com.zr.servlet.LoginOut</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginOut</servlet-name>
<url-pattern>/servlet/loginout</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncoding</filter-name>
<filter-class>com.zr.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncoding</filter-name>
<!--只要是/servlet的任何請求,都會經過這個過濾器-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.zr.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<!--只要是/sys的任何請求,都會經過這個過濾器-->
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
JDBC
Java連線資料庫,匯入JDBC依賴mysql-connector-java,IDEA中連線資料庫
public class TestJdbc {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置資訊
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
String username = "root";
String password = "123456";
//載入驅動
Class.forName("com.mysql.jdbc.Driver");
//連線資料庫
Connection connection = DriverManager.getConnection(url, username, password);
//向資料庫傳送sql的物件
Statement statement = connection.createStatement();
//編寫sql
String sql = "select * from users";
//執行查詢sql,返回一個結果集
ResultSet rs = statement.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"));
}
//關閉連線
rs.close();
statement.close();
connection.commit();
}
}
預編譯sql
public class TestJdbc2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//配置資訊
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
String username = "root";
String password = "123456";
//載入驅動
Class.forName("com.mysql.jdbc.Driver");
//連線資料庫
Connection connection = DriverManager.getConnection(url, username, password);
//向資料庫傳送sql的物件
Statement statement = connection.createStatement();
String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,4);
preparedStatement.setString(2,"周七");
preparedStatement.setString(3,"888888");
preparedStatement.setString(4,"666@qwq.com");
preparedStatement.setString(5, String.valueOf(new Date(new java.util.Date().getTime())));
int i = preparedStatement.executeUpdate();
if (i>0){
System.out.println("插入成功");
}
//關閉連線
statement.close();
connection.commit();
}
}
事務
要麼都成功,要麼都失敗 !
ACID原則,保證資料的安全。
開啟事務
事務提交 commi ()
事務回滾 rollback ()
關閉事務
Junit單元測試
依賴
<!--單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
簡單使用
@Test註解只在方法上有效,只要加了這個註解的方法,就可以直接執行。
public class TestJdbc3 {
@Test
public void test(){
System.out.println("Hello");
}
}
轉賬事務(建立account表,欄位id,name,money),使用單元測試
public class TestJdbc3 {
@Test
public void test() {
//配置資訊
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
String username = "root";
String password = "123456";
Connection connection=null;
//載入驅動
try {
Class.forName("com.mysql.jdbc.Driver");
//連線資料庫
connection = DriverManager.getConnection(url, username, password);
//通知資料庫開啟事務
connection.setAutoCommit(false);
String sql1 = "update account set money=money-100 where name='A'";
connection.prepareStatement(sql1).executeUpdate();
//製造錯誤
int i=1/0;
String sql2 = "update account set money=money+100 where name='B'";
connection.prepareStatement(sql2).executeUpdate();
connection.commit();//以上sql都執行成功才提交
System.out.println("提交成功!");
} catch (Exception e) {
try {
//如果出現異常,就回滾事務
connection.rollback();
System.out.println("轉賬失敗!");
} catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
}finally {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}