JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式
Jackson所依赖的jar包较少,简单易用并且性能也要相对高些。
Jackson社区相对比较活跃,更新速度快。
综上三种Json技术的比较,在项目选型的时候可以使用Google的Gson和阿里巴巴的FastJson两种并行使用,
如果只是功能要求,没有性能要求,可以使用google的Gson,
如果有性能上面的要求可以使用Gson将bean转换json确保数据的正确,使用FastJson将Json转换Bean
一个JSON库涉及的最基本功能就是序列化和反序列化。Fastjson支持java bean的直接序列化。提供了com.alibaba.fastjson.JSON这个类进行序列化和反序列化。
JSONObject本质是实现了Map接口,因此可以直接向上转型给Map,JSONObject的数据是用 { } 来表示的
//示例json:{ "id" : "123", "courseID" : "huangt-test", "title" : "提交作业" }
public class JSONObject extends JSON implements Map<String, Object>
JSONArray 中是由JSONObject构成的数组,可以将
//示例json [{ "id" : "123", "courseID" : "huangt-test", "title" : "提交作业" } , { "content" : null, "beginTime" : 1398873600000 "endTime" } ] ;
public class JSONArray extends JSON implements List<Object>
//举例代码
String json = "{\"name\":\"张三\",\"age\":20,\"some\":[{\"name\":\"张一\",\"age\":\"30\"},{\"name\":\"张二\",\"age\":\"10\"}]}";
//json字符串转换成jsonObject对象
JSONObject jso = JSON.parseObject(json);
//jsonobject对象取得some对应的jsonarray数组
JSONArray someList = jso.getJSONArray("some");
//jsonarray对象通过getjsonobjext(index)方法取得数组里面的jsonobject对象
JSONObject ao = someList.getJSONObject(0);
String str = ao.getString("name");
System.out.println(str);
//将JavaBean序列化为JSON文本(常用)
public static final String toJSONString(Object object);
//把JSON文本parse为JavaBean(常用)
public static final T parseObject(String text, Class clazz);
// 把JSON文本parse成JSONObject
public static final JSONObject parseObject(String text);
// 把JSON文本parse成JSONArray
public static final JSONArray parseArray(String text);
//把JSON文本parse成JavaBean集合
public static final List parseArray(String text, Class clazz);
// 将JavaBean序列化为带格式的JSON文本
public static final String toJSONString(Object object, boolean prettyFormat);
// 把JSON文本parse为JSONObject或者JSONArray
public static final Objectparse(String text);
//将JavaBean转换为JSONObject或者JSONArray。
public static final Object toJSON(Object javaObject);
int o =10;
//UseSingleQuotes 单引号
String json = JSON.toJSONString(o,SerializerFeature.UseSingleQuotes);
int k= JSON.parseObject(json,Integer.class);
System.out.println("json:"+json);
System.out.println("object:"+k);
public class User{
public String username="";
public int id=0;
public ArrayList link=null;
public Map result=null;
}
class Link {
public String name = "";
public String phone = "";
}
//序列化和反序列化方法
//将Bean转换成json字符串
String str=JSON.toJSONString(user);
//将json字符串转换为Bean
User user=JSON.parseObject(str,User.class);
使用TypeReference将json串转成定义好的泛型对象
public class Result {
//some thing...
}
Result obj = (Result) JSON.parseObject(js, new TypeReference>(){});
可以把@JSONField配置在字段或者getter/setter方法上
// 配置在字段上
public class Vo {
@JSONField(name="ID")
private Integer id;
}
// SerializeResult:{"ID":0}
// 配置在字段上
public class Vo {
private Integer id;
@JSONField(name="ID")
public Integer getId() { return id;}
//这里不一样
@JSONField(name="IDs")
public void setId(Integer value) {this.id = value;}
//
}
// SerializeResult:{"IDs":0}
方法 | 描述 |
---|---|
ordinal | 指定字段的顺序 |
name | 字段key值 |
format | 配置日期格式化 |
serialize | 指定字段是否序列化 |
deserialize | 指定字段不序列化 |
serialzeFeatures | 指定规则 |
@JSONType与@JSONField区别在于,@JSONType是作用在类上的。
//配置序列化的时候,不序列化id sex
@JSONType(ignores ={"id", "sex"})
// 配置序列化的时候,序列化name 和sex
@JSONType(includes={"name","sex"})
通过SerializeFilter可以使用扩展编程的方式实现定制序列化。fastjson提供了多种SerializeFilter:
以上的SerializeFilter在JSON.toJSONString中可以使用。
可以通过扩展实现根据object或者属性名称或者属性值进行判断是否需要序列化。例如:
PropertyFilter filter = new PropertyFilter() {
public boolean apply(Object source, String name Object value) {
if ("id".equals(name)) {
int id = ((Integer) value).intValue();
return id >= 100;
}
return false;
}
};
JSON.toJSONString(obj, filter); // 序列化的时候传filter
ParseProcess是编程扩展定制反序列化的接口。fastjson支持如下ParseProcess:
public static class VO {
private int id;
private Map attributes = new HashMap();
public int getId() { return id; }
public void setId(int id) { this.id = id;}
public Map getAttributes() { return attributes;}
}
ExtraProcessor processor = new ExtraProcessor() {
public void processExtra(Object object, String key, Object value) {
VO vo = (VO) object;
vo.getAttributes().put(key, value);
}
};
VO vo = JSON.parseObject("{\"id\":123,\"name\":\"abc\"}", VO.class, processor);
Assert.assertEquals(123, vo.getId());
Assert.assertEquals("abc", vo.getAttributes().get("name"));
public static class VO {
private int id;
private Map attributes = new HashMap();
public int getId() { return id; }
public void setId(int id) { this.id = id;}
public Map getAttributes() { return attributes;}
}
class MyExtraProcessor implements ExtraProcessor, ExtraTypeProvider {
public void processExtra(Object object, String key, Object value) {
VO vo = (VO) object;
vo.getAttributes().put(key, value);
}
public Type getExtraType(Object object, String key) {
if ("value".equals(key)) {
return int.class;
}
return null;
}
};
ExtraProcessor processor = new MyExtraProcessor();
VO vo = JSON.parseObject("{\"id\":123,\"value\":\"123456\"}", VO.class, processor);
Assert.assertEquals(123, vo.getId());
Assert.assertEquals(123456, vo.getAttributes().get("value")); // value本应该是字符串类型的,通过getExtraType的处理变成Integer类型了。
先调用startArray函数,然后再遍历对象,最后调用endArray
//序列化
JSONWriter writer = new JSONWriter(new FileWriter("/tmp/hello.json"));
writer.startArray();
for (int i = 0; i < 1000 * 1000; ++i) {
writer.writeValue(new Model());
}
writer.endArray();
writer.close();
//反序列化
JSONReader reader = new JSONReader(new FileReader("/tmp/hello.json"));
reader.startArray();
while (reader.hasNext()) {
VO vo = reader.readObject(VO.class);
System.out.println(vo);
}
reader.endArray();
reader.close();
//序列化
JSONWriter writer = new JSONWriter(new FileWriter("/tmp/hello.json"));
writer.startObject();
for (int i = 0; i < 1000 * 1000; ++i) {
writer.writeKey("x" + i);
writer.writeValue(new VO());
}
writer.endObject();
writer.close();
//反序列化
JSONReader reader = new JSONReader(new FileReader("/tmp/huge.json"));
reader.startObject();
while(reader.hasNext()) {
String key = reader.readString();
VO vo = reader.readObject(VO.class);
//处理..
}
reader.endObject();
reader.close();
fastjson处理日期的API很简单,例如:
JSON.toJSONStringWithDateFormat(date, "yyyy-MM-dd HH:mm:ss.SSS")
使用ISO-8601日期格式
JSON.toJSONString(obj, SerializerFeature.UseISO8601DateFormat);
全局修改日期格式
JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd";
JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat);
反序列化能够自动识别如下日期格式:
使用SerializerFeature来输出空值
SerializerFeature | 描述 |
---|---|
WriteNullListAsEmpty | 将Collection类型字段的字段空值输出为[] |
WriteNullStringAsEmpty | 将字符串类型字段的空值输出为空字符串 “” |
WriteNullNumberAsZero | 将数值类型字段的空值输出为0 |
WriteNullBooleanAsFalse | 将Boolean类型字段的空值输出为false |
//示例代码
String text = JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty);