ajax模擬用戶註冊和搜索頁面

概要

異步簡介

ajax簡介

應用場景1

應用場景2

常見問題及排除方法

小結


1、異步簡介

你打電話問書店老闆有沒有《分佈式系統》這本書,若是是同步通訊機制,書店老闆會說,你稍等,」我查一下",而後開始查啊查,等查好了(多是5秒,也多是一天)告訴你結果(返回結果)。 而異步通訊機制,書店老闆直接告訴你我查一下啊,查好了打電話給你,而後直接掛電話了(不返回結果)。而後查好了,他會主動打電話給你。在這裏老闆經過「回電」這種方式來回調。^1javascript

"異步模式"很是重要。在瀏覽器端,耗時很長的操做都應該異步執行,避免瀏覽器失去響應,最好的例子就是Ajax操做。在服務器端,"異步模式"甚至是惟一的模式,由於執行環境是單線程的,若是容許同步執行全部http請求,服務器性能會急劇降低,很快就會失去響應。^2css


2、ajax簡介

Asynchronous Javascript And XML ----異步的javascript和xml。 頁面發起請求,會將請求發送給瀏覽器內核中的Ajax引擎,Ajax引擎會提交請求到服務器,在這段時間裏,客戶端能夠任意進行任意操做,直到服務器端將數據返回給Ajax引擎後,Ajax引擎再將數據給瀏覽器解析。 html

ajax工做原理.jpg


3、應用場景1

1.功能演示

模擬帳號註冊:註冊頁面中,若是用戶名文本框失去焦點,則進行異步校驗;若是用戶名已經存在,則在右側用紅色字體提示用戶用戶名不可用,而且禁用註冊按鈕,不然提示可用,並解除註冊按鈕禁用。 java

ajax註冊.gif

2.代碼

  1. 頁面源碼(使用了一些Bootstrap樣式):
<div class="form-group">
	<label for="inputname1" class="col-sm-2 col-sm-offset-2 control-label">用戶名:</label>
	<div class="col-sm-3">
		<input type="text" name="remitter" class="form-control" id="inputname1" placeholder="請填寫全稱">
	</div>
	<div class="col-sm-3" id = "msg" style="vertical-align: middle;">
	</div>
</div>
複製代碼
  1. 導入jquery及bootstrap樣式
<link href="${pageContext.request.contextPath}/css/bootstrap.min.css" rel="stylesheet">
<script src="${pageContext.request.contextPath}/js/jquery-1.11.3.min.js"></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js"></script>
複製代碼
  1. ajax異步校驗
<script type="text/javascript">
	// 頁面加載
	$(function(){
		// 觸發文本框失去焦點事件
		$("#inputname1").blur(function(){
			// 初步判斷文本框非空和去掉空格後仍然非空
			if($(this).val() != "" && $.trim($(this).val()) != "") {
				// 使用post請求方式傳輸數據
				var url = "${pageContext.request.contextPath}/CheckServlet";	// 訪問服務器地址
				var params = "remitter=" + $(this).val();	// 檢驗參數
				$.post(url, params, function(d) {	//post請求方式
					if(d > 0) {	//	若是查詢到1條記錄,則提示用戶從新選擇用戶名
						$("#msg").html("<font color='red'>該用戶名太受歡迎,請從新輸入</font>");
						$("#submit").prop("disabled", true);
					}else{	//不然提示可使用該用戶名
						$("#msg").html("用戶名可使用").css("color", "blue");
						$("#submit").prop("disabled", false);
					}
				});
			}else{	//	若是文本框沒有有用的信息則將提示內容清空,並禁用註冊鍵
				$("#msg").html("");
				$("#submit").prop("disabled", true);
			}
		});
	});
</script>
複製代碼
  1. CheckServlet內容
try {
	// post請求解決亂碼問題
	request.setCharacterEncoding("UTF-8");
	// 獲取請求數據
	String remitter = request.getParameter("remitter");
	// 調用service層
	CheckService cs = new CheckService();
	// 返回查詢參數
	int count = cs.find(remitter);
	// 傳遞到客戶端
	response.getWriter().print(count);
} catch (SQLException e) {
	e.printStackTrace();
}
複製代碼
  1. CheckService內容 略......
  2. CheckDao內容
public int find(String remitter) throws SQLException {
	// 使用QueryRunner工具類
	QueryRunner qr = new QueryRunner(C3p0Utils.getDataSource());
	// 編寫sql語句
	String sql = "select count(*) from searchkey where username = ?";
	// 因爲ScalarHandler返回的Object只能強轉成Long類型,必須再次調用intValue()方法才能返回int類型
	return ((Long)qr.query(sql, new ScalarHandler(), remitter)).intValue();
}
複製代碼
  1. C3p0Utils自定義工具類請參考使用
public class C3p0Utils {
	private static DataSource ds = new ComboPooledDataSource("nefu");
	public static DataSource getDataSource() {
		return ds;
	}
}
複製代碼

配置文件c3p0-config.xml存放在src目錄下mysql

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
	<named-config name="nefu">
		<!-- 鏈接數據庫的4項基本參數 -->
		<property name="driverClass">com.mysql.jdbc.Driver</property>
		<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/searchkey_db
		</property>
		<property name="user">root</property>
		<property name="password">123</property>
		<!-- 若是池中數據鏈接不夠時一次增加多少個 -->
		<property name="acquireIncrement">5</property>
		<!-- 初始化鏈接數 -->
		<property name="initialPoolSize">20</property>
		<!-- 最小鏈接受 -->
		<property name="minPoolSize">10</property>
		<!-- 最大鏈接數 -->
		<property name="maxPoolSize">40</property>
		<!-- -JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量 -->
		<property name="maxStatements">0</property>
		<!-- 鏈接池內單個鏈接所擁有的最大緩存statements數 -->
		<property name="maxStatementsPerConnection">5</property>
	</named-config>
</c3p0-config>
複製代碼

應用場景2

1.功能演示

模擬搜索引擎:輸入關鍵字,查詢數據庫,並將查詢結果返回到瀏覽器展現。 jquery

ajax模擬搜索引擎.gif

2.代碼

  1. 頁面源碼
<div class="form-group dropdown">
	<input type="text" class="form-control dropdown-toggle" id="key" style="width: 300px"
		data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" />
	<ul id="list" class="dropdown-menu"
		style="width: 100%; display: none;" aria-labelledby="dropdownMenu"></ul>
</div>
複製代碼
  1. ajax代碼(導包內容與應用場景2一致)
<script>
	// 當單擊備選條是文本框輸入內容
	function selected(obj) {
		$("#key").val($(obj).text());
		$("#list").hide();
	}
	// 頁面加載
	$(function(){
		// 當按鍵彈起事件
		$("#key").keyup(function() {
			// 先將下拉列表清空,並隱藏列表
			$("#list").html("");
			$("#list").hide();
			if($(this).val() != "" && $.trim($(this).val()) != "") {
				url = "${pageContext.request.contextPath}/SearchingServlet";
				params = "keyword=" + $(this).val();
				// post請求
				$.post(url, params, function(d) {
					if(d != null) {
						$(d).each(function(a,b) {	// 遍歷d,並將結果追加到列表後面
							$("#list").append("<li onclick='selected(this)'><a>" + b + "</a></li>");
							$("#list").show();	// 展現列表內容
						})
					}
				}, "json")	// 使用json的數據形式返回數據
			}
		})
	})
</script>
複製代碼
  1. SearchServlet內容
try {
	request.setCharacterEncoding("UTF-8");
	response.setCharacterEncoding("UTF-8");
	String keyword = request.getParameter("keyword");
	SearchingService ss = new SearchingService();
	List<Object> list = ss.find(keyword);
	// 隨機選擇集合中的前10個選項
	Collections.shuffle(list);
	ArrayList<Object> temp = new ArrayList<Object>();
	for (Object object : list) {
		if(temp.size() < 10) {
			temp.add(object);
		}
	}
	// 將temp集合轉換成json格式
	JSONArray jsonarray = JSONArray.fromObject(temp);
	String json = jsonarray.toString();	
	// 傳遞給瀏覽器
	response.getWriter().print(json);
} catch (SQLException e) {
	e.printStackTrace();
}
複製代碼
  1. SearchingService層 略......
  2. SearchingDao層
public List<Object> find(String keyword) throws SQLException {
	QueryRunner qr = new QueryRunner(C3p0Utils.getDataSource());
	// 將關鍵字拆分單個字符
	char[] array = keyword.toCharArray();
	StringBuilder sql = new StringBuilder();
	// where 1 = 1 拼接字符串過程當中,避免沒法肯定and的開始位置
	sql.append("select distinct username from searchkey where 1 = 1");
	// 創建一個list集合存儲參數 注意空格
	List<String> params = new ArrayList<>();
	if(array != null) {
		for (char c : array) {
			if(c != ' ') {
				sql.append( " and username like ?");
				params.add("%" + c + "%");
			}
		}
	}
	List<Object> list = qr.query(sql.toString(), new ColumnListHandler(), params.toArray());
	return list;
}
複製代碼
  1. C3p0Utils自定義工具類及配置文件 略.....

5、常見問題及排除方法

因爲html沒有語法檢查功能(HBuilder好像有,可是加載半天你能忍),因此事件觸發後沒有響應的錯誤很難排查,根據筆者的經驗給出幾點建議ajax

  • 排查語法格式,例如$("inputname1")沒有#號,var url=寫成了val url=(我好像暴露了什麼dog臉)
  • 註釋一部份內容,並使用alert("字符串"),來判斷錯誤的地方,若是是頁面加載也沒有彈框,多是沒有導入jquery庫
  • 使用junit進行單元測試,主要是sql語句,再者容易出現的問題就是數據庫鏈接失敗,注意C3p0Utils的配置文件是否錯誤
  • 頁面500錯誤提示信息,控制檯異常信息均可以幫助定位錯誤內容。

6、小結

  1. 內容較雜,不少細節沒法面面俱到,不清楚的請詢問;
  2. ajax的格式本人瞭解到的有三種,第二種經常使用
$.get(url,[params],[fn],[type]):發送了一個get請求
複製代碼
$.post(url,[params],[fn],[type]):發送一個post請求
複製代碼
$.ajax({選項});
	常見的選項:
		url:路徑,
		data:發送的參數,
		type:請求的方式,
		success:成功時候的回調,
		error:錯誤時候的回調,
		async:是否異步 默認就是異步的方式,
		dataType:返回內容的格式 默認字符串
複製代碼
  1. 本文涉及到json數據格式通常有{"key":value,"key1":value1}[e1,e2],可使用jsonlib調用方法直接將數組、集合等轉成json數據類型。
  2. 使用到的jar包
    jar包
相關文章
相關標籤/搜索