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();
}
}
}
}