javascript
java笔记:自己动手写javaEE框架(七)--使用JSON和Ajax技术
今天我要將json和ajax引入到我所寫的框架,不過今天用到的技術有部分不是我框架最終使用到的技術,比如ajax技術,我用到的是最為原始的ajax技術,這次算是對老技術的回顧,不過不管技術如何演進,對技術的本質(zhì)的掌握都是十分重要的。
首先我簡單介紹下json的基礎知識。
json的定義是:基于JavaScript語言的輕量級的數(shù)據(jù)交換格式(JavaScript Object Notiation)。(摘錄于有道)
JSON建構于兩種結構:
1. “名稱/值”對的集合(A collection of name/value pairs)。不同的語言中,它被理解為對象(object),記錄(record),結構(struct),字典(dictionary),哈希表(hash table),有鍵列表(keyed list),或者關聯(lián)數(shù)組 (associative array)。
2. 值的有序列表(An ordered list of values)。在大部分語言中,它被理解為數(shù)組(array)。這些都是常見的數(shù)據(jù)結構。事實上大部分現(xiàn)代計算機語言都以某種形式支持它們。這使得一種數(shù)據(jù)格式在同樣基于這些結構的編程語言之間交換成為可能。
在我寫到的架構里,前端和服務端的交互統(tǒng)一通過json來進行,這個做法符合我的觀點,所有邏輯層的通訊都是通過鍵值對的方式進行,,參見我以前的博文:《系統(tǒng)設計與架構筆記:鍵值對在架構設計里的應用》
下面我們繼續(xù)寫框架,首先我新建一張表,它的結構如下圖:
?
下面我將為這張表建立dao、service以及action,下面我將代碼貼在下面(按我開發(fā)的過程):
首先看看工程新的結構目錄,如下圖:
1.首先是/ssiprj/src/cn/com/sharpxiajun/dao/sqlmap包下的映射文件PRODUCT.xml,代碼如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="PRODUCT">
<select id="queryProductList" parameterClass="java.util.Map" resultClass="java.util.HashMap">
select t.id,t.name,t.desc,t.create_date,t.modify_date,t.status from product t
<dynamic prepend="where">
<isNotEmpty prepend="and" property="name">
t.name = #name:VARCHAR#
</isNotEmpty>
</dynamic>
</select>
</sqlMap>
2.在/ssiprj/conf包的SqlMapConfig.xml文件里添加PRODUCT.xml路徑,代碼如下:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" errorTracingEnabled="true"
maxRequests="64" maxSessions="20" maxTransactions="10"
useStatementNamespaces="true"/>
<sqlMap resource="cn/com/sharpxiajun/dao/sqlmap/USERS.xml"/>
<sqlMap resource="cn/com/sharpxiajun/dao/sqlmap/PRODUCT.xml"/>
</sqlMapConfig>
3.在cn.com.sharpxiajun.dao包下建立接口ProductDao,代碼如下:
package cn.com.sharpxiajun.dao;import java.util.List;
import java.util.Map;
public interface ProductDao {
public static final String QUERY_PRODUCT_LIST_SQL = "PRODUCT.queryProductList";
public List<Map<String, Object>> queryProductList(Map<String, Object> params) throws Exception;
}
4.在cn.com.sharpxiajun.dao.impl包下實現(xiàn)接口ProductDao的類ProductDaoImpl,代碼如下:
?
package cn.com.sharpxiajun.dao.impl;import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.stereotype.Repository;
import cn.com.sharpxiajun.dao.ProductDao;
@SuppressWarnings("unchecked")
@Scope("prototype")
@Repository("productDao")
public class ProductDaoImpl implements ProductDao {
@Autowired
@Qualifier("sqlMapClientTemplate")
private SqlMapClientTemplate sqlMapClientTemplate = null;
@Override
public List<Map<String, Object>> queryProductList(Map<String, Object> params)
throws Exception {
return this.sqlMapClientTemplate.queryForList(QUERY_PRODUCT_LIST_SQL, params);
}
}
5.在cn.com.sharpxiajun.service包下建立接口ProductService,代碼如下:
?
package cn.com.sharpxiajun.service;import java.util.List;
import java.util.Map;
public interface ProductService {
public List<Map<String, Object>> queryProductList(Map<String, Object> params) throws Exception;
}
6.在cn.com.sharpxiajun.service.impl包下建立ProductServiceImpl,他實現(xiàn)ProductService接口,代碼如下:
package cn.com.sharpxiajun.service.impl;import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.com.sharpxiajun.dao.ProductDao;
import cn.com.sharpxiajun.service.ProductService;
@SuppressWarnings("unchecked")
@Scope("prototype")
@Transactional
@Service("productService")
public class ProductServiceImpl implements ProductService {
@Autowired
@Qualifier("productDao")
private ProductDao productDao = null;
@Override
public List<Map<String, Object>> queryProductList(Map<String, Object> params)
throws Exception {
return this.productDao.queryProductList(params);
}
}
7.在cn.com.sharpxiajun.action包下建立ProductAction,代碼如下:
package cn.com.sharpxiajun.action;import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.com.sharpxiajun.common.action.BaseAction;
import cn.com.sharpxiajun.service.ProductService;
@SuppressWarnings("serial")
@Scope("prototype")
@Controller("productAction")
public class ProductAction extends BaseAction {
@Autowired
@Qualifier("productService")
private ProductService productService = null;
//輸入值
private String namequery = null;
private Integer id = 0;
private String name = null;
private String desc = null;
private Date createDate = null;
private Date modifyDate = null;
private Boolean status = null;
//輸出值
private List<Map<String, Object>> results = null;//返回查詢的列表
private String msg = null;//系統(tǒng)運行信息
private String flag = null;//操作狀態(tài)標記
private String welcome = null;//歡迎語
public String productinit() throws Exception
{
welcome = "歡迎使用本系統(tǒng)!";
return SUCCESS;
}
public String queryProductList() throws Exception
{
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", namequery);
results = this.productService.queryProductList(map);
flag = "success";
msg = "查詢操作成功!";
welcome = "你的查詢操作已經(jīng)完成!";
return SUCCESS;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public List<Map<String, Object>> getResults() {
return results;
}
public void setResults(List<Map<String, Object>> results) {
this.results = results;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public String getWelcome() {
return welcome;
}
public void setWelcome(String welcome) {
this.welcome = welcome;
}
public String getNamequery() {
return namequery;
}
public void setNamequery(String namequery) {
this.namequery = namequery;
}
}
8.在WEB-INF\jsp包下,建立product.jsp文件,代碼如下:
要在struts2程序里使用json,首先http://code.google.com/p/jsonplugin/downloads/list下載JSON插件的JAR包,我下載的版本是jsonplugin-0.34.jar,把jar包加入到工程的lib里,修改conf包下的struts-action.xml文件,代碼如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="action" extends ="struts-default">
<action name="queryUsersList" class="usersAction" method="queryUsersList">
<result name="success">/WEB-INF/jsp/users.jsp</result>
</action>
<action name="usersinit" class="usersAction" method="usersinit">
<result name="success">/WEB-INF/jsp/users.jsp</result>
</action>
<action name="addUsers" class="usersAction" method="addUsers">
<result name="success">/WEB-INF/jsp/users.jsp</result>
<result name="error">/WEB-INF/common/error.jsp</result>
</action>
</package>
<package name="json" extends ="json-default">
<action name="productinit" class="productAction" method="productinit">
<result name="success">/WEB-INF/jsp/product.jsp</result>
</action>
<action name="queryProductList" class="productAction" method="queryProductList">
<result name="success" type="json"></result>
</action>
</package>
</struts>
上面配置文件的“package”元素和以往不同的是,它擴展了“json-default”而不是“struts-default”。“json-default”是在jsonplugin-0.34.jar包里的struts-plugin.xml中定義的。該文件同時定義了“json”的結果類型,有興趣的朋友可以打開此文件看看。
下面我們啟動tomcat服務器,在瀏覽器地址欄里填入下面地址:http://localhost:8080/ssiprj/productinit.action
頁面如下圖:
?
?
點擊按鈕query,結果是:
選擇用記事本打開,顯示結果如下:
?
{"createDate":null,"desc":null,"flag":"success","id":0,"modifyDate":null,"msg":"查詢操作成功!","name":null,"namequery":"","results":[{"id":1,"desc":"apple","create_date":"2011-10-28T00:00:00","status":true,"modify_date":"2011-10-28T00:00:00","name":"ipad"},
{"id":2,"desc":"google","create_date":"2011-10-28T00:00:00","status":true,"modify_date":"2011-10-28T00:00:00","name":"android"}],"status":null,"welcome":"你的查詢操作
已經(jīng)完成!"}
結果居然是一個下載的文本文件,這個不符合我們的要求,下面我用ajax技術來處理這些返回結果。
AJAX技術:服務端返回客戶端JSON數(shù)據(jù)
上面的例子里,我們服務端程序返回到前端頁面的數(shù)據(jù)格式是json方式,下面的程序就是使用ajax來訪問服務端程序并且展示頁面如何處理json對象,這里我們只需要修改product.jsp代碼,代碼如下:
?
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSON</title>
</head>
<body>
名稱:<input type="text" id="namequery" name="namequery"/> <input type="button" onClick="queryBtnClick();" value="query"/>
<div id="datashow"></div>
</body>
</html>
<script src="<%= request.getContextPath()%>/js/json.js"/></script>
<script type="text/javascript">
var xmlHttp;//XMLHttpRequest對象
//創(chuàng)建XMLHttpRequest對象
function createXMLHttpRequest()
{
if (window.ActiveXobject)
{
xmlHttp =new ActiveXOject('Microsoft.XMLHTTP');
}elseif (window.XMLHttpRequest)
{
xmlHttp =new XMLHttpRequest();
}
}
//查詢操作
function queryBtnClick()
{
var url ="queryProductList.action";
createXMLHttpRequest();
xmlHttp.open("POST",url,true);
xmlHttp.onreadystatechange = jsonCallBack;
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");//使用POST傳遞信息時候用到的
xmlHttp.send(null);
}
//處理返回數(shù)據(jù)的回調(diào)函數(shù)
function jsonCallBack()
{
if (xmlHttp.readyState ==4)
{
if (xmlHttp.status ==200)
{
parseResults();
}
}
}
//處理返回數(shù)據(jù)的方法
function parseResults()
{
var product = eval('('+ xmlHttp.responseText +')');
var showstr ="<table border='1'>";
for (var i =0;i < product.results.length;i++)
{
obj = product.results[i];
showstr +='<tr>';
showstr +='<td>'+ obj.id +'</td>';
showstr +='<td>'+ obj.name +'</td>';
showstr +='<td>'+ obj.desc +'</td>';
showstr +='<td>'+ obj.create_date +'</td>';
showstr +='<td>'+ obj.modify_date +'</td>';
showstr +='<td>'+ obj.status +'</td>';
showstr +='</tr>';
}
showstr +='</table>';
document.getElementById('datashow').innerHTML = showstr;
}
</script>
這次提交服務端請求里沒有放入任何參數(shù),也就是說前端沒有傳參數(shù)到服務端,因此這個測試代碼就是展示ajax是如何調(diào)用的以及如何處理返回數(shù)據(jù)是json格式的數(shù)據(jù),我們點擊頁面的query按鈕,結果如下:
?
大家看到了數(shù)據(jù)成功返回并且被正確處理。
AJAX技術:客戶端傳給服務端JSON數(shù)據(jù)
大家在http://www.json.org/網(wǎng)站里下載json.js腳本以及json在java里的操作類,我下載了這些文件,把他們放到我寫的工程里,結果如下:
?
?
(我發(fā)現(xiàn)我的jsp文件夾放的位置不對了,導致最后在struts-action.xml里面放回頁面前還要加/WEB-INF/,哎,算了,將錯就錯吧!)
我們修改ProductAction.java文件,代碼如下:
?
package cn.com.sharpxiajun.action;import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.com.sharpxiajun.common.action.BaseAction;
import cn.com.sharpxiajun.common.util.JSONObject;
import cn.com.sharpxiajun.service.ProductService;
@SuppressWarnings("serial")
@Scope("prototype")
@Controller("productAction")
public class ProductAction extends BaseAction {
@Autowired
@Qualifier("productService")
private ProductService productService = null;
//輸入值
private String namequery = null;
private Integer id = 0;
private String name = null;
private String desc = null;
private Date createDate = null;
private Date modifyDate = null;
private Boolean status = null;
private String jsonQuery = null;//獲得json格式的參數(shù)
//輸出值
private List<Map<String, Object>> results = null;//返回查詢的列表
private String msg = null;//系統(tǒng)運行信息
private String flag = null;//操作狀態(tài)標記
private String welcome = null;//歡迎語
public String productinit() throws Exception
{
welcome = "歡迎使用本系統(tǒng)!";
return SUCCESS;
}
public String queryProductList() throws Exception
{
Map<String, Object> map = new HashMap<String, Object>();
//map.put("name", namequery);
JSONObject jsonObject = new JSONObject(jsonQuery);//把查詢參數(shù)轉(zhuǎn)化為json對象
map.put("name", jsonObject.get("namequery"));
results = this.productService.queryProductList(map);
flag = "success";
msg = "查詢操作成功!";
welcome = "你的查詢操作已經(jīng)完成!";
return SUCCESS;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
public List<Map<String, Object>> getResults() {
return results;
}
public void setResults(List<Map<String, Object>> results) {
this.results = results;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public String getWelcome() {
return welcome;
}
public void setWelcome(String welcome) {
this.welcome = welcome;
}
public String getNamequery() {
return namequery;
}
public void setNamequery(String namequery) {
this.namequery = namequery;
}
public String getJsonQuery() {
return jsonQuery;
}
public void setJsonQuery(String jsonQuery) {
this.jsonQuery = jsonQuery;
}
}
修改頁面product.jsp,代碼如下:
?
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSON</title>
</head>
<body>
名稱:<input type="text" id="namequery" name="namequery"/> <input type="button" onClick="queryBtnClick();" value="query"/>
<div id="datashow"></div>
</body>
</html>
<script src="<%= request.getContextPath()%>/js/json.js"/></script>
<script type="text/javascript">
var xmlHttp;//XMLHttpRequest對象
//創(chuàng)建XMLHttpRequest對象
function createXMLHttpRequest()
{
if (window.ActiveXobject)
{
xmlHttp =new ActiveXOject('Microsoft.XMLHTTP');
}elseif (window.XMLHttpRequest)
{
xmlHttp =new XMLHttpRequest();
}
}
//查詢操作
function queryBtnClick()
{
var url ="queryProductList.action";
createXMLHttpRequest();
xmlHttp.open("POST",url,true);
xmlHttp.onreadystatechange = jsonCallBack;
var obj = getQueryParams();//獲取查詢參數(shù)對象
var queryJson ="jsonQuery="+ JSON.stringify(obj);//構建查詢參數(shù)
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");//使用POST傳遞信息時候用到的
xmlHttp.send(queryJson);//將參數(shù)發(fā)送到服務端
}
//處理返回數(shù)據(jù)的回調(diào)函數(shù)
function jsonCallBack()
{
if (xmlHttp.readyState ==4)
{
if (xmlHttp.status ==200)
{
parseResults();
}
}
}
//處理返回數(shù)據(jù)的方法
function parseResults()
{
var product = eval('('+ xmlHttp.responseText +')');
var showstr ="<table border='1'>";
for (var i =0;i < product.results.length;i++)
{
obj = product.results[i];
showstr +='<tr>';
showstr +='<td>'+ obj.id +'</td>';
showstr +='<td>'+ obj.name +'</td>';
showstr +='<td>'+ obj.desc +'</td>';
showstr +='<td>'+ obj.create_date +'</td>';
showstr +='<td>'+ obj.modify_date +'</td>';
showstr +='<td>'+ obj.status +'</td>';
showstr +='</tr>';
}
showstr +='</table>';
document.getElementById('datashow').innerHTML = showstr;
}
//獲取查詢參數(shù)對象
function getQueryParams()
{
returnnew queryObj();
}
//構建查詢參數(shù)類
function queryObj()
{
this.namequery = document.getElementById('namequery').value;
}
</script>
代碼里面我寫了注釋,這里就不做過多解釋了。
我們在瀏覽器地址欄里錄入:http://localhost:8080/ssiprj/productinit.action,在名稱框里錄入ipad,點擊query查詢按鈕,結果如下:
?
控制臺打印日志:
|statement| select t.id,t.name,t.desc,t.create_date,t.modify_date,t.status from product t where t.name = 'ipad'|resultset|
|commit|
返回結果是:
[{id=1, desc=apple, create_date=2011-10-28, status=true, modify_date=2011-10-28, name=ipad}]
攔截器執(zhí)行結束!!
操作成功了!!!!
最后總結下了:struts2把返回給客戶端的數(shù)據(jù)封裝成json格式,前端再處理,這個做起來很自然,也帶來了編寫代碼的便利,但是從客戶端到服務端這種做法就有點奇怪了,至少沒有看到便利之處,當然今天寫的代碼都很簡單,沒有把許多功能抽象出來,不管怎樣,讓action把返回值封裝成json,前端的參數(shù)也封裝成json格式這就是我的框架里面所追求的。下一篇文章我將引入jquery了,為了展示數(shù)據(jù)我會使用到jqgrid,下一個階段我將著重寫寫前端技術。
?
?
?
?
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/sharpxiajun/archive/2011/10/29/2228290.html
總結
以上是生活随笔為你收集整理的java笔记:自己动手写javaEE框架(七)--使用JSON和Ajax技术的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IDEA破解 2017 IDEA lic
- 下一篇: gradle idea java ssm