现在json的第三方解析工作很多,如json-lib,gson,jackson,fastjson等,先学习下面两种。
JackSON使用: Jackson主要使用ObjectMapper对象来进行序列化以及反序列化操作。
使用Jackson可以毫无压力的将复杂对象进行完全序列化,也可以将各种类型的对象反序列化
以下代码均省略异常处理
普通对象
序列化Order order对象: ObjectMapper mapper = new ObjectMapper ();Writer strWriter = new StringWriter ();mapper.writeValue(strWriter, order); String json = strWriter.toString();
反序列化: Order order = mapper.readValue(json, Order.class);
链表、Map等
序列化List orderList: ObjectMapper mapper = new ObjectMapper ();Writer strWriter = new StringWriter ();mapper.writeValue(strWriter, orderList); String json = strWriter.toString();
反序列化: 需要用到TypeReference
List<Order> orderList = mapper.readValue(json, new TypeReference <List<Order>>() { } );
反序列化List<LinkedHashMap<String,String>> List orderList = mapper.readValue(json, List.class);
解析某个字段 JsonNode node = mapper.readTree(json);String name= node.get("name" );
Jackson的JSON操作方法 准备工作 首先去官网下载Jackson工具包,下载地址http://wiki.fasterxml.com/JacksonDownload。Jackson有1.x系列和2.x系列,截止目前2.x系列的最新版本是2.2.3,2.x系列有3个jar包需要下载:
jackson-core-2.2.3.jar(核心jar包,下载地址 )
jackson-annotations-2.2.3.jar(该包提供Json注解支持,下载地址 )
jackson-databind-2.2.3.jar(下载地址 )
import java.util.Date;public class User { private String name; private Integer age; private Date birthday; private String email; public String getName () { return name; } public void setName (String name) { this .name = name; } public Integer getAge () { return age; } public void setAge (Integer age) { this .age = age; } public Date getBirthday () { return birthday; } public void setBirthday (Date birthday) { this .birthday = birthday; } public String getEmail () { return email; } public void setEmail (String email) { this .email = email; } }
JAVA对象转JSON[JSON序列化] import java.io.IOException;import java.text.ParseException;import java.text.SimpleDateFormat;import com.fasterxml.jackson.databind.ObjectMapper;public class JacksonDemo { public static void main (String[] args) throws ParseException, IOException { User user = new User (); user.setName("小民" ); user.setEmail("xiaomin@sina.com" ); user.setAge(20 ); SimpleDateFormat dateformat = new SimpleDateFormat ("yyyy-MM-dd" ); user.setBirthday(dateformat.parse("1996-10-01" )); ObjectMapper mapper = new ObjectMapper (); String json = mapper.writeValueAsString(user); System.out.println(json); List<User> users = new ArrayList <User>(); users.add(user); String jsonlist = mapper.writeValueAsString(users); System.out.println(jsonlist); } }
JSON转Java类[JSON反序列化] import java.io.IOException;import java.text.ParseException;import com.fasterxml.jackson.databind.ObjectMapper;public class JacksonDemo { public static void main (String[] args) throws ParseException, IOException { String json = "{\"name\":\"小民\",\"age\":20,\"birthday\":844099200000,\"email\":\"xiaomin@sina.com\"}" ; ObjectMapper mapper = new ObjectMapper (); User user = mapper.readValue(json, User.class); System.out.println(user); } }
JSON注解 Jackson提供了一系列注解,方便对JSON序列化和反序列化进行控制,下面介绍一些常用的注解。
@JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。
@JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = “yyyy-MM-dd HH-mm-ss”)。
@JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty(“name”)。
import java.util.Date;import com.fasterxml.jackson.annotation.*;public class User { private String name; @JsonIgnore private Integer age; @JsonFormat(pattern = "yyyy年MM月dd日") private Date birthday; @JsonProperty("mail") private String email; public String getName () { return name; } public void setName (String name) { this .name = name; } public Integer getAge () { return age; } public void setAge (Integer age) { this .age = age; } public Date getBirthday () { return birthday; } public void setBirthday (Date birthday) { this .birthday = birthday; } public String getEmail () { return email; } public void setEmail (String email) { this .email = email; } }
import java.io.IOException;import java.text.ParseException;import java.text.SimpleDateFormat;import com.fasterxml.jackson.databind.ObjectMapper;public class JacksonDemo { public static void main (String[] args) throws ParseException, IOException { User user = new User (); user.setName("小民" ); user.setEmail("xiaomin@sina.com" ); user.setAge(20 ); SimpleDateFormat dateformat = new SimpleDateFormat ("yyyy-MM-dd" ); user.setBirthday(dateformat.parse("1996-10-01" )); ObjectMapper mapper = new ObjectMapper (); String json = mapper.writeValueAsString(user); System.out.println(json); } }
GSON的使用: Gson(又称Google Gson)是Google公司发布的一个开放源代码的Java库,主要用途为串行化Java对象为JSON字符串,或反串行化JSON字符串成Java对象。GSON核心jar包不到1M,非常精简,但提供的功能无疑是非常强大的,如果使用JDK自带的JSON解析API,使用起来相对比较繁琐一点,而且代码量较多。
GSON目前的发展状况 初始版本 2008年5月22日 最新版本(稳定版本) 2.2.4/2013年5月13日;2个月前 编程语言 Java 操作平台 各种平台 许可协议 Apache License 2.0 官方网站 http://code.google.com/p/google-gson/ 下载地址 http://code.google.com/p/google-gson/downloads/list GSON帮助文档 http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/index.html
使用GSON转换时报的一个异常。 Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176) at com.google.gson.Gson.fromJson(Gson.java:803) at com.google.gson.Gson.fromJson(Gson.java:768) at com.google.gson.Gson.fromJson(Gson.java:717) at com.google.gson.Gson.fromJson(Gson.java:689) at com.demoone.UseGson.testOneBeanFromJSON(UseGson.java:54) at com.demoone.UseGson.main(UseGson.java:89) Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 //注意这句话跟数组集合有关 at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:374) at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:165) ... 6 more
下面贴出,笔者的测试源码,注意上述异常,在代码的注释中已经指出问题原因
package com.demoone; import java.util.ArrayList; import java.util.List; import com.entity.Person; import com.google.gson.Gson; import com.google.gson.reflect.*; public class UseGson { static Gson g=new Gson (); public static void testToJSON () { List<Person> list=new ArrayList <>(); for (int i=0 ;i<2 ;i++){ Person p=new Person (i, "散仙" +i, "北京市" +i, "54152541@qq.com" , 500.0 ); list.add(p); } String json=g.toJson(list); System.out.println(json); } public static void testOneBeanFromJSON () { String jsonBean="[{\"id\":0,\"name\":\"散仙0\",\"address\":\"北京市0\",\"email\":\"54152541@qq.com\",\"money\":500.0}]" ; Person p=g.fromJson(jsonBean, Person.class); System.out.println(p); } public static void testListBeanFromJSON () { String jsonBeanList="[{\"id\":0,\"name\":\"散仙0\",\"address\":\"北京市0\",\"email\":\"54152541@qq.com\",\"money\":500.0},{\"id\":1,\"name\":\"散仙1\",\"address\":\"北京市1\",\"email\":\"54152541@qq.com\",\"money\":500.0}]" ; List<Person> lists=g.fromJson(jsonBeanList,new TypeToken <List<Person>>(){}.getType()); System.out.println("反序列之后" ); for (Person pp:lists){ System.out.println(pp); } } public static void main (String[] args) { testListBeanFromJSON(); testOneBeanFromJSON(); } }
运行结果:
testListBeanFromJSON() 方法: 反序列之后 编号:0 名字:散仙0 地址:北京市0 E-mail:54152541@qq.com 钱:500.0 编号:1 名字:散仙1 地址:北京市1 E-mail:54152541@qq.com 钱:500.0 testOneBeanFromJSON() 方法: 编号:0 名字:散仙0 地址:北京市0 E-mail:54152541@qq.com 钱:500.0
实体类Person:
package com.entity; public class Person { private int id; private String name; private String address; private String email; private double money; @Override public String toString () { return "编号:" +id+" 名字:" +name+" 地址:" +address+" E-mail:" +email+" 钱:" +money; } public Person () { } public Person (int id, String name, String address, String email, double money) { super (); this .id = id; this .name = name; this .address = address; this .email = email; this .money = money; } public int getId () { return id; } public void setId (int id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } public String getAddress () { return address; } public void setAddress (String address) { this .address = address; } public String getEmail () { return email; } public void setEmail (String email) { this .email = email; } public double getMoney () { return money; } public void setMoney (double money) { this .money = money; } }