回顧
1. listener監(jiān)聽器
監(jiān)聽三大域?qū)ο蟮膭?chuàng)建和銷毀,request九秀、session玄捕、servletContext
快速入門
1.普通類烟阐,實(shí)現(xiàn)listener接口
2.重寫抽象方法墓卦,創(chuàng)建和銷毀
3.配置
web.xml
注解
統(tǒng)計(jì)在線人數(shù)
2. 綜合案例
使用mvc和三層架構(gòu)的思想實(shí)現(xiàn)用戶模塊的增刪改查
程序入口(瀏覽器)---servlet(轉(zhuǎn)發(fā)、重定向)---service---dao
AJAX&文件上傳
今日目標(biāo)
1. json
java和json數(shù)據(jù)相互轉(zhuǎn)換
2. 校驗(yàn)用戶名是否存在
3. 文件上傳【可以照著抄一遍...】
4. 安裝mysql5.7版本(如果mysql5.6以上可以繼續(xù)使用....)
一 JSON
1.1 回顧
最早是JavaScript對象表示形式睛榄,現(xiàn)在主要用于互聯(lián)網(wǎng)傳輸數(shù)據(jù)載體
* java
User user =new User();
user.setUsername("jack");
user.setAge(18);
* javaScript
let user = {"username":"jack","age":18};
let array = [{},{},{}]
name:都是字符串
value:支持各種類型
JSON 比 XML 更小荣茫、更快,更易解析
1587864032897.png
1.2 JSON數(shù)據(jù)與java對象轉(zhuǎn)換
常見的解析器
工具名稱 | 介紹 |
---|---|
Jsonlib | Java 類庫场靴,需要導(dǎo)入的jar包較多 |
Gson | google提供的一個(gè)簡單的json轉(zhuǎn)換工具 |
Fastjson | alibaba技術(shù)團(tuán)隊(duì)提供的一個(gè)高性能的json轉(zhuǎn)換工具 |
Jackson | 開源免費(fèi)的json轉(zhuǎn)換工具啡莉,springmvc轉(zhuǎn)換默認(rèn)使用jackson |
1587864344057.png
使用jackson,需要導(dǎo)入jar包
1587864541216.png
提供了一個(gè)核心轉(zhuǎn)換器對象
ObjectMapper om = new ObjectMapper();
1.2.1 java對象轉(zhuǎn)為json(字符串)【重點(diǎn)】
String writeValueAsString(Object object);
// 將user對象轉(zhuǎn)為json字符串
@Test
public void UserToJson() throws Exception {
User user = new User("1", "lucy", "女", 15, "德克薩斯", "123", "123@qq.com");
// 創(chuàng)建jackson轉(zhuǎn)換器對象
ObjectMapper om = new ObjectMapper();
// 將任意對象轉(zhuǎn)為json字符串
String json = om.writeValueAsString(user);
System.out.println(json); // 在java中name必須使用雙引號包裹起來
}
// 將map集合轉(zhuǎn)為json字符串
@Test
public void MapToJson() throws Exception {
Map<String, Object> map = new HashMap<>();
map.put("name", "張三");
map.put("age", 18);
// 創(chuàng)建jackson轉(zhuǎn)換器對象
ObjectMapper om = new ObjectMapper();
// toJson
String json = om.writeValueAsString(map);
System.out.println(json); // {"name":"張三","age":18}
}
// 將list集合轉(zhuǎn)為json數(shù)組字符串
@Test
public void ListToJson() throws Exception {
List<User> list = new ArrayList<>();
list.add(new User("1", "lucy", "女", 15, "德克薩斯", "123", "123@qq.com"));
list.add(new User("2", "jack", "男", 15, "德克薩斯", "123", "123@qq.com"));
// 創(chuàng)建jackson轉(zhuǎn)換器對象
ObjectMapper om = new ObjectMapper();
// toJson
String json = om.writeValueAsString(list);
System.out.println(json); // [{},{}]
}
1.2.2 將json(字符串)轉(zhuǎn)為java對象【了解】
T readValue(String json,Class<T> classType);
// 將json字符串轉(zhuǎn)為user對象
@Test
public void JsonToUser() throws Exception {
String json = "{\"id\":\"1\",\"name\":\"lucy\",\"sex\":\"女\",\"age\":15,\"address\":\"德克薩斯\",\"qq\":\"123\",\"email\":\"123@qq.com\"}";
// 創(chuàng)建jackson轉(zhuǎn)換器對象
ObjectMapper om = new ObjectMapper();
// toUser
User user = om.readValue(json, User.class);
System.out.println(user);
}
// 將json字符串轉(zhuǎn)為map集合(如果你獲取的json格式?jīng)]有對應(yīng)的java實(shí)體對象憎乙,就可以拿map接收)
@Test
public void JsonToMap() throws Exception {
String json = "{\"name\":\"lucy\",\"age\":18}";
// 創(chuàng)建jackson轉(zhuǎn)換器對象
ObjectMapper om = new ObjectMapper();
// toMap
Map<String, Object> map = om.readValue(json, Map.class);
System.out.println(map);
}
// 將json數(shù)組字符串轉(zhuǎn)為list集合
@Test
public void JsonToList() throws Exception {
String json = "[{\"id\":\"1\",\"name\":\"lucy\",\"sex\":\"女\",\"age\":15,\"address\":\"德克薩斯\",\"qq\":\"123\",\"email\":\"123@qq.com\"},{\"id\":\"2\",\"name\":\"jack\",\"sex\":\"男\(zhòng)",\"age\":15,\"address\":\"德克薩斯\",\"qq\":\"123\",\"email\":\"123@qq.com\"}]";
// 創(chuàng)建jackson轉(zhuǎn)換器對象
ObjectMapper om = new ObjectMapper();
// toList
List list = om.readValue(json, List.class);
System.out.println(list);
}
1.3 自定義模板
1587866270735.png
二 案例:檢查用戶名是否可用
需求
? 在用戶注冊頁面票罐,輸入用戶名,當(dāng)用戶名輸入框失去焦點(diǎn)時(shí)泞边,發(fā)送異步請求该押,將輸入框的用戶名傳遞給服務(wù)器進(jìn)行是否存在的校驗(yàn)。
2.1 技術(shù)分析
此需求使用了ajax技術(shù):通過==異步提交==阵谚,實(shí)現(xiàn)頁面的==局部刷新==蚕礼,提高用戶的體驗(yàn)
JQuery提供的ajax函數(shù)
* ajax
$.ajax({
type:"請求方式,get|post",
url:"請求服務(wù)器地址",
data:"請求參數(shù)",
success:function(resp){
resp就是服務(wù)器返回的結(jié)果...
}
});
* get
$.get(url(地址?參數(shù)),function(resp){
});
* post
$.post(url,data,function(resp){
})
2.2 需求分析
1587868403078.png
2.3 代碼實(shí)現(xiàn)
① index.jsp
1587868753719.png
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>${NAME}</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.2.1.js"></script>
</head>
<body>
<h3>用戶注冊</h3>
<form action="#" method="post">
用戶名:<input type="text" name="username" id="username"> <span id="userwarn"></span> <br>
</form>
<script>
// 給用戶文本框綁定失去焦點(diǎn)事件
$('#username').blur(function () {
// 獲取用戶輸入的值
console.log(this.value);
let data = "username=" + this.value;
// 發(fā)送ajax請求
$.ajax({
type:"post",
url:'${pageContext.request.contextPath}/CheckServlet',
data:data,
success:function (resp) {
console.log(resp);
// 判斷結(jié)果并實(shí)現(xiàn)局部刷新
if(resp.flag){
$('#userwarn').text(resp.msg).css('color','green');
}else{
$('#userwarn').text(resp.msg).css('color','red');
}
}
})
})
</script>
</body>
</html>
② CheckServlet
@WebServlet("/CheckServlet")
public class CheckServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 1.接收請求參數(shù)
String username = request.getParameter("username");
// 2.聲明map集合
Map<String, Object> map = new HashMap<>();
// 3.判斷用戶是否存在
if(username.equals("jack")){
map.put("flag",false);
map.put("msg", "× 此用戶已注冊");
}else{
map.put("flag",true);
map.put("msg", "√ 此用戶可以注冊");
}
// 4.將map集合轉(zhuǎn)為json字符串
ObjectMapper om = new ObjectMapper();
String json = om.writeValueAsString(map);
System.out.println(json);
// 5.設(shè)置json的MIME類型
response.setContentType("application/json;charset=utf-8");
// 6.response響應(yīng)json到客戶端
response.getWriter().write(json);
}
}
三 案例:文件上傳
需求
? 在用戶注冊頁面梢什,我們可以輸入用戶名奠蹬,還可以選擇要上傳的文件;點(diǎn)擊提交按鈕嗡午,就可以將用戶輸入的內(nèi)容和選擇的文件保存到服務(wù)器上
3.1 技術(shù)分析
1587870989239.png
3.1.1 客戶端如何將文件轉(zhuǎn)為文本
1. 表單提交方式必須為post
action="post"
2. 表單的enctype屬性值必須為multipart/form-data 多組件表單數(shù)據(jù)
enctype="multipart/form-data"
3. 在表單中提供文件上傳項(xiàng)
<input type="file" name="pic">
1587871962157.png
3.1.2 服務(wù)器將文本轉(zhuǎn)為字節(jié)流
- 使用apache提供工具類 commons-fileupload(今天講囤躁,最麻煩的....)
- 使用servlet3.0版本,通過注解實(shí)現(xiàn)(黑馬旅游網(wǎng))
- 使用springMVC框架(最簡單荔睹,底層使用commons-fileupload)
3.1.2 代碼實(shí)現(xiàn)【課下抄一遍即可】
① 導(dǎo)入文件上傳相關(guān)jar包
1587872397979.png
1587872441280.png
② index.jsp
1587872494757.png
③ 指定服務(wù)器保存文件路徑
1587872548319.png
④ 編寫servlet接收文件并保存
步驟分析
1. 創(chuàng)建磁盤文件項(xiàng)工廠
2. 創(chuàng)建核心解析對象(依賴工廠對象)
3. 解析request對象狸演,返回上傳項(xiàng)list集合
4. 遍歷list,獲取每一個(gè)上傳項(xiàng)
5. 判斷
普通上傳項(xiàng)
name和value
文件上傳項(xiàng)
文件名
字節(jié)輸入流
保存服務(wù)器端
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
// 1.創(chuàng)建磁盤文件項(xiàng)工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
// 2.創(chuàng)建上傳解析器對象(依賴工廠對象)
ServletFileUpload fileUpload = new ServletFileUpload(factory);
// 3.解析request請求僻他,返回上傳項(xiàng)list集合
List<FileItem> fileItems = fileUpload.parseRequest(request);
// 4.遍歷list
for (FileItem fileItem : fileItems) {
// 5.判斷是文件項(xiàng)還是普通項(xiàng)
if (fileItem.isFormField()) {// 普通上傳項(xiàng)
// 獲取name屬性名
String name = fileItem.getFieldName();
// 獲取value屬性值
String value = fileItem.getString();
System.out.println("普通上傳項(xiàng):" + name + "=" + value);
} else {// 文件上傳項(xiàng)
// a.獲取文件名 demo.txt
String fileName = fileItem.getName();
// b.獲取文件字節(jié)輸入流
InputStream in = fileItem.getInputStream();
// c.獲取文件擴(kuò)展名
String extName = FileUtil.extName(fileName);
// d.生成隨機(jī)文件名
fileName = IdUtil.simpleUUID() + "." + extName;
// 此文件名會保存數(shù)據(jù)庫一份宵距,給用戶查詢使用...
// 獲取upload目錄在服務(wù)器真實(shí)路徑
String realPath = request.getServletContext().getRealPath("/upload/");
// 判斷此目錄是否存在
File dirFile = new File(realPath);
if (!dirFile.exists()) {
dirFile.mkdirs(); // 如果不存在自己創(chuàng)建
}
// 設(shè)置文件字節(jié)輸出流
FileOutputStream out = new FileOutputStream(realPath + fileName);
// 流的拷貝
IoUtil.copy(in, out);
// 關(guān)流
out.close();
in.close();
response.getWriter().write("success");
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
}