前面說過,Servlet就是Tomcat這個HTTP服務(wù)器提供給Java的一組API,來完成構(gòu)建動態(tài)頁面等任務(wù)。Servlet中涉及的API非常多,這里我們只關(guān)注以下三個即可,其余的可在工作中獲得遇到具體場景再學(xué)習(xí)使用
HttpServlet
HttpServletRequest
HttpServletResponse
一:HttpServlet
HttpServlet:它提供了處理基于HTTP協(xié)議的請求和響應(yīng)的功能,為開發(fā)人員提供了一組用于處理HTTP請求的方法,其中最常用的是doGet()
和doPost()
方法。這些方法可以被子類重寫以實(shí)現(xiàn)具體的業(yè)務(wù)邏輯。HttpServlet功能包括
- 解析HTTP請求:HttpServlet類負(fù)責(zé)解析來自客戶端的HTTP請求,并提供了與請求相關(guān)的方法,如獲取請求方法、獲取請求參數(shù)、獲取請求頭等
- 處理HTTP請求:HttpServlet類定義了doGet()、doPost()等方法,用于處理GET和POST請求。開發(fā)人員可以根據(jù)業(yè)務(wù)需求重寫這些方法,并在其中實(shí)現(xiàn)相應(yīng)的業(yè)務(wù)邏輯
- 生成HTTP響應(yīng):HttpServlet類提供了一組用于生成HTTP響應(yīng)的方法,如設(shè)置響應(yīng)狀態(tài)碼、設(shè)置響應(yīng)頭、寫入響應(yīng)內(nèi)容等
- 會話管理:HttpServlet類支持會話管理,可以通過getSession()方法獲取會話對象,進(jìn)行會話跟蹤和管理
- 錯誤處理:HttpServlet類提供了對HTTP錯誤的處理機(jī)制,可以重寫相應(yīng)的方法來自定義錯誤頁面或錯誤處理邏輯
其核心方法如下,常用方法是后三個,前三個經(jīng)常在相關(guān)面試中出現(xiàn)
方法名稱 | 調(diào)用時機(jī) |
---|---|
init |
在HttpServlet 實(shí)例化后被調(diào)用一次 |
destory |
在HttpServlet 不再使用后被調(diào)用一次(正常關(guān)閉Tomcat ) |
service |
收到HTTP請求時候調(diào)用 |
doGet |
收到GET請求的時候調(diào)用(由service 方法調(diào)用) |
doPost |
收到POST請求的時候調(diào)用(由service 方法調(diào)用) |
doPut/doDelete/doOptions/... |
收到其他請求的時候調(diào)用((由service 方法調(diào)用)) |
這些方法的調(diào)用時機(jī)就稱為“Servlet的生命周期”
二:HttpServletRequest
(1)介紹
HttpServletRequest:繼承自ServletRequest
接口,并提供了訪問HTTP請求的方法和屬性。HttpServletRequest對象包含了客戶端發(fā)送到服務(wù)器的HTTP請求的信息,開發(fā)人員可以使用該對象獲取請求的參數(shù)、請求頭、請求方法等信息
其核心方法如下(都是get
系列)
方法名稱 | 調(diào)用時機(jī) |
---|---|
String getProrocol() |
返回請求協(xié)議的名稱和版本 |
String getMehtod() |
返回請求方法名稱 |
String getRequestURI() |
從協(xié)議名稱直到HTTP請求的第一行查詢字符串中,返回該請求的URL的一部分 |
String getContexPath() |
返回指示請求上下文的URI部分 |
Eunmeration getParameterNames() |
返回一個String對象的美劇,包含在該請求中包含的參數(shù)的名稱 |
String getParameter(String name) |
以字符串形式返回請求參數(shù)的值,如果參數(shù)不存在則返回null
|
String[] getParameterValues(String name) |
返回一個字符串對象的數(shù)組,包含所有給定的請求參數(shù)的值,如果參數(shù)不存在返回null
|
Enumeration getHeaderNames() |
返回一個枚舉,包含在該請求中包含的所有的頭名 |
String getHeader(String name) |
以字符串形式返回指定的請求頭的值 |
String getCharacterEncoding() |
返回請求主體中使用的字符編碼名稱 |
String getHeader(String name) |
以字符串形式返回指定的請求頭的值 |
String getContentType() |
返回請求主體的MIME類型,如果不知道類型則返回null
|
int getContentLength |
以字節(jié)為單位返回請求主體的長度,并提供輸入流,如果長度未知則返回-1 |
InputStream getInputStream() |
用于讀取去請求的body內(nèi)容,返回一個InputStream 對象 |
(2)示例1:打印請求信息
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;
@WebServlet("/showRequest")
public class ShowRequestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//把API執(zhí)行的結(jié)果,放到stringBuilder中
StringBuilder stringBuilder=new StringBuilder();
// 聲明響應(yīng)boyd是html結(jié)構(gòu)數(shù)據(jù)
resp.setContentType("text/html");
stringBuilder.append("<h3>首行部分</h3>");
stringBuilder.append(req.getProtocol());
stringBuilder.append("<br>");
stringBuilder.append(req.getMethod());
stringBuilder.append("<br>");
stringBuilder.append(req.getRequestURI());
stringBuilder.append("<br>");
stringBuilder.append(req.getContextPath());
stringBuilder.append("<br>");
stringBuilder.append(req.getQueryString());
stringBuilder.append("<br>");
stringBuilder.append("<h3>header部分</h3>");
Enumeration<String> headerNames=req.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName= headerNames.nextElement();
String headerValue=req.getHeader(headerName);
stringBuilder.append(headerName+":"+headerValue+"<br>");
}
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write(stringBuilder.toString());
}
}
在瀏覽器中輸入http://localhost:8080/HelloServlet/showRequest?a=10&b=20&c=30
,效果如下
(3)示例2:獲取Get請求參數(shù)
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/getparameter")
public class GetParameter extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 獲取 query string 中的鍵值對
String studentId = req.getParameter("studentId");
String studentName = req.getParameter("studentName");
System.out.println(studentId);
System.out.println(studentName);
// 告訴瀏覽器類型和編碼,讓瀏覽器正常顯示
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("studentId: " + studentId + ", " + "studentName: " + studentName);
}
}
在瀏覽器中輸入http://localhost:8080/GetParameter/getparameter?studentId=22123213&studentName=張三
,效果如下
(3)實(shí)例3:獲取Post請求參數(shù)
A:情況一
此時請求的body
是x-www-form-urlencoded
,也即form
表單
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/postparameter")
public class PostParameter extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 通過發(fā)送post請求,獲取 body 中的參數(shù)
// 讓Servlet知道如何解析
req.setCharacterEncoding("utf-8");
String studentId = req.getParameter("studentId");
String studentName = req.getParameter("studentName");
System.out.println(studentId);
System.out.println(studentName);
// 告訴瀏覽器類型和編碼,讓瀏覽器正常顯示
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("studentId: " + studentId + ", " + "studentName: " + studentName);
}
}
此時并不能在瀏覽器中直接輸入?yún)?shù),因?yàn)槟鞘?code>Get請求,構(gòu)造Post
請求可以有以下兩種方法
-
方法一:利用
Html
通過form
表單發(fā)送 - 方法二:使用軟件postman
先說方法一:需要注意該Html
文件必須位于webapp
目錄之下。復(fù)習(xí)一下,在HTML中,form
標(biāo)簽用于創(chuàng)建一個表單,其中action
屬性義了表單提交時要發(fā)送數(shù)據(jù)的目標(biāo)URL或服務(wù)器端腳本,當(dāng)用戶提交表單時,瀏覽器會將表單中的數(shù)據(jù)發(fā)送到action
屬性指定的URL。有以下兩種常見的寫法
-
相對路徑(此時基準(zhǔn)目錄就是
Html
文件所在目錄,也即/PostParameter
):例如postparameter
-
絕對路徑:例如
/PostParameter.postparameter
運(yùn)行PostParameter
后,然后在地址欄中輸入http://localhost:8080/PostParameter/student.html
,即可正確訪問到該文件
-
再次重復(fù):在Java Web應(yīng)用程序中,通常將靜態(tài)資源(例如
Html
、CSS
等)放置在webapp
目錄下,該目錄是Web應(yīng)用程序的根目錄。鏈接中PostParameter
是Servlet類的名稱,并不是文件夾或路徑
接著向表單輸入內(nèi)容,然后提交
再說方法二:postman使用方法非常簡單
另外,postman十分方便的一點(diǎn)是可以轉(zhuǎn)換為代碼
B:情況二
這種情況下請求的body
是json格式,步驟如下
- 首先需要讀取
body
中的內(nèi)容,這里需要借助getInputStream
,以此獲取到要解析的字符串 - Servlet并沒有內(nèi)置json解釋器,所以需要我們手動實(shí)現(xiàn)或者是借助第三方庫,這里借助
jackson
這個庫(因?yàn)樗荢pringBoot御用的)。然后就會得到一組鍵值對 - 根據(jù)類對象(在Java反射中講到過)創(chuàng)建一個實(shí)例
- 遍歷類對象中的屬性的名字,以此作為Key查詢對應(yīng)的Value
- 返回構(gòu)造好的對象
進(jìn)入Java中央倉庫,搜索jackson
,選擇Jackson Databind
隨便選擇一個版本后,拷貝Maven
至pom.xml中的<dependencies></dependencies>
標(biāo)簽內(nèi)
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4.1</version>
</dependency>
</dependencies>
jackson
會提供一個核心類叫ObjectMapper
,其中有兩個常用方法:
-
readValue
:用于將json數(shù)據(jù)轉(zhuǎn)換為Java對象- 第一個參數(shù):可以是字符串,也可以是輸入流
- 第二個參數(shù):是一個類對象,也就是要解析出來的結(jié)果的對象的類
-
writeValueAsString
:用于將Java對象轉(zhuǎn)換為json數(shù)據(jù)
代碼如下
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
一個Java對象,要想正確解析,必須滿足以下條件
這個類的屬性務(wù)必是public或者帶有public的getter/setter,否則jackson無法訪問到這個對象的屬性
這個類務(wù)必要有無參版本的構(gòu)造方法(如果不寫編譯器自動生成無參構(gòu)造)
*/class Student {
public int studentId;
public String studentName;
}
@WebServlet("/json")
public class JacksonServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 假設(shè)請求的body格式如下
// {studentId: 10, studentName: "張三"}
// 創(chuàng)建Jackson核心類
ObjectMapper objectMapper = new ObjectMapper();
// 解析json
Student s = objectMapper.readValue(req.getInputStream(), Student.class);
System.out.println(s.studentId);
System.out.println(s.studentName);
resp.setContentType("text/html; charset=utf-8");
resp.getWriter().write("studentId: " + s.studentId + ", " + "studentName: " + s.studentName);
}
}
利用postman發(fā)送請求(注意設(shè)置正確),可以看到回應(yīng)
當(dāng)然我們也可以返回json
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*
一個Java對象,要想正確解析,必須滿足以下條件
這個類的屬性務(wù)必是public或者帶有public的getter/setter,否則jackson無法訪問到這個對象的屬性
這個類務(wù)必要有無參版本的構(gòu)造方法(如果不寫編譯器自動生成無參構(gòu)造)
*/class Student {
public int studentId;
public String studentName;
}
@WebServlet("/json")
public class JacksonServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 假設(shè)請求的body格式如下
// {studentId: 10, studentName: "張三"}
// 創(chuàng)建Jackson核心類
ObjectMapper objectMapper = new ObjectMapper();
// 解析json
Student s = objectMapper.readValue(req.getInputStream(), Student.class);
System.out.println(s.studentId);
System.out.println(s.studentName);
// 修改
s.studentId=20;
s.studentName="李四";
// 返回json
resp.setContentType("application/json; charset=utf-8");
resp.getWriter().write(objectMapper.writeValueAsString(s));
}
}
三:HttpServletResponse
(1)介紹
HttpServletResponse:用于處理來自客戶端的請求并生成響應(yīng),其中的方法可以設(shè)置和操作HTTP響應(yīng)的各種屬性,包括響應(yīng)頭、狀態(tài)碼、字符編碼等等
其核心方法如下(都是set
系列)
方法 | 描述 |
---|---|
void setStatus(int sc) |
為該響應(yīng)設(shè)置狀態(tài)碼 |
void setHeader(String name, String value) |
設(shè)置一個帶有給定的名稱和值的header (如果name 存在則覆蓋) |
void addHeader(String name, Strin value) |
添加一個帶有給定的名稱和值的header (如果name 存在則并列添加新鍵值對) |
void setContentType(String type) |
設(shè)置被發(fā)送到客戶端的響應(yīng)的內(nèi)容類型 |
void setCharacterEncoding(String charset) |
設(shè)置被發(fā)送到客戶端的響應(yīng)的字符編碼(MIME字符集),例如utf-8
|
void sendRedirect(String location) |
使用指定的重定向位置URL發(fā)送臨時重定向響應(yīng)到客戶端 |
PrintWriter getWriter() |
用于向body 中寫入文本格式數(shù)據(jù) |
OutputStream getOutputStream() |
用于向body 中寫入二進(jìn)制格式數(shù)據(jù) |
(2)示例1:設(shè)置狀態(tài)碼
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/status")
public class StatusServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 利用 queryString 設(shè)置狀態(tài)碼
String type = req.getParameter("type");
if (type.equals("1")) {
resp.setStatus(200);
} else if (type.equals("2")) {
resp.setStatus(404);
} else {
resp.setStatus(504);
}
}
}
在瀏覽器地址里輸入http://localhost:8080/StatusServlet/status?type=2
(3)示例2:自動刷新
在HTTP響應(yīng)的頭部(Header)中,Refresh
屬性用于在服務(wù)器返回的響應(yīng)中指示瀏覽器進(jìn)行自動刷新或重定向操作。語法如下
- 延遲時間:表示延遲多少秒后進(jìn)行屬性,默認(rèn)為0s
- URL=重定向URL:指定要重定向的URL
Refresh: [延遲時間]; URL=重定向URL
當(dāng)瀏覽器接收到帶有Refresh
屬性的響應(yīng)時,它會根據(jù)指定的延遲時間進(jìn)行等待,并在延遲結(jié)束后執(zhí)行刷新或重定向。如果未指定延遲時間,默認(rèn)為立即刷新
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/refresh")
public class AutoRefreshServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 每2s刷新一次
resp.setHeader("refresh", "2");
// 顯示當(dāng)前時間戳
resp.getWriter().write(System.currentTimeMillis() + "");
}
}
(4)示例3:重定向
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/redirect")
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 瀏覽器收到請求后跳轉(zhuǎn)到百度首頁
resp.setStatus(302);
resp.setHeader("Location", "https://www.baidu.com");
}
}
四:綜合案例之表白墻
前面介紹的表白墻案例非常簡單,它只是一個單純的HTML頁面,如果將瀏覽器關(guān)閉,那么輸入的內(nèi)容將不復(fù)存在。所以這里我們可以將其做成服務(wù)器版本,這樣即使頁面關(guān)閉,表白墻內(nèi)容也不會丟失
- 注意:本案例雖然比較簡單,但是會結(jié)合到之前很多知識,所以相關(guān)內(nèi)容不再重復(fù),如有需求可以翻看前面的內(nèi)容
(1)效果展示
當(dāng)加載頁面時可以自動從服務(wù)器數(shù)據(jù)庫中獲取之前的提交內(nèi)容
點(diǎn)擊提交則可以將內(nèi)容保存到服務(wù)器數(shù)據(jù)庫中
(2)請求和響應(yīng)報文格式
發(fā)送數(shù)據(jù)給服務(wù)器:
-
請求報文
POST/message HTTP/1.1
Content-Type:application/json; charset=utf-8
{"who":"我", "whom":"你", "我啊你"}
-
響應(yīng)報文
HTTP/1.1 200 OK
從服務(wù)器獲取數(shù)據(jù):
-
請求報文
GET/message
-
響應(yīng)報文
HTTP/1.1 200ok
Content-Type:application/json; charset=utf-8
(3)代碼梳理
(4)完整代碼
- 代碼Github:點(diǎn)擊跳轉(zhuǎn)
整個項(xiàng)目概覽
Mysql相關(guān)語句
show databases;
create database confession_wall;
use confession_wall;
create table message (who varchar(50), whom varchar(50), content varchar(1024));
配置文件
pom.xml
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>
相關(guān)類
Message.java
:用于封裝消息內(nèi)容
public class Message {
public String who;
public String whom;
public String content;
public String getWho() {
return who;
}
public String getWhom() {
return whom;
}
public String getContent() {
return content;
}
public void setWho(String who) {
this.who = who;
}
public void setWhom(String whom) {
this.whom = whom;
}
public void setContent(String content) {
this.content = content;
}
}
MessageServlet.java
:Servlet服務(wù)器
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/message")
public class MessageServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
private List<Message> messageList = new ArrayList<>();
// 讓頁面獲取到數(shù)據(jù)
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 聲明當(dāng)前的響應(yīng)數(shù)據(jù)格式
resp.setContentType("application/json; charset=utf-8");
// 讀取數(shù)據(jù)庫內(nèi)容返回給頁面
try {
messageList = load();
} catch (SQLException e) {
throw new RuntimeException(e);
}
resp.getWriter().write(objectMapper.writeValueAsString(messageList));
}
// 瀏覽器向服務(wù)器提交數(shù)據(jù)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 獲取到body中的數(shù)據(jù)并解析
Message message = objectMapper.readValue(req.getInputStream(), Message.class);
// 向數(shù)據(jù)庫提交內(nèi)容
try {
save(message);
} catch (SQLException e) {
throw new RuntimeException(e);
}
resp.setStatus(200);
System.out.println("成功提交數(shù)據(jù):"
+ "【" + message.getWho() + "】" + "對【" + message.getWhom() + "】" + "說:" + message.getContent());
}
// 從數(shù)據(jù)庫查詢數(shù)據(jù)
private List<Message> load() throws SQLException {
// 先得有一個數(shù)據(jù)源
DataSource dataSource = DBUtil.getDataSource();
// 與服務(wù)器建立連接
Connection connection = dataSource.getConnection();
// 構(gòu)造SQL并預(yù)處理
String sql = "select * from message";
PreparedStatement statement = connection.prepareStatement(sql);
// 執(zhí)行SQL得到結(jié)果集合
ResultSet resultSet = statement.executeQuery();
//遍歷結(jié)果集合
// List<Message> messageList = new ArrayList<>();
while (resultSet.next()) {
Message message = new Message();
message.setWho(resultSet.getString("who"));
message.setWhom(resultSet.getString("whom"));
message.setContent(resultSet.getString("content"));
messageList.add(message);
}
// 關(guān)閉連接釋放資源
statement.close();
connection.close();
return messageList;
}
// 保存數(shù)據(jù)到數(shù)據(jù)庫
private void save(Message message) throws SQLException {
// 先得有一個數(shù)據(jù)源
DataSource dataSource = DBUtil.getDataSource();
// 與服務(wù)器建立連接
Connection connection = dataSource.getConnection();
System.out.println(connection);
// 構(gòu)造SQL并進(jìn)行預(yù)處理
String sql = "insert into message values(?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql);
System.out.println(sql);
statement.setString(1, message.who);
statement.setString(2, message.whom);
statement.setString(3, message.content);
// 執(zhí)行SQL然后插入
try {
int res = statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
// 關(guān)閉連接釋放資源
statement.close();
connection.close();
}
}
DBUtil.java
:用于用于封裝DataSource的單例
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
// 用于封裝DataSource的單例(懶漢模式,注意線程安全)
public class DBUtil {
private static volatile DataSource dataSource = null;
public static DataSource getDataSource() {
if (dataSource == null) {
synchronized (DBUtil.class) {
if(dataSource == null) {
dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/confession_wall?characterEncoding=utf8&useSSL=false&serverTimezone=UTC");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("123456");
}
}
}
return dataSource;
}
// 防止直接new DBUtil
private DBUtil() {};
}
webapp文章來源:http://www.zghlxwxcb.cn/news/detail-708849.html
onfessionalWall.html
:網(wǎng)頁文章來源地址http://www.zghlxwxcb.cn/news/detail-708849.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ConfessionalWall</title>
</head>
<body>
<style>
.container {
width: 400px;
/*水平居中*/
margin: 0 auto;
}
h1 {
text-align: center;
}
p {
text-align: center;
color: #808080;
}
.row {
height: 40px;
display: flex;
/* 水平居中*/
justify-content: center;
/* 垂直居中*/
align-items: center;
}
.row span {
width: 100px;
}
.row input {
width: 200px;
height: 25px;
}
.row button {
width: 310px;
height: 40px;
color:white;
background-color: orange;
border: none;
}
.row button:active {
background-color: #666;
}
</style>
<div class="container">
<h1>表白墻</h1>
<p>(輸入后點(diǎn)擊下方按鈕提交)</p>
<div class="row">
<span>姓名:</span><input type="text">
</div>
<div class="row">
<span>對誰:</span><input type="text">
</div>
<div class="row">
<span>內(nèi)容:</span><input type="text">
</div>
<div class="row">
<button>提交</button>
</div>
</div>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
var container = document.querySelector('.container');
var button = document.querySelector('button');
button.onclick = function () {
// 獲取內(nèi)容
var inputs = document.querySelectorAll('input');
var who = inputs[0].value;
var whom = inputs[1].value;
var content = inputs[2].value;
console.log(who);
console.log(who);
console.log(content);
if (who === '' || whom === '' || content === '') {
alert("有未填寫項(xiàng)");
return;
}
// 構(gòu)造出div生成發(fā)送內(nèi)容
let newDiv = document.createElement('div');
newDiv.className = 'row';
newDiv.innerHTML = "【" + who + "】" + "對【" + whom + "】" + "說:" + content;
container.appendChild(newDiv);
// 清空之前輸入
for (var i = 0; i < inputs.length; i++) {
inputs[i].value = '';
}
// 構(gòu)造對象
let data = {
who: who,
whom, whom,
content, content
};
// 利用ajax發(fā)送請求
$.ajax({
type: 'post',
url : 'message',
// 以下是body內(nèi)容
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
success: function(body) {
console.log("成功提交數(shù)據(jù)")
}
});
}
// 在頁面加載時就獲取服務(wù)器數(shù)據(jù)
function getMessages() {
$.ajax({
type: 'get',
url: 'message',
success: function (body) {
// body就是響應(yīng)的body內(nèi)容,json數(shù)組
// JQuery可以很智能的我們將json數(shù)組解析為js對象數(shù)組(但注意設(shè)置Content-Type為application/json)
let contatiner = document.querySelector('.container')
for (let i = 0; i < body.length; i++) {
let message = body[i];
// 構(gòu)造元素
let newDiv = document.createElement('div');
newDiv.className = 'row';
newDiv.innerHTML = "【" + message.who + "】" + "對【" + message.whom + "】" + "說:" + message.content;
contatiner.appendChild(newDiv);
}
}
})
}
getMessages();
</script>
</body>
</html>
到了這里,關(guān)于(Java高級教程)第三章Java網(wǎng)絡(luò)編程-第七節(jié)2:Servlet API和綜合案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!