Web-第十五天 Ajax學習【悟空教程】
今日內(nèi)容介紹 案例:異步用戶名校驗 案例:異步自動填充 今日內(nèi)容學習目標 使用jQuery可以發(fā)送ajax請求 將Java對象轉(zhuǎn)換成JSON數(shù)據(jù) 使用jQuery處理JSON數(shù)據(jù) 在實際開發(fā)中,完成注冊功能前,如果用戶填寫用戶信息,準備填寫其他信息時,將提示當前用戶的用戶名是否可用。效果圖如下:JS Ajax和jQuery Ajax
第1章 案例:異步用戶名校驗
1.1 案例介紹
AJAX即“Asynchronous Javascript And XML”(異步JavaScript和XML)可以使網(wǎng)頁實現(xiàn)異步更新,就是不重新加載整個網(wǎng)頁的情況下,對網(wǎng)頁的某部分進行更新(局部刷新)。傳統(tǒng)的網(wǎng)頁(不使用 AJAX)如果需要更新內(nèi)容,必須重載整個網(wǎng)頁頁面。
AJAX = 異步 JavaScript和XML,是一種新的思想,整合之前的多種技術,用于創(chuàng)建快速交互式網(wǎng)頁應用的網(wǎng)頁開發(fā)技術。
1.1使用JavaScript獲得瀏覽器內(nèi)置的AJAX引擎(XMLHttpRequest對象)
1.2 通過AJAX引擎確定請求路徑和請求參數(shù)
1.3 通知AJAX引擎發(fā)送請求
AJAX引擎會在不刷新瀏覽器地址欄的情況下,發(fā)送請求
2.1 服務器獲得請求參數(shù)
2.2 服務器處理請求參數(shù)(添加、查詢等操作)
2.3 服務器響應數(shù)據(jù)給瀏覽器
AJAX引擎獲得服務器響應的數(shù)據(jù),通過執(zhí)行JavaScript的回調(diào)函數(shù)將數(shù)據(jù)傳遞給瀏覽器頁面。
3.1 通過設置給AJAX引擎的回調(diào)函數(shù)獲得服務器響應的數(shù)據(jù)
3.2 使用JavaScript在指定的位置,顯示響應數(shù)據(jù),從而局部修改頁面的數(shù)據(jù),達到局部刷新目的。
原生態(tài)JS操作ajax步驟
1. 獲得ajax引擎
2. 設置回調(diào)函數(shù)
3. 確定請求路徑
4. 發(fā)送請求
JavaScript ajax處理GET和POST請求有細微差異,接下來簡單介紹
提供處理程序HelloServlet,并分別實現(xiàn)doGet和doPost兩個方法
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>cn.com.javahelp.demo01.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
步驟1:編寫servlet,doGet()方法獲得數(shù)據(jù),并發(fā)送響應數(shù)據(jù)
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1 獲得數(shù)據(jù)
String username = request.getParameter("username");
String password = request.getParameter("password");
//2 處理
System.out.println(username + " : " + password);
//3 響應數(shù)據(jù)
response.getWriter().print("get success");
}
步驟2:在demo01.jsp提供按鈕,點擊發(fā)送get請求。(注意:只能谷歌或火狐瀏覽器使用)
<script type="text/javascript">
function sendGet(){
//1 獲得ajax引擎
var xmlhttp = new XMLHttpRequest();
//2 設置回調(diào)函數(shù)
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4){
if(xmlhttp.status == 200){
alert("響應數(shù)據(jù)" + xmlhttp.responseText);
}
}
};
//3 確定請求方式、路徑及參數(shù)
xmlhttp.open("GET","/day15/helloServlet?username=jack&password=1234");
//4 發(fā)送請求
xmlhttp.send(null);
}
</script>
<input type="button" onclick="sendGet()" value="get請求"/> <br/>
步驟1:編寫servlet,doPost()方法,用于接收數(shù)據(jù)和發(fā)送響應數(shù)據(jù)
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//0 處理亂碼
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//1 獲得數(shù)據(jù)
String username = request.getParameter("username");
String password = request.getParameter("password");
//2 處理
System.out.println(username + " : " + password);
//3 響應數(shù)據(jù)
response.getWriter().print("post 成功");
}
步驟2:在demo01.jsp提供按鈕,點擊發(fā)送post請求。(注意:只能谷歌或火狐瀏覽器使用)
<script type="text/javascript">
function sendPost(){
//1 獲得ajax引擎
var xmlhttp = new XMLHttpRequest();
//2 設置回調(diào)函數(shù)
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4){
if(xmlhttp.status == 200){
alert("響應數(shù)據(jù)" + xmlhttp.responseText);
}
}
};
//3 確定請求方式、路徑及參數(shù)
xmlhttp.open("POST","/day15/helloServlet");
//4 設置請求編碼
xmlhttp.setRequestHeader("content-type","application/x-www-form-urlencoded");
//5 發(fā)送請求
xmlhttp.send("username=杰克&password=1234");
}
</script>
<input type="button" onclick="sendPost()" value="post請求"/> <br/>
function getXMLhttp(){
var xmlhttp=null;
// 谷歌、火狐、IE最新瀏覽器
if (window.XMLHttpRequest){
xmlhttp=new XMLHttpRequest();
}else if (window.ActiveXObject){
//IE老版本瀏覽器(IE6、7、8 等)
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
$.post() 以post請求方式發(fā)送ajax
格式:jQuery.post(url, [data], [callback], [type])
參數(shù)1:url,請求路徑
參數(shù)2:data,請求參數(shù)
參數(shù)3:callback,回調(diào)函數(shù)
參數(shù)4:type,返回內(nèi)容格式,xml, html, script, json, text, _default。
服務器響應編碼為:application/json;charset=UTF-8,回調(diào)函數(shù)data類型是json對象
服務器響應編碼為:text/html;charset=UTF-8,回調(diào)函數(shù)data類型是字符串。
$.get() 以get請求方式發(fā)送ajax
除了請求方式不同,使用方式與$.post()完全一致。
測試:
<script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(function(){
//get請求
$("#getId").click(function(){
var url = "/day15/helloServlet";
var params = {
"username":"jack",
"password":"1234"
};
$.get(url,params,function(data){
alert(data);
});
});
//post請求
$("#postId").click(function(){
var url = "/day15/helloServlet";
var params = {
"username":"杰克",
"password":"1234"
};
$.post(url,params,function(data){
alert(data);
});
});
});
</script>
1. <input name=”username”>失去焦點時,使用$.post() 將用戶名username以ajax方式發(fā)送給服務器
2. 服務器獲得用戶名,并通過用戶名查詢用戶
a) 如果用戶名存在,返回不可用提示
b) 如果用戶名可用,返回可用提示
3. 根據(jù)服務器響應的json數(shù)據(jù),控制提示信息的顯示和提交的按鈕是否可用。
步驟1:創(chuàng)建項目,導入頁面
步驟2:導入jar包
步驟3:復制工具類
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/day15_db</property>
步驟4:數(shù)據(jù)庫及表
create database day22_db;
use day22_db;
create table user(
uid varchar(32) primary key,
username varchar(50),
password varchar(32)
);
insert into user(uid,username,password) values('u001','jack','1234');
insert into user(uid,username,password) values('u002','rose','1234');
步驟5:編寫JavaBean
public class User {
private String uid;
private String username;
private String password;
步驟1:編寫servlet,獲得用戶名查詢是否存在,并返回json數(shù)據(jù)。
public class UserCheckServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//0 編碼
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//1 獲得用戶名
String username = request.getParameter("username");
//2 查詢是否存在
UserService userService = new UserService();
User user = userService.findByName(username);
//3 處理
String jsonData = "";
if(user != null){
jsonData = "{\"message\":\"用戶名不可用\",\"flag\":false}";
} else {
jsonData = "{\"message\":\"用戶名可用\",\"flag\":true}";
}
response.getWriter().print(jsonData);
}
步驟2:編寫service
public class UserService {
/**
* 通過用戶名查詢
* @param username
* @return
*/
public User findByName(String username) {
UserDao userDao = new UserDao();
return userDao.findByName(username);
}
}
步驟3:編寫dao,提供findByName()方法
public class UserDao {
/**
* 通過用戶名查詢用戶
* @param username
* @return
*/
public User findByName(String username) {
try {
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
String sql = "select * from user where username = ?";
Object[] params = {username};
return queryRunner.query(sql, new BeanHandler<User>(User.class), params);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
步驟1:修改提示信息顯示區(qū)域
步驟2:給按鈕添加id屬性,并設置禁用,使用bootstrap的樣式顯示禁用效果。
步驟3:編寫js,當input失去焦點,發(fā)送ajax,并控制提示信息顯示和按鈕是否可用。
<script type="text/javascript">
$(function(){
$("input[name='username']").blur(function(){
//1 確定請求路徑
var url = "${pageContext.request.contextPath}/userCheckServlet";
//2 確定請求參數(shù)
var params = {"username":$(this).val()};
//3 發(fā)送ajax請求
$.post(url,params,function(data){
//4.1 給“提示顯示”區(qū)域添加label樣式
$("#showUsernameSpan").addClass("label");
if(data.flag){
//4.2 可用 ,添加success樣式(bootstrap提供),并移除按鈕禁用
$("#showUsernameSpan").addClass("label-success");
$("#showUsernameSpan").removeClass("label-danger");
$("#registButton").removeProp("disabled");
} else {
//4.3不可用,添加danger樣式(bootstrap提供),并禁用按鈕
$("#showUsernameSpan").addClass("label-danger");
$("#showUsernameSpan").removeClass("label-success");
$("#registButton").prop("disabled","disabled");
}
//4.4 設置提示信息
$("#showUsernameSpan").text(data.message);
},"json");
});
});
</script>
在開發(fā)中,通常情況下,搜索功能是非常常見的,類似百度,當我們輸入搜索條件時,將自動填充我們需要的數(shù)據(jù),并提供選擇,我們將此類功能稱為:自動填充(autocomplete)。如下圖:
什么是JSON
JSON(JavaScript Object Notation) 是一種輕量級的數(shù)據(jù)交換格式。JSON采用完全獨立于語言的文本格式,就是說不同的編程語言JSON數(shù)據(jù)是一致的。
易于人閱讀和編寫,同時也易于機器解析和生成(一般用于提升網(wǎng)絡傳輸速率)。
JSON格式:
JSON對象格式
{"key":"value","key":"value",....}
鍵和值使用冒號分隔。
標準規(guī)范要求key必須使用雙引號,value如果沒有使用雙引號表示變量。
JSON數(shù)組
[ obj , obj , obj , ....]
表示一組值,多個值使用逗號分隔
例如:
<script type="text/javascript">
//1 json對象
var user = {
"username":"jack",
"password":"1234"
};
alert(user.username); //通過key獲得json數(shù)據(jù)
//2 json數(shù)組
var arr = ['jack','rose','tom'];
alert(arr[1]);
//3 綜合案例
var data = [
{"id":"b001","title":"javaweb","price":"998"},
{"id":"b002","title":"java 基礎","price":"123"},
{"id":"b003","title":"ssh","price":"250"},
];
alert(data[1].title);
</script>
json-lib是將java對象與json數(shù)據(jù)相互轉(zhuǎn)換的工具。
第三方工具,使用時需要導入jar包
常用對象:
JSONObject, java對象(JavaBean、Map)與JSON數(shù)據(jù) 轉(zhuǎn)換工具類
JSONArray,java集合(List、Array) 與JSON數(shù)據(jù) 轉(zhuǎn)換工具類
常用方法:
static fromObject(…) ,靜態(tài)方法,用于將java對象或集合轉(zhuǎn)換常 jsonlib對象。
toString() 將jsonlib對象 轉(zhuǎn)換成 json 字符串。
例如:
// map或javabean
Map<String, String> map = new HashMap<String, String>();
map.put("username", "jack");
map.put("password", "1234");
String str = JSONObject.fromObject(map).toString();
System.out.println(str);
/* 輸出結(jié)果:
{
"username":"jack",
"password":"1234"
}
*/
// list 或 array
List<Map<String,String>> list = new ArrayList<>();
list.add(map);
list.add(map);
String str2 = JSONArray.fromObject(list).toString();
System.out.println(str2);
/* 輸出結(jié)果:
[
{"username":"jack","password":"1234"},
{"username":"jack","password":"1234"}
]
*/
1.用戶輸入搜索條件,鍵盤彈起時,發(fā)送ajax請求,將用戶輸入的內(nèi)容發(fā)送給服務器
2.1 服務器獲得用戶輸入的內(nèi)容
2.2 根據(jù)要求拼湊查詢條件,商品名稱需要匹配,拼音也需要匹配,用戶項可以不連續(xù)。
2.3 根據(jù)拼湊條件查詢商品信息
3.將查詢的商品信息使用json-lib轉(zhuǎn)換成json數(shù)據(jù)。
4.在$.post() 回調(diào)函數(shù)中處理查詢結(jié)果。
步驟1:創(chuàng)建項目,導入頁面
步驟2:導入jar包:
步驟3:復制工具了和c3p0配置文件
步驟4:創(chuàng)建表
create table product(
pid varchar(32) primary key,
pname varchar(100),
pinyin varchar(200)
);
insert into product(pid,pname,pinyin) values('p001','服裝','fuzhuang');
insert into product(pid,pname,pinyin) values('p002','男裝','nanzhuang');
insert into product(pid,pname,pinyin) values('p003','女裝','nvzhuang');
insert into product(pid,pname,pinyin) values('p004','電腦','diannao');
insert into product(pid,pname,pinyin) values('p005','奢侈品','shechipin');
insert into product(pid,pname,pinyin) values('p006','圖書','tushu');
insert into product(pid,pname,pinyin) values('p007','食品','shipin');
步驟5:創(chuàng)建Javabean
public class Product {
private String pid;
private String pname;
private String pinyin;
步驟1:編寫servlet,獲得關鍵字,然后查詢,將查詢結(jié)果轉(zhuǎn)換成json數(shù)據(jù)。
public class ProductFindByWordServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try{
//0編碼
request.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
//1 關鍵字
String word = request.getParameter("word");
//2 查詢
ProductService productService = new ProductService();
List<Product> allProduct = productService.findAllByWord(word);
//3 轉(zhuǎn)換成json
String jsonData = JSONArray.fromObject(allProduct).toString();
response.getWriter().println(jsonData);
}catch(Exception e){
e.printStackTrace();
}
}
步驟2:編寫service,允許用戶可以輸入“漢字”、“拼音”、“若干字母”等進行查詢。
public class ProductService {
/**
* 通過關鍵字查詢
* @param word
* @return
*/
public List<Product> findAllByWord(String word) throws SQLException {
ProductDao productDao = new ProductDao();
return productDao.findAll(word);
}
}
步驟3:編寫dao,查詢帶有條件商品信息
public class ProductDao {
/**
* 條件查詢商品
* @param condition
* @param params
* @return
*/
public List<Product> findAll(String word) throws SQLException{
StringBuilder builder = new StringBuilder();
List<Object> paramsList = new ArrayList<Object>();
if(word != null){
// 拼湊關鍵字的屬性,hao拼湊成“%h%a%o%”
StringBuilder wordBuilder = new StringBuilder();
wordBuilder.append("%");
for(int i = 0 ; i < word.length() ; i ++ ){
wordBuilder.append(word.charAt(i)).append("%");
}
//1 漢字匹配
builder.append(" and pname like ?");
paramsList.add(wordBuilder.toString());
//2 拼音匹配
builder.append(" or pinyin like ?");
paramsList.add(wordBuilder.toString());
}
//轉(zhuǎn)換成需要的條件
String condition = builder.toString();
Object[] params = paramsList.toArray();
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
String sql = "select * from product where 1=1 " + condition;
return queryRunner.query(sql, new BeanListHandler<Product>(Product.class), params);
}
}
步驟1:添加div和css,用于顯示自動填充數(shù)據(jù)的div
//HTML頁面已經(jīng)提供
<div id="completeShow">
<ul id="itemul">
<%-- <li>Cras justo odio</li>--%>
</ul>
</div>
//CSS樣式,“./css/main.css” 文件中已提供
#completeShow{
border: 1px solid #999;
min-height: 200px;
position: absolute;
width: 196px;
z-index: 1000;
background-color: #fff;
border-radius: 5px;
display: none;
}
步驟2:將查詢結(jié)果顯示到指定的區(qū)域,數(shù)據(jù)使用<li>包裹,使用bootstrap的list-group-item渲染列表項。
//自動填充
$(function(){
$("#search").keyup(function(){
var url = "/day15_autocomplete/productFindByWordServlet";
var word = $(this).val();
if(word == "") {
//如果沒有輸入關鍵字,隱藏提供區(qū)域
$("#completeShow").slideUp(200);
return false;
}
var params = {"word":word};
$.post(url,params,function(data){
$("#completeShow").html("<ul id='itemul'></ul>");
for(var i = 0 ; i < data.length ; i ++){
var product = data[i];
//處理關鍵字顯示
var str = ""+product.pname + "("+ product.pinyin +")";
$("#itemul").append("<li><a href='#'>"+str+"</a></li>");
$("#completeShow").show();
}
});
}).focus(function(){
//獲得焦點時,如果有搜索項顯示
if($("#completeShow li").size() > 0){
$("#completeShow").show();
}
}).click(function(){
//如果點擊的是文本框,阻止點擊事件,及不觸發(fā)document的click事件
return false;
});
/**
* 點擊其他位置時,隱藏提示區(qū)域
*/
$(document).click(function(){
$("#completeShow").slideUp(200);
});
});
聯(lián)系客服