在異步應用程序中發送和接收信息時,可以選擇以純文本和 XML 作為數據格式。為了更好的使用ajax,我們將學習一種有用的數據格式 JavaScript Object Notation(JSON),以及如何使用它更輕松地在應用程序中移動數據和對象。JSON是一種簡單的數據交換格式,在某些方面,它的作用與XML非常類似,但比XML更為簡單,JSON的語法簡化了數據交換的難度,而且提供了一種偽對象的方式。
Java的對象 < - >JavaScript對象(json數據格式)
簡單地說,JSON 可以將 JavaScript 對象中表示的一組數據轉換為字符串(偽對象),然后就可以在函數之間輕松地傳遞這個字符串,或者在異步應用程序中將字符串從 Web 客戶端傳遞給服務器端程序。這個字符串看起來有點兒古怪(稍后會看到幾個示例),但是 JavaScript 很容易解釋它,而且 JSON 可以表示比名稱/值對更復雜的結構。例如,可以表示數組和復雜的對象,而不僅僅是鍵和值的簡單列表。
關於JSON對象
1、使用JavaScript語法創建對象
//定義一個函數,作為構造函數
fucntion person(name,sex)
{
this.name=name;
this.sex=sex;
}
//創建一個實例
var p=new Person(‘張三’,’男’);
//輸出Person實例
alert(p.name);
注意:通過該方式創建的對象是一般的腳本對象
2、從JavaScript1.2開始創建對象有了一種更快捷的語法(Json的語法),如下:
var obj={name:"張三","sex":'男'};
alert(obj.sex);
關於數組
1、早期的JavaScript數組
var arr=new Array();
arr[0]=’a’;
arr[1]=’bbc’
我們也可以通過如下方式創建數組
var arr=new Array(‘a’,’bbc’);
2、使用JSON語法,則可以通過如下方式創建數組
var arr=[‘a’,’bbc’];
按照最簡單的形式,可以用下面這樣的 JSON 表示名稱/值對:
{ "firstName":"Brett" } |
這個示例非常基本,而且實際上比等效的純文本名稱/值對占用更多的空間:
firstName=Brett |
但是,當將多個名稱/值對串在一起時,JSON 就會體現出它的價值了。首先,可以創建包含多個名稱/值對的記錄,比如:
{"firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com"} |
從語法方面來看,這與名稱/值對相比並沒有很大的優勢,但是在這種情況下 JSON 更容易使用,而且可讀性更好。例如,它明確地表示以上三個值都是同一記錄的一部分;花括號使這些值有了某種聯系。
當需要表示一組值時,JSON 不但能夠提高可讀性,而且可以減少復雜性。例如,假設您希望表示一個人名列表。在 XML 中,需要許多開始標記和結束標記;如果使用典型的名稱/值對(就像在本系列前面文章中看到的那種名稱/值對),那么必須建立一種專有的數據格式,或者將鍵名稱修改為 person1-firstName
這樣的形式。
如果使用 JSON,就只需將多個帶花括號的記錄分組在一起:
{ "people": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" } ]} |
這不難理解。在這個示例中,只有一個名為 people
的變量,值是包含三個條目的數組,每個條目是一個人的記錄,其中包含名、姓和電子郵件地址。上面的示例演示如何用括號將記錄組合成一個值。當然,可以使用相同的語法表示多個值(每個值包含多個記錄):
{ "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" } ], "authors": [ { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] } |
這里最值得注意的是,能夠表示多個值,每個值進而包含多個值。但是還應該注意,在不同的主條目(programmers、authors 和 musicians)之間,記錄中實際的名稱/值對可以不一樣。JSON 是完全動態的,允許在 JSON 結構的中間改變表示數據的方式。甚至可以聲明如下的Json對象
var obj2={people:{name:'張三',sex:"男"}}
alert(obj2.people.name);
在處理 JSON 格式的數據時,沒有需要遵守的預定義的約束。所以,在同樣的數據結構中,可以改變表示數據的方式,甚至可以以不同方式表示同一事物。
{deptid:'1',deptname:'開發部',deptnum:'2',deptdesc:'開發相關',
emps:[{empid:1,empname:'張三',sex:’男’,age:’20’},{empid:2,empname:'張三',sex:’男’,age:’20’},{empid:3,empname:'張三',sex:’男’,age:’20’}]}
掌握了 JSON 格式之后,在 JavaScript 中使用它就很簡單了。JSON 是 JavaScript 原生格式,這意味着在 JavaScript 中處理 JSON 數據不需要任何特殊的 API 或工具包。
例如,可以創建一個新的 JavaScript 變量,然后將 JSON 格式的數據字符串直接賦值給它:
var people = { "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" } ], "authors": [ { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] } |
這非常簡單;現在 people
包含前面看到的 JSON 格式的數據。但是,這還不夠,因為訪問數據的方式似乎還不明顯。
盡管看起來不明顯,但是上面的長字符串實際上只是一個數組;將這個數組放進 JavaScript 變量之后,就可以很輕松地訪問它。實際上,只需用點號表示法來表示數組元素。所以,要想訪問 programmers 列表的第一個條目的姓氏,只需在 JavaScript 中使用下面這樣的代碼:
people.programmers[0].lastName; |
注意,數組索引是從零開始的。所以,這行代碼首先訪問 people
變量中的數據;然后移動到稱為 programmers
的條目,再移動到第一個記錄([0]
);最后,訪問lastName
鍵的值。結果是字符串值 “McLaughlin”。
下面是使用同一變量的幾個示例。
people.authors[1].genre// Value is "fantasy" people.musicians[3].lastName // Undefined. This refers to the fourth entry,and there isn't one people.programmers[2].firstName// Value is "Elliotte" |
利用這樣的語法,可以處理任何 JSON 格式的數據,而不需要使用任何額外的 JavaScript 工具包或 API。
正如可以用點號和括號訪問數據,也可以按照同樣的方式輕松地修改數據:
people.musicians[1].lastName = "Rachmaninov"; |
在將字符串轉換為 JavaScript json格式對象之后,就可以像這樣修改變量中的數據。
注意:json格式的對象和json文本是不同的
var obj={name:"張三","sex":'男'}; //json格式的對象
var str="{name:"張三","sex":'男'}"; //json格式的字符串(json格式的文本)
當然,如果不能輕松地將對象轉換回本文提到的文本格式,那么所有數據修改都沒有太大的價值。在 JavaScript 中這種轉換也很簡單:
var newJSONtext = people.toJSONString(); |
這樣就行了!現在就獲得了一個可以在任何地方使用的文本字符串,例如,可以將它用作 Ajax 應用程序中的請求字符串。
更重要的是,可以將任何 JavaScript 對象轉換為 JSON 文本。並非只能處理原來用 JSON 字符串賦值的變量。為了對名為 myObject
的對象進行轉換,只需執行相同形式的命令:
<script type="text/javascript">
function Car(make,model,year,color)
{
this.make=make;
this.model=model;
this.year=year;
this.color=color;
}
function showCar()
{
var carr = new Car("Dodge","Coronet R/T",1968,"yellow");
alert(carr.toJSONString());
}
</script>
這就是 JSON 與其他數據格式之間最大的差異。如果使用 JSON,只需調用一個簡單的函數,就可以獲得經過格式化的數據,可以直接使用了。對於其他數據格式,需要在原始數據和格式化數據之間進行轉換。即使使用 Document Object Model 這樣的 API(提供了將自己的數據結構轉換為文本的函數),也需要學習這個 API 並使用 API 的對象,而不是使用原生的 JavaScript 對象和語法。
最終結論是,如果要處理大量 JavaScript 對象,那么 JSON 幾乎肯定是一個好選擇,這樣就可以輕松地將數據轉換為可以在請求中發送給服務器端程序的格式(Ajax)。
四、JSON在Ajax中的應用
JSON(JavaScript Object Notation)一種簡單的數據格式,比xml更輕巧。 JSON 是 JavaScript 原生格式,這意味着在 JavaScript 中處理 JSON 數據不需要任何特殊的 API 或工具包。
通過以上學習我們知道JSON的規則很簡單:對象是一個無序的“‘名稱/值’對”集合。一個對象以“{”(左括號)開始,“}”(右括號)結束。每個“名稱”后跟一個“:”(冒號);“‘名稱/值’對”之間使用“,”(逗號)分隔。
1、通過Json格式來聲明對象和操作對象
案例:
js 代碼
function showJSON()
{
var user =
{
"username":"andy",
"age":20,
"info": { "tel": "123456", "cellphone": "98765"},
"addresses":
[
{"city":"beijing","postcode":"222333"},
{"city":"newyork","postcode":"555666"}
]
}
alert(user.username);
alert(user.age);
alert(user.info.cellphone);
alert(user.address[0].city);
alert(user.address[0].postcode);
}
這表示一個user對象,擁有username, age, info, address 等屬性。
同樣也可以用JSON來簡單的修改數據,修改上面的例子
js 代碼
function showJSON() {
var user =
{
"username":"andy",
"age":20,
"info": { "tel": "123456", "cellphone": "98765"},
"address":
[
{"city":"beijing","postcode":"222333"},
{"city":"newyork","postcode":"555666"}
]
}
alert(user.username);
alert(user.age);
alert(user.info.cellphone);
alert(user.address[0].city);
alert(user.address[0].postcode);
user.username = "Tom";
alert(user.username);
}
2、一般對象轉換成JSON格式的字符
JSON提供了json.js包,下載http://www.json.org/json.js 后,將其引入然后就可以簡單的使用object.toJSONString()轉換成JSON數據。
js 代碼
function Car(make, model, year, color) {
this.make = make;
this.model = model;
this.year = year;
this.color = color;
}
function showCar() {
var carr = new Car("Dodge", "Coronet R/T", 1968, "yellow");
alert(carr.toJSONString());
}
2、js對象和JSON格式的js對象、JSON格式的js對象和JSON文本的轉換
可以使用eval來轉換JSON字符到JSON格式的Object
js 代碼
function myEval() {
var str = '{ "name": "張三", "sex": "男" }';
var obj = eval('(' + str + ')');
alert(obj.toJSONString());
}
或者使用parseJSON()方法
function myparse()
{
var str= '{ "name": "張三", "sex": "男" }';
var obj=str.parseJSON(); //把其Json文本解析成為json對象
alert(obj.toJSONString()); //把json對象轉換成JSON 文本
}
3、從Java 類產生json對象(json-lib)
Jar包:
從Java 類產生json對象要使用json-lib jar包
json的jar包
json-lib-2.2.2-jdk15.jar
json-lib的依賴包:
commons-logging.jar
common.lang.jar
commons-beanutils.jar
commons-collections-3.0.jar
ezmorph-0.9.2.jar
作用:
json-lib可以在服務器端把java對象轉換成json對象、從json對象轉化到Java對象,比如:
json-lib可以將java中的Array,Collections,Object,XML轉化成json對象,反之也可以將json對象轉化成java對象.
配置:
需要把json-lib-2.2.2-jdk15.jar以及依賴都要放到項目的lib庫下
常用的JSON API:
(1)、JSONObject
//java對象或滿足一定格式的字符串("{username:'admin',password:'12345',..}")轉化為JSONObject對象,用法:
JSONObject json=JSONObject.fromObject(userinfo);
//從json對象中根據鍵名取對應的值, username為鍵名
json.getObject("username");
//json對象到java對象的轉化(jsonobject-->po)
Userinfo userinfo=(Dept)JSONObject.toBean(jsonObject,Userinfo.class);
//Json對象轉化成json文本字符串
String josStr=JSONObject.fromObject(userinfo).toString();
(2)、JSONArray
boolean[] boolArray={true,false};
List list = new ArrayList();
Map map=new HashMap();
bject[] test={new Userinfo(),new Userinfo()};
//轉化為java的數組Array為json對象
JSONArray jsonArray = JSONArray.fromObject(boolArray);
//System.out.println(jsonArray.toString());
JSONArray jsonArray1=JSONArray.fromObject("['1','2','3']");
//System.out.println(jsonArray1.toString());
list.add("first");
list.add("second");
list.add(new Userinfo());
//轉換java的List為json對象
JSONArray jsonList = JSONArray.fromObject(list);
System.out.println(jsonList);
//轉換java的Map為json對象
map.put("name", "windfree");
map.put("bool", Boolean.TRUE);
map.put("int",new Integer(0));
map.put( "arr", new String[]{"a","b"} );
map.put("func", "function (i){ return this.arr[i]; }");
map.put("bean",test);
JSONObject jsonMap = JSONObject.fromObject(map);
//System.out.println(jsonMap);
思考:什么時候在客戶端及服務器端使用json格式的數據
4、下面使用prototype寫一個JSON的ajax例子
案例:
在頁面中寫一個ajax的請求
js 代碼:
function sendRequest()
{
var url = "/WLLTWebApp/JsonTestServlet";
var mailAjax = new Ajax.Request(
url,
{
method: 'get',
onComplete: jsonResponse
}
);
}
function jsonResponse(originalRequest) {
alert(originalRequest.responseText);
var myobj = originalRequest.responseText.parseJSON();
alert(myobj.name);
}
服務器端代碼:
先寫一個servlet,java 代碼
package org.wllt.www.actions;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.wllt.www.beans.Userinfo;
public class JsonTestServlet extends HttpServlet
{
public JsonTestServlet(){ }
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=GBK");
System.out.println(request.getParameter("someParameter"));
PrintWriter out =response.getWriter();
//(1)使用JSON API包中JSONObject的fromObject方法把Java對象轉換成JSon對象
//Userinfo info=new Userinfo("admin","123456");
//JSONObject obj=JSONObject.fromObject(info);
//out.println(obj);
//(2)或者使用
out.print("{ \"username\": \"張三\", \"password\": \"123\" }");
out.println("未來藍圖歡迎你!");
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
{
this.doPost(request, response);
}
}
View
|
Controller |
Java中 轉換為Json對象-->Java對象 |
瀏 覽 器 |
Js中 Json文本或js對象-->Json對象- |
。。。。 |
Java中 轉換為Json對象<--Java對象 |
Js中 Json對象 <--Json文本
|
prototype-1.5.1.js中提供了JSON的方法,String.evalJSON(), 可以不使用json.js中的函數對從服務器端響應到頁面的json文本對象, 修改上面的方法
js代碼
function jsonResponse(originalRequest)
{
alert(originalRequest.responseText);
var myobj = originalRequest.responseText.evalJSON(true);
alert(myobj.name);
}
5、JSON服務器端的數據格式轉化的應用
JSON還提供了java的jar包 http://www.json.org/java/index.html API也很簡單,下面舉個案例:
在javascript中填加請求參數
js代碼
function Car(make, model, year, color) {
this.make = make;
this.model = model;
this.year = year;
this.color = color;
}
function sendRequest()
{
var carr = new Car("Dodge", "Coronet R/T", 1968, "yellow");
var pars = "car=" + carr.toJSONString();
var url = "/MyWebApp/JSONTest1";
var mailAjax = new Ajax.Request(
url,
{
method: 'get',
parameters: pars,
onComplete: jsonResponse
}
);
}
使用JSON請求字符串就可以簡單的生成JSONObject並進行解析(要使用json-lib.jar)
java 代碼
private void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {
String s3 = request.getParameter("car");
try {
JSONObject jsonObj = new JSONObject(s3);
System.out.println(jsonObj.getString("model"));
System.out.println(jsonObj.getInt("year"));
} catch (JSONException e) {
e.printStackTrace();
}
response.getWriter().print("{\"name\": \"張三\",\"sex\": \"男\" }");
}
同樣可以使用JSONObject生成JSON字符串,修改servlet
java代碼
private void doService(HttpServletRequest request, HttpServletResponse response) throws IOException {
String s3 = request.getParameter("car");
try {
JSONObject jsonObj = new JSONObject(s3);
System.out.println(jsonObj.getString("model"));
System.out.println(jsonObj.getInt("year"));
} catch (JSONException e) {
e.printStackTrace();
}
JSONObject resultJSON = new JSONObject();
try {
resultJSON.append("name", "張三")
.append("sex", "男")
.append("age", new Integer(22));
System.out.println(resultJSON.toString());
}catch(JSONException e) {
e.printStackTrace();
}
response.getWriter().print(resultJSON.toString());
}
js 代碼
function jsonResponse(originalRequest)
{
alert(originalRequest.responseText);
var myobj = originalRequest.responseText.evalJSON(true);
alert(myobj.name);
alert(myobj.age);
}
五、Struts 2中使用Json ajax支持
JSON插件提供了一種名為json的ResultType,一旦為某個Action指定了一個類型為json的Result,則該Result無需映射到任何視圖資源。因為JSON插件會負責將Action里的狀態信息序列化成JSON格式的數據,並將該數據返回給客戶端頁面的 JavaScript。
簡單地說,JSON插件允許我們在JavaScript中異步調用Action,而且Action不再需要使用視圖資源來顯示該Action里的狀態信息,而是由JSON插件負責將Action里的狀態信息返回給調用頁面——通過這種方式,就可以完成Ajax交互。
Struts2提供了一種可插拔方式來管理插件,安裝Struts2的JSON插件與安裝普通插件並沒有太大的區別,一樣只需要將Struts2插件的JAR文件復制到Web應用的WEB-INF/lib路徑下即可。
安裝JSON插件按如下步驟進行:
(1)登陸http://code.google.com/p/jsonplugin/downloads/list 站點,下載Struts2的JSON插件的最新版本,當前最新版本是0.7,我們可以下載該版本的JSON插件。
(2)將下載到的jsonplugin-0.7.jar文件復制到Web應用的WEB-INF路徑下,即可完成JSON插件的安裝。
實現Action邏輯
假設deptnew.html輸入頁面中包含了四個表單域,這四個表單域對於四個請求參數,因此應該使用Action來的dept對象封裝這四個請求參數。四個表單域的name分別為dept.deptid、dept.deptname、dept.deptnum和dept.deptdesc。
處理該請求的Action類代碼如下:
package org.wllt.ajax.actions;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.wllt.ajax.beans.Dept;
import com.googlecode.jsonplugin.annotations.JSON;
import com.opensymphony.xwork2.Action;
public class JSONExample
{
//封裝請求參數的三個屬性
private String field1;
private transient String field2;
private String field3;
//封裝處理結果的屬性
private int[] ints ={10, 20};
private Map map = new HashMap();
private String customName = "custom";
//日期格式的屬性
private Date date;
private Dept dept;
//三個請求參數對應的setter和getter方法
@JSON(serialize=false)
public String getField1(){
return field1;
}
public void setField1(String field1)
{
this.field1 = field1;
}
//封裝處理結果的屬性的setter和getter方法
public int[] getInts()
{
return ints;
}
public void setInts(int[] ints)
{
this.ints = ints;
}
@JSON(format="yyyy-MM-dd")
public Map getMap()
{
return map;
}
public void setMap(Map map)
{
this.map = map;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
public String getField3() {
return field3;
}
public void setField3(String field3) {
this.field3 = field3;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
//使用注釋語法來改變該屬性序列化后的屬性名
@JSON(name="newName")
public String getCustomName()
{
return this.customName;
}
@JSON(format="yyyy-MM-dd")
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String execute()
{
map.put("name", "yeeku");
map.put("curdate",new Date());
return Action.SUCCESS;
}
}
在上面代碼中,使用了JSON注釋,注釋時指定了name域,name域指定Action屬性被序列化成JSON對象的屬性名。除此之外,JSON注釋還支持如下幾個域:
Name:Action屬性被序列化成JSON對象的屬性名
serialize:設置是否序列化該屬性(默認的action的所有屬性都會序列化成json文本響應到原頁面,也可以根據需要設定某些屬性不序列化)。也可以通過在配置json類型的結果的時候定義需要不序列化的屬性:
<result name="success" type="json">
<param name="excludeProperties">service,joindate,dept</param>
</result>
deserialize:設置是否反序列化該屬性。
format:設置用於格式化輸出、解析日期表單域的格式。例如"yyyy-MM-dd'T'HH:mm:ss"。
一般需要注釋到需要轉換日期格式屬性的get方法上面
配置該Action與配置普通Action存在小小的區別,為該Action配置結果類型為json的Result。而這個Result無需配置任何視圖資源,只需要把通過該結果把json文本響應到原頁面。
配置該Action的struts.xml文件代碼如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.locale" value="zh_CN"/>
<constant name="struts.action.extension" value="do,action"/>
<package name="json" extends="json-default">
<action name="dept" class="org.wllt.ajax.actions.DeptAction">
<result type="json"/>
</action>
</package>
</struts>
在上面配置文件中有兩個值得注意的地方:
第一個地方是配置struts.i18n.encoding常量時,不再是使用GBK編碼,而是UTF-8編碼,這是因為Ajax的POST請求都是以UTF-8的方式進行編碼的。
第二個地方是配置包時,自己的包繼承了json-default包,而不再繼承默認的default包,這是因為只有在該包下才有json類型的Result。
實現JSP頁面first.jsp:
為了簡單地訪問DOM節點,這里用了JavaScript框架Prototype.js.
<html>
<head>
<title>使用JSON插件</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="./js/prototype.js" type="text/javascript">
</script>
<script language="JavaScript">
function gotClick()
{
//請求的地址
var url='./dept.do';
//將Form中所有Input對象的值轉化為一個URL String,方便把Form轉為用 URL Get方式//的Ajax提交,常用Ajax提交Form的例子:
var params=Form.serialize('form1');
//創建Ajax.Request對象,對應於發送請求
var myAjax=new Ajax.Request(url,{
//請求方式:POST
method:'post',
//請求參數
parameters:params,
//指定回調函數
onComplete: processResponse,
//是否異步發送請求
asynchronous:true
});
}
function processResponse(request)
{
$("show").innerHTML=request.responseText;
}
</script>
</head>
<body>
<form id="form1" name="form1" method="post">
部門編號<INPUT TYPE="text" name="dept.deptid" id="deptid"/><br>
部門名稱<INPUT TYPE="text" name="dept.deptname" id="deptname"/><br>
部門編制<INPUT TYPE="text" name="dept.deptnum" id="deptnum"/><br>
部門描述<INPUT TYPE="text" name="dept.deptdesc" id="deptdesc"/><br>
<INPUT TYPE="button" value="提交" onClick="gotClick();"/>
</form>
<div id="show">
</div>
</body>
</html>
六、當json碰到hibernate 延時加載
在開發Struts2.0+hibernate3.2+spring2.0項目過程中,遇到了failed to lazily initialize a collection of role: org.wllt.www.pojo.Dept.emps, no session or session was closed 這個異常的出現,通過以下方法可以解決這個問題:
1、是把對應一對多的那兩個列lazy=true改為lazy=false即可;
2、對於查詢中如果用的是xxx.load(class,id)則改為xxx,get(class,id);
3、在web.xml文件中加入:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
<init-param>
<param-name>singleSession</param-name>
<param-value>false</param-value>
</init-param>
<!--這個-- <init-param>一定要加不然很可能會報錯: org.springframework.dao.InvalidDataAccessApiUsageException:Write operations are not allowed in read-only mode (FlushMode.NEVER) - turn your Session into FlushMode.AUTO or remove 'readOnly' marker from transaction definition
-->
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.wllt</url-pattern>
</filter-mapping>
對以上方法進行一一測試,到后來結果都是一樣,出現同樣的異常,其實spring能很好地解決這個問題,Spring框架為Hibernate延遲加載與DAO模式的整合提供了一種方便的解決方法。以一個Web應用為例,Spring提供了OpenSessionInViewFilter和OpenSessionInViewInterceptor。我們可以隨意選擇一個類來實現相同的功能。兩種方法唯一的不同就在於interceptor在Spring容器中運行並被配置在web應用的上下文中,而Filter在Spring之前運行並被配置在web.xml中。不管用哪個,他們都在請求將當前會話與當前(數據庫)線程綁定時打開Hibernate會話。一旦已綁定到線程,這個打開了的Hibernate會話可以在DAO實現類中透明地使用。這個會話會為延遲加載數據庫中值對象的視圖保持打開狀態。一旦這個邏輯視圖完成了,Hibernate會話會在Filter的doFilter方法或者Interceptor的postHandle方法中被關閉。用spring解決這個問題而且不用把lazy設置為false,提高性能。
方法是:在web.xml中加入以下配置:
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
如果把這個配置隨意地加到web.xml的最后,會出現相應的錯誤,其實該過濾器和Struts2的過濾器有順序的問題,應該是:
OpenSessionInViewFilter
FilterDispatcher
的順序,最后調整過濾器的順序,問題解決。
注意:有些時候會出現一些頁面或者一些其他的action過濾不到,可以修改如下:
<url-pattern>/*</url-pattern>
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,采用完全獨立於語言的文本格式,是理想的數據交換格式。同時,JSON是 JavaScript 原生格式,這意味着在 JavaScript 中處理 JSON數據不須要任何特殊的 API 或工具包。
本文主要是對JS操作JSON的要領做下總結。
在JSON中,有兩種結構:對象和數組。
1. 一個對象以“{”(左括號)開始,“}”(右括號)結束。每個“名稱”后跟一個“:”(冒號);“‘名稱/值’ 對”之間運用 “,”(逗號)分隔。 名稱用引號括起來;值如果是字符串則必須用括號,數值型則不須要。例如:
var o={"xlid":"cxh","xldigitid":123456,"topscore":2000,"topplaytime":"2009-08-20"};
2. 數組是值(value)的有序集合。一個數組以“[”(左中括號)開始,“]”(右中括號)結束。值之間運用 “,”(逗號)分隔。
例如:
var jsonranklist=[{"xlid":"cxh","xldigitid":123456,"topscore":2000,"topplaytime":"2009-08-20"},{"xlid":"zd","xldigitid":123456,"topscore":1500,"topplaytime":"2009-11-20"}];
為了方便地處理JSON數據,JSON提供了json.js包,下載地址:http://www.json.org/json.js
在數據傳輸流程中,json是以文本,即字符串的形式傳遞的,而JS操作的是JSON對象,所以,JSON對象和JSON字符串之間的相互轉換是關鍵。例如:
JSON字符串:
var str1 = '{ "name": "cxh", "sex": "man" }';
JSON對象:
var str2 = { "name": "cxh", "sex": "man" };
一、JSON字符串轉換為JSON對象
要運用上面的str1,必須運用下面的要領先轉化為JSON對象:
//由JSON字符串轉換為JSON對象
var obj = eval('(' + str + ')');
或者
var obj = str.parseJSON(); //由JSON字符串轉換為JSON對象
或者
var obj = JSON.parse(str); //由JSON字符串轉換為JSON對象
然后,就可以這樣讀取:
Alert(obj.name);
Alert(obj.sex);
特別留心:如果obj本來就是一個JSON對象,那么運用 eval()函數轉換后(哪怕是多次轉換)還是JSON對象,但是運用 parseJSON()函數處理后會有疑問(拋出語法異常)。
二、可以運用 toJSONString()或者全局要領 JSON.stringify()將JSON對象轉化為JSON字符串。
例如:
var last=obj.toJSONString(); //將JSON對象轉化為JSON字符
或者
var last=JSON.stringify(obj); //將JSON對象轉化為JSON字符
alert(last);
留心:
上面的多個要領中,除了eval()函數是js自帶的之外,其他的多個要領都來自json.js包。新版本的 JSON 修改了 API,將 JSON.stringify() 和 JSON.parse() 兩個要領都注入到了 Javascript 的內建對象里面,前者變成了 Object.toJSONString(),而后者變成了 String.parseJSON()。如果提示找不到toJSONString()和parseJSON()要領,則說明您的json包版本太低。