JSON、JAVA互转方法

来源:互联网 发布:同花顺看盘软件 编辑:程序博客网 时间:2024/06/10 17:18

JSON --- JAVA 使用方法

使用JSON的方法

 

JSON  JavaScript Object Natation,它是一种轻量级的数据交换格式,非常适合于服务器与 JavaScript 的交互。本文将快速讲解 JSON 格式,并通过代码示例演示如何分别在客户端和服务器端进行 JSON 格式数据的处理。

 

Json必需的包

commons-httpclient-3.1.jar
commons-lang-2.4.jar
commons-logging-1.1.1.jar
json-lib-2.2.3-jdk13.jar
ezmorph-1.0.6.jar
commons-collections-3.2.1.jar

以上包可以从

http://commons.apache.org/index.html

http://json-lib.sourceforge.net/

http://ezmorph.sourceforge.net/

http://morph.sourceforge.net/

http://www.docjar.com/

中下载到。

出现java.lang.NoClassDefFoundError: net/sf/ezmorph/Morpher错误是因为没有导入ezmorph.jar文件或版本不对。

出现java.lang.NoClassDefFoundError: org/apache/commons/collections/map/ListOrderedMap错误是因为没有导入commons-collections.jar文件或版本不对。

Java代码转换成json代码

1.       List集合转换成json代码

List list = new ArrayList();

list.add( "first" );

list.add( "second" );

JSONArray jsonArray2 = JSONArray.fromObject( list );

2.       Map集合转换成json代码

Map map = new HashMap();

map.put("name", "json");

map.put("bool", Boolean.TRUE);

map.put("int", new Integer(1));

map.put("arr", new String[] { "a", "b" });

map.put("func", "function(i){ return this.arr[i]; }");

JSONObject json = JSONObject.fromObject(map);

3.       Bean转换成json代码

JSONObject jsonObject = JSONObject.fromObject(new JsonBean());

4.       数组转换成json代码

boolean[] boolArray = new boolean[] { true, false, true };

JSONArray jsonArray1 = JSONArray.fromObject(boolArray);

 

5. 一般数据转换成json代码

JSONArray jsonArray3 = JSONArray.fromObject("['json','is','easy']" );

6.       beans转换成json代码

List list = new ArrayList();

JsonBean2 jb1 = new JsonBean2();

jb1.setCol(1);

jb1.setRow(1);

jb1.setValue("xx");

JsonBean2 jb2 = new JsonBean2();

jb2.setCol(2);

jb2.setRow(2);

jb2.setValue("");

list.add(jb1);

list.add(jb2);

JSONArray ja = JSONArray.fromObject(list);

 

 

看了JSON的处理,对应存在特殊字符比如""的,怎么处理的?


用 \ 转义 

关于 JSON 的Java库, Nutz 的 Json 解析器就非常好: 

Java转换成Json: 

Java代码 

1. Map<String,Object> map = new HashMap<String, Object>();   

2. map.put("name", "Peter");   

3. map.put("age", 21);   

4. map.put("friends", null);   

5. String result = Json.toJson(map);  

Map<String,Object> map = new HashMap<String, Object>();

map.put("name", "Peter");

map.put("age", 21);

map.put("friends", null);

String result = Json.toJson(map);


这个时候会输出成: 

Json代码 

1. {   

2.   age :21,   

3.   name :"Peter"  

4. }  

{

  age :21,

  name :"Peter"

}


会自动忽略掉值为空的字段. 

Json转换成Java: 

Java代码 

1. String json = "{age :21,name :\"Peter\"}";   

2. map = Json.fromJson(HashMap.class, Lang.inr(json));  

String json = "{age :21,name :\"Peter\"}";

map = Json.fromJson(HashMap.class, Lang.inr(json));



可以支持行注释,块注释, Json.fromJson(Class<T> type, Reader) 可以直接生成一个 Java 对象 
详细的可以参见它的一个简单的手册: 

http://code.google.com/p/nutz/downloads/detail?name=Nutz_Json_Book.pdf

 

 

 

我也是在用JSON,但不是像这样的动态生成js脚本,而是为了处理大批表格数据的读取问题,用struts(1.2)的action来生成json字符串,再用response.getWriter().write()输出到页面,ExtJS自然就是用Ext.data.JsonStore来读取了。这种方式的效率比较高,也达到了代码分离的目的,逻辑层和数据访问层根本无需暴露在web上,页面虽然是jsp,也无需使用<%%>或者struts标签。欢迎交流~ 

我先贴部分代码上来和大家交流一下,目前处于开发初期阶段,稍后我才做一个sample放上来。 

Java代码 

1. /**  

2.  * 向浏览器输出JSON字符串  

3.  * @param response HttpServletResponse对象  

4.  * @param obj 任意对象,可以是List,也可以是单个对象  

5.  */  

6. public void writeJsonString(HttpServletResponse response, Object obj) throws IOException {   

7.     if( obj == null ) {   

8.         this.exception = "obj参数为空";   

9.         logger.error(this.exception);   

10.         throw new NullPointerException(this.exception);   

11.     }   

12.        

13.     JSONArray array = JSONArray.fromObject(obj);   

14.        

15.     try {   

16.         String json = array.toString();   

17.         if( json.startsWith("[") ) {   

18.             json = json.substring(1);   

19.         }   

20.         if( json.endsWith("]") ) {   

21.             json = json.substring(0, json.length()-1);   

22.         }   

23.         response.setCharacterEncoding("utf-8");   

24.         response.getWriter().write(json);   

25.     } catch (IOException e) {   

26.         this.exception = "向浏览器输出JSON字符串时发生错误";   

27.         logger.error(this.exception);   

28.         logger.error(e);   

29.         throw new IOException(this.exception);   

30.     }   

31. }  

/**

 * 向浏览器输出JSON字符串

 * @param response HttpServletResponse对象

 * @param obj 任意对象,可以是List,也可以是单个对象

 */

public void writeJsonString(HttpServletResponse response, Object obj) throws IOException {

if( obj == null ) {

this.exception = "obj参数为空";

logger.error(this.exception);

throw new NullPointerException(this.exception);

}

JSONArray array = JSONArray.fromObject(obj);

try {

String json = array.toString();

if( json.startsWith("[") ) {

json = json.substring(1);

}

if( json.endsWith("]") ) {

json = json.substring(0, json.length()-1);

}

response.setCharacterEncoding("utf-8");

response.getWriter().write(json);

} catch (IOException e) {

this.exception = "向浏览器输出JSON字符串时发生错误";

logger.error(this.exception);

logger.error(e);

throw new IOException(this.exception);

}

}



这里是js部分 

Java代码 

1. var store = new Ext.data.JsonStore({   

2.     url: '../demo.do', //请大家根据实际情况修改action路径   

3.     root: 'data', //传回来的JSON字符串是HashMap生成的,data对应具体的数据集,一般是List对象   

4.     totalProperty: 'totalCount', //总记录数,整型   

5.     id: 'id',   

6.     fields: ['title', 'state', {name:'createDate', type: 'date'}, 'author', {name:'id', type:'int'}]   

7. });   

8. store.setDefaultSort('id', 'asc');   

9. store.load({params:{start:0, limit:25}}); //传两个URL参数做分页处理  

var store = new Ext.data.JsonStore({

url: '../demo.do', //请大家根据实际情况修改action路径

root: 'data', //传回来的JSON字符串是HashMap生成的,data对应具体的数据集,一般是List对象

totalProperty: 'totalCount', //总记录数,整型

id: 'id',

fields: ['title', 'state', {name:'createDate', type: 'date'}, 'author', {name:'id', type:'int'}]

});

store.setDefaultSort('id', 'asc');

store.load({params:{start:0, limit:25}}); //传两个URL参数做分页处理



还需要说明的是:需要json-lib-2.1-jdk15.jar, ezmorph-1.0.3.jar,到附件中取。

 

 

在学习JSON之前,当我在写大量JSP页面的时候,产生动态数据一般采用两种途径: 
1.直接在页面中写java代码 
2 采用各种标签代替 
   这两种用法的支持者都很多,但是我发现就算是采用标签也好,对于页面的重用还是无能为力,比如有几个页面都需要用到一个item数据,一个是管理用户页面,一个是订单页面。我们既要在管理用户的servlet写上setAttribute('item',item),也要在管理订单的servlet写上setAttribute('item',item);然后在页面上通过getAttribute()获得数据: 

Java代码 

1. <%for(int i=0;i<item.length;++i){%>   

2.     html tag ...   

3. <%}%>  

  <%for(int i=0;i<item.length;++i){%>

      html tag ...

  <%}%>


或者采用标签的形式: 

Java代码 

1. <ww:iterator value="item">   

2.     html tag...   

3. <ww:iterator>  

  <ww:iterator value="item">

      html tag...

  <ww:iterator>


   很多时候我们会采用 <jsp:inclue page="common.jsp"/>来重用这样的页面,但这里有个问题,如果多个的页面样式不一样呢?如果数据不是很多呢,这样会产生很多页面碎片,实践已经证明,重用页面并不是一个好办法. 

   有时候我想,如果我能单独用一个action来提供输出数据,每个需要这些数据的页面页面都去获取这些数据,关于这些数据在页面如何渲染是页面的问题,这个action只提供数据,这样我们重用数据不是比重用页面好很多么? 

   但是之前的技术并不能支撑这样的实现,一个页面如何自己主动去访问它需要的数据呢? 

   答案是当然是通过AJAX技术.但今天我介绍的是另外一种技术JSON. 

   先简单的介绍一下JSON(虽然很多人已经知道),JSON JavaScirp Object Notion 可以看成一段javascript对象树,比如 user.id 表示的是user对象的id,如果对webwork或则是srtus2.0熟悉的朋友应该对此并不陌生,对象树可以嵌套对象,比如user.cat.age 表示user对象的成员cat的年龄。除了对象还可以嵌套数组方法user.cat[0].sayHello(); 
  我们这样声明一个JSON: 

Java代码 

1. var user = { id:’1’, name:’sanyun’};       

2. alert(user.id)  //输出1   

3. user = { id:’1’, cat:{age:2,color:’white’ }};   

4. alert(user.cat.age) //输出2  

var user = { id:’1’, name:’sanyun’};

alert(user.id) //输出1

user = { id:’1’, cat:{age:2,color:’white’ }};

alert(user.cat.age) //输出2



  但是JSON本身是不能和后端通信的,不过我们可以通过 

Java代码 

1. <script type="text/javascript" src="后端资源"> </script>  

<script type="text/javascript" src="后端资源"> </script>


来和服务器后端通信. 
我们可以把它封装成一个方法: 

Java代码 

1. function CallBack(model) {   

2.     this.model = model;   

3. }   

4. CallBack.init = function (url) {   

5.     var headElement = document.getElementsByTagName("head").item(0);   

6.     var scriptTag = document.createElement("script");   

7.     scriptTag.setAttribute("type", "text/javascript");   

8.     scriptTag.setAttribute("src", url);   

9.     headElement.appendChild(scriptTag);   

10. };  

function CallBack(model) {

    this.model = model;

}

CallBack.init = function (url) {

    var headElement = document.getElementsByTagName("head").item(0);

    var scriptTag = document.createElement("script");

    scriptTag.setAttribute("type", "text/javascript");

    scriptTag.setAttribute("src", url);

    headElement.appendChild(scriptTag);

};


   不过需要注意的是采用这种方式后台MIME必须要设置为 html/Javascritp,当然你也可以轻松把这种方式替换成Ajax. 
解析 
  通信之后我们需要做的是解析数据,一般来说,我们可以通过for in 简单的遍列JSON 

Java代码 

1.    //model表示后端产生的JSON   

2. CallBack.update(model){   

3.   for(i in model){   

4.      var node =document.getElementByID(i);   

5.      if(node){   

6.        node.value = model[i];   

7.      }   

8.   }   

9. }  

   //model表示后端产生的JSON

CallBack.update(model){

  for(i in model){

     var node =document.getElementByID(i);

     if(node){

       node.value = model[i];

     }

  }

}


后台 

Java代码 

1. public class ShowType extends HttpServlet {   

2.        

3.    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {   

4.        

5.    response.addHeader("Cache-Control", "no-cache");  //(1)   

6.    response.setContentType("HTML/JavaScript;charset=GBK");//(2)   

7.    PrintWriter out = response.getWriter();   

8.    String json = ” {name:'jiangyunpeng', status:'1',sex:'female'}  ”//(3)   

9.    out.print("CallBack.update("+json+")"); //(4)   

10.   }        

11. }  

public class ShowType extends HttpServlet {

    

   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

   response.addHeader("Cache-Control", "no-cache");  //(1)

   response.setContentType("HTML/JavaScript;charset=GBK");//(2)

   PrintWriter out = response.getWriter();

   String json = ” {name:'jiangyunpeng', status:'1',sex:'female'}  ”//(3)

   out.print("CallBack.update("+json+")"); //(4)

  }  

}


(1)首先需要设置缓存为空 
(2)然后MIME必须要设置为 html/Javascritp 
(3)产生一段JSON,这里我们是手动产生的,可以采用JSON开源框架 
(4)调用我们前面页面定义的JS函数 
通过这样处理了之后我们的页面再也没有任何JAVA代码或者自定义标签了,他完全是一个HTML页面(当然这里为了演示,把解析JSON过程过于简单化了),他具有这些好处: 
1.它是一个HTML,响应速度比JSP快 
2.对于一些表单元素,比如checkbox,select,如果采用java代码会很繁琐, 

Java代码 

1.  function initCheckbox(){   

2.    if('<%=status%>'==1){  //这里有JAVA代码   

3.       document.getElementById('checkbox').checked = true;   

4.    }else{   

5.       document.getElementById('checkbox').checked = fasle;   

6.     }   

7. }  

   function initCheckbox(){

     if('<%=status%>'==1){  //这里有JAVA代码

        document.getElementById('checkbox').checked = true;

     }else{

        document.getElementById('checkbox').checked = fasle;

      }

  }


但是如果采用JSON的话 

Java代码 

1. function initCheckbox(){   

2.    if(status==1){      //这里只有JSON   

3.       document.getElementById('checkbox').checked = true;   

4.    }else{   

5.       document.getElementById('checkbox').checked = fasle;   

6.     }   

7. }  

  function initCheckbox(){

     if(status==1){      //这里只有JSON

        document.getElementById('checkbox').checked = true;

     }else{

        document.getElementById('checkbox').checked = fasle;

      }

  }


  我们可以把这段代码放在解析方法里面,判断查询的对象如果是checkbox,就像上面这样处理,这样我们就可以更本不用关心它是否是checkbox 
3.重用了数据.多个页面可以通过JSON访问相同的数据,这里没有setAttribute(),也不用考虑生命周期。 
4.降低了服务器端的负载。因为我们把解析的数据任务放在客户端里面进行,服务器只需要产生一些JSON字符串。 
5.分离了JAVA代码和JS,诸如验证,判断,很多时候在javascript里面嵌套java,可读性很差。 

小结:我觉得采用JSON是个不错的选择,大家可以试试。 原来大伙早知道啦! 
参考:http://www.javaworld.com/javaworld/jw-11-2006/jw-1115-json.html