`
jiangzhenghua
  • 浏览: 592340 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

js中的json对象(二)

    博客分类:
  • JSON
 
阅读更多

四、JSONAjax中的应用

    JSONJavaScript Object Notation)一种简单的数据格式,比xml更轻巧。 JSONJavaScript 原生格式,这意味着在 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());   

}   

 

2js对象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

      jsonjar

            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的数组Arrayjson对象

    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());

    //转换javaListjson对象

    JSONArray jsonList = JSONArray.fromObject(list);  

    System.out.println(jsonList);  

    //转换javaMapjson对象

    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写一个JSONajax例子

案例:   

在页面中写一个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包中JSONObjectfromObject方法把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对象-

                                 RequestString

 

 

。。。。

 

 


 

Java

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

Js

Json对象       <--Json文本

 

                                      ResponseString

 

 

 

 


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);   

}  

5JSON服务器端的数据格式转化的应用

JSON还提供了javajarhttp://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插件提供了一种名为jsonResultType,一旦为某个Action指定了一个类型为jsonResult,则该Result无需映射到任何视图资源。因为JSON插件会负责将Action里的状态信息序列化成JSON格式的数据,并将该数据返回给客户端页面的 JavaScript

 

  简单地说,JSON插件允许我们在JavaScript中异步调用Action,而且Action不再需要使用视图资源来显示该Action里的状态信息,而是由JSON插件负责将Action里的状态信息返回给调用页面——通过这种方式,就可以完成Ajax交互。

  Struts2提供了一种可插拔方式来管理插件,安装Struts2JSON插件与安装普通插件并没有太大的区别,一样只需要将Struts2插件的JAR文件复制到Web应用的WEB-INF/lib路径下即可。

安装JSON插件按如下步骤进行:

1)登陆http://code.google.com/p/jsonplugin/downloads/list 站点,下载Struts2JSON插件的最新版本,当前最新版本是0.7,我们可以下载该版本的JSON插件。

2)将下载到的jsonplugin-0.7.jar文件复制到Web应用的WEB-INF路径下,即可完成JSON插件的安装。

 

  实现Action逻辑

  假设deptnew.html输入页面中包含了四个表单域,这四个表单域对于四个请求参数,因此应该使用Action来的dept对象封装这四个请求参数。四个表单域的name分别为dept.deptiddept.deptnamedept.deptnumdept.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;

  

  

   //三个请求参数对应的settergetter方法

   @JSON(serialize=false)

   public String getField1(){

   return field1;

   }

   public void setField1(String field1)

{

     this.field1 = field1;

}

   //封装处理结果的属性的settergetter方法

   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注释还支持如下几个域:

NameAction属性被序列化成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配置结果类型为jsonResult。而这个Result无需配置任何视图资源,只需要把通过该结果把json文本响应到原页面。

 

配置该Actionstruts.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编码,这是因为AjaxPOST请求都是以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改为lazyfalse即可;

2、对于查询中如果用的是xxx.loadclassid)则改为xxx,get(classid)

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提供了OpenSessionInViewFilterOpenSessionInViewInterceptor。我们可以随意选择一个类来实现相同的功能。两种方法唯一的不同就在于interceptorSpring容器中运行并被配置在web应用的上下文中,而FilterSpring之前运行并被配置在web.xml中。不管用哪个,他们都在请求将当前会话与当前(数据库)线程绑定时打开Hibernate会话。一旦已绑定到线程,这个打开了的Hibernate会话可以在DAO实现类中透明地使用。这个会话会为延迟加载数据库中值对象的视图保持打开状态。一旦这个逻辑视图完成了,Hibernate会话会在FilterdoFilter方法或者InterceptorpostHandle方法中被关闭。用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>

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics