標籤:blog http io ar os 使用 java for sp
執行個體解析java + jQuery + json工作過程(登入)
本文主要講解在java環境下使用jQuery進行JSON資料傳送的互動過程
參考根據作者的賬務管理系統(個人版) 源碼下載 講解
一、相關技術、工具簡介
1、簡單介紹一下JSON,JSON是一種輕量級的資料交換格式。 易於人閱讀和編寫。同時也易於機器解析和產生。已索引值對形式表示資料,和java中的Map的資料存放區形式相似,具體細節請參考http://www.json.org/json-zh.html。
2、對應後台JSON的資料處理工具json-lib,包含各種格式資料的工具類,比如:JavaBean、數組、集合(Collection)等,參考API文檔。
3、jQuery架構中的資料表現形式,如果你熟悉jQuery的話就會發現jQuery的使用的資料轉送都是JSON格式,比如我們經常使用的$.ajax方法:
Js代碼
- $.ajax({
- url : url,
- data : {
- id : chkValue
- },
- cache : false,
- dataType : "json",
- success : function(result){
- alert(result);
- }
- );
其中 {…} 表示的就是JSON格式的資料
二、前台工作方式
為了能夠容易理解以系統登入講解,最後會以一個執行個體的方式講解
1、登入頁面
代碼請參見 http://code.google.com/p/finance-p/source/browse/trunk/login.jsp
Java代碼
- 使用者名稱:
- <input id="loginName" name="loginName" size="20" type="text" />
-
- 密碼:
- <input id="password" name="password" size="20" type="password" />
2、登入javascript檔案 login.js
Js代碼
- /**
- * 設定表單驗證規則
- */
- function regFormValidator() {
- $.formValidator.initConfig({formid:"loginForm"});
- $("#loginName").formValidator({
- onshow : "請輸入使用者名稱",
- onfocus : "使用者名稱至少2個字,最多4個字"
- }).inputValidator({
- min : 1,
- onerror : "你輸入的使用者名稱非法,請確認"
- });
-
- $("#password").formValidator({
- onshow : "請輸入密碼"
- }).inputValidator({
- min : 6,
- onerror : "密碼在6位以上,請確認"
- });
- }
-
- $(function() {
- // 註冊表單驗證外掛程式
- regFormValidator();
-
- $(‘#submit‘).click(function(){
- // 驗證輸入的使用者名稱、密碼是否正確
- var valid = jQuery.formValidator.pageIsValid(‘1‘);
- if (valid) {
- $(this).attr(‘value‘, ‘正在登入……‘).attr(‘disabled‘, true);
- } else {
- return;
- }
-
- // 發送請求
- $.ajax({
- url : ‘login.do‘,
- data : { loginName:$(‘#loginName‘).val(), password: $(‘#password‘).val() },
- success : function(result){
- // 根據result返回資訊判斷是否登入成功
- if(result && result == ‘success‘) {
- window.location.href = ‘index.jsp‘;
- } else {
- alert(‘登入失敗,使用者名稱或密碼錯誤,請重試!‘);
- }
- }
- });
-
- });
- });
這樣當點擊“登入”按鈕的時候觸發ajax請求:
- 驗證表單完整性
- 發送ajax請求到後台,值通過data鍵已JSON格式傳送至後台
- 如果後台返回的result為success時表示登入成功,頁面跳轉至首頁index.jsp
三、後台工作方式
後台要比前台操作複雜一些,以為涉及到資料庫、編碼或者一些商務邏輯
1、獲得請求參數
有兩種方式:
- 通過request.getParameter(”key”)的方式
- 通過json-lib工具包擷取
這我們主要講解怎麼通過json-lib擷取參數
首先我們來寫一個公用的方法,可以返回一個net.sf.json.JSONObject對象,具體代碼如下:
Java代碼
- /**
- * 讀取請求參數轉換JSONObject對象
- *
- * @param request HttpServletRequest 對象
- * @return json格式的String對象
- * @throws Exception
- */
- @SuppressWarnings("unchecked")
- protected JSONObject readJson(HttpServletRequest request) throws Exception {
- JSONObject jsonObject = new JSONObject();
- try {
- Map parameterMap = request.getParameterMap();
- // 通過迴圈遍曆的方式獲得key和value並set到JSONObject中
- Iterator paIter = parameterMap.keySet().iterator();
- while (paIter.hasNext()) {
- String key = paIter.next().toString();
- String[] values = (String[])parameterMap.get(key);
- jsonObject.accumulate(key, values[0]);
- }
- log.debug("從用戶端獲得json=" + jsonObject.toString());
- } catch (Exception e) {
- log.error("擷取json資料出錯,錯誤資訊如下:nt" + e.getMessage());
- e.printStackTrace();
- throw e;
- }
- return jsonObject;
- }
通過這個方法我們可以獲得一個JSONObject對象,然後就可以通過key獲得對應的value;
2、登入處理Action
Java代碼
- public ActionForward login(ActionMapping mapping, ActionForm actionForm,
- HttpServletRequest request,HttpServletResponse response) throws Exception {
- JSONObject jsonObject = readJson(request);
- String name = jsonObject.getString("loginName");
- String pass = jsonObject.getString("password");
- try {
- int loginFlag = userManager.validLogin(name, pass);
- if (loginFlag == UserManager.LOGIN_SUCCESS) {
- User user = userManager.getUserByNameAndPass(name, pass);
- UserUtil.saveUser2Session(user, request);
- log.info("使用者<" + user.getUserName()
- + ",ip=" + request.getRemoteAddr() + ">登入系統");
- print(response, RESBONSE_SUCCESS);
- } else if (loginFlag == UserManager.LOGIN_FAIL) {
- print(response, RESBONSE_ERROR);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
解釋:
在34行我們通過剛剛準備好的readJson方法獲得一個JSONObject對象,接下來通過key獲得使用者名稱和密碼,接下來就是商務邏輯的驗證工作了,通過後我們向前台返回請求結果。
我們還需要一個小方法向前台寫結果,如上面44、46行
Java代碼
- protected void print(HttpServletResponse response, String info) throws IOException {
- try {
- response.getWriter().print(info);
- } catch (IOException e) {
- e.printStackTrace();
- throw e;
- }
- }
/**
* 輸出字元流
*
* @param reps
* 輸出的參數對象
* @param str
* 輸出的內容
*/
public static void outPutStream(HttpServletResponse reps, String str) throws IOException
{
// getResponse().setCharacterEncoding("UTF-8");
// getResponse().setContentType("text/html;charset=UTF-8");
reps.getOutputStream().write(str.toString().getBytes("UTF-8"));
}
outPutStream(response, "{\"code\":\"-12\",\"msg\":\"使用者無效,請重新登入!\"}");
這裡有一點要說明,在獲得輸出資料流的時候有個小插曲,我在開發的時候使用的tomcat5.5.26版本,
當時的寫法為:
Java代碼
- response.getOutputStream().print(info);
Java代碼
- 後來源碼開源後一個網友使用的tomcat6版本,說系統不能正常運行,後來他查到了原因,因為獲得輸出資料流時出了問題,
- 改成getWriter就沒有問題了,集體也沒有搞清楚為什麼會是這樣……
基於java開發時會使用struts,struts需要返回一個ActionMapping對象,但是在ajax請求不需要返回特定頁面,因為根本沒有跳轉頁面的動作,解決辦法很簡單,直接return null就可以了
輸出結果後jQuery的ajax的success方法就接收到了請求結果,然後就可以根據結果處理商務邏輯了O(∩_∩)O~
jQuery ajax 流程全解析