读书人

js中的json对象(2)

发布时间: 2012-09-07 10:38:15 作者: rapoo

js中的json对象(二)

四、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_r() {???

??? var str = '{ "name": "张三", "sex": "男" }';???

??? var obj = eval_r('(' + 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对象-

???????????????????????????????? Request(String)

?

?

。。。。

?

?


?

Java中

转换为Json对象<--Java对象

Js中

Json对象?????? <--Json文本

?

??????????????????????????????? ??????Response(String)

?

?

?

?


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>

读书人网 >JavaScript

热点推荐