赞
踩
Fastjson是一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。Fastjson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。
主要特点:
例如:
- import com.alibaba.fastjson.JSON;
-
- Group group = new Group();
- group.setId(0L);
- group.setName("admin");
-
- User guestUser = new User();
- guestUser.setId(2L);
- guestUser.setName("guest");
-
- User rootUser = new User();
- rootUser.setId(3L);
- rootUser.setName("root");
-
- group.getUsers().add(guestUser);
- group.getUsers().add(rootUser);
- String jsonString = JSON.toJSONString(group);
- System.out.println(jsonString);
JSON这个类是fastjson API的入口,主要的功能都通过这个类提供。
- package com.alibaba.fastjson;
-
- public abstract class JSON {
- // 将Java对象序列化为JSON字符串,支持各种各种Java基本类型和JavaBean
- public static String toJSONString(Object object, SerializerFeature... features);
-
- // 将Java对象序列化为JSON字符串,返回JSON字符串的utf-8 bytes
- public static byte[] toJSONBytes(Object object, SerializerFeature... features);
-
- // 将Java对象序列化为JSON字符串,写入到Writer中
- public static void writeJSONString(Writer writer,
- Object object,
- SerializerFeature... features);
-
- // 将Java对象序列化为JSON字符串,按UTF-8编码写入到OutputStream中
- public static final int writeJSONString(OutputStream os, //
- Object object, //
- SerializerFeature... features);
-
-
-
- }
- package com.alibaba.fastjson;
-
- public abstract class JSON {
- // 将JSON字符串反序列化为JavaBean
- public static <T> T parseObject(String jsonStr,
- Class<T> clazz,
- Feature... features);
-
- // 将JSON字符串反序列化为JavaBean
- public static <T> T parseObject(byte[] jsonBytes, // UTF-8格式的JSON字符串
- Class<T> clazz,
- Feature... features);
-
- // 将JSON字符串反序列化为泛型类型的JavaBean
- public static <T> T parseObject(String text,
- TypeReference<T> type,
- Feature... features);
-
- // 将JSON字符串反序列为JSONObject
- public static JSONObject parseObject(String text);
- }
接下来看:
parseTree
- import com.alibaba.fastjson.*;
-
- JSONObject jsonObj = JSON.parseObject(jsonStr);
parse pojo
- import com.alibaba.fastjson.JSON;
-
- Model model = JSON.parseObject(jsonStr, Model.class);
parse pojo generic
- import com.alibaba.fastjson.JSON;
-
- Type type = new TypeReference<List<Model>>() {}.getType();
- List<Model> list = JSON.parseObject(jsonStr, type);
convert pojo to json string
- import com.alibaba.fastjson.JSON;
-
- Model model = ...;
- String jsonStr = JSON.toJSONString(model);
convert pojo to json bytes
- import com.alibaba.fastjson.JSON;
-
- Model model = ...;
- byte[] jsonBytes = JSON.toJSONBytes(model);
注意:1、若属性是私有的,必须有set*方法。否则无法反序列化。
- package com.alibaba.fastjson.annotation;
-
- public @interface JSONField {
- // 配置序列化和反序列化的顺序,1.1.42版本之后才支持
- int ordinal() default 0;
-
- // 指定字段的名称
- String name() default "";
-
- // 指定字段的格式,对日期格式有用
- String format() default "";
-
- // 是否序列化
- boolean serialize() default true;
-
- // 是否反序列化
- boolean deserialize() default true;
- }
FieldInfo可以配置在getter/setter方法或者字段上。例如:
- public class A {
- private int id;
-
- @JSONField(name="ID")
- public int getId() {return id;}
- @JSONField(name="ID")
- public void setId(int value) {this.id = id;}
- }
- public class A {
- @JSONField(name="ID")
- private int id;
-
- public int getId() {return id;}
- public void setId(int value) {this.id = id;}
- }
- public class A {
- // 配置date序列化和反序列使用yyyyMMdd日期格式
- @JSONField(format="yyyyMMdd")
- public Date date;
- }
- public class A {
- @JSONField(serialize=false)
- public Date date;
- }
-
- public class A {
- @JSONField(deserialize=false)
- public Date date;
- }
- public static class VO {
- @JSONField(ordinal = 3)
- private int f0;
-
- @JSONField(ordinal = 2)
- private int f1;
-
- @JSONField(ordinal = 1)
- private int f2;
- }
- public static class Model {
- @JSONField(serializeUsing = ModelValueSerializer.class)
- public int value;
- }
-
- public static class ModelValueSerializer implements ObjectSerializer {
- @Override
- public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
- int features) throws IOException {
- Integer value = (Integer) object;
- String text = value + "元";
- serializer.write(text);
- }
- }
测试代码
- Model model = new Model();
- model.value = 100;
- String json = JSON.toJSONString(model);
- Assert.assertEquals("{\"value\":\"100元\"}", json);
看一个DEMO
- public static class Model {
- public int id;
-
- @JSONField(alternateNames = {"user", "person"})
- public String name;
- }
-
- String jsonVal0 = "{\"id\":5001,\"name\":\"Jobs\"}";
- String jsonVal1 = "{\"id\":5382,\"user\":\"Mary\"}";
- String jsonVal2 = "{\"id\":2341,\"person\":\"Bob\"}";
-
- Model obj0 = JSON.parseObject(jsonVal0, Model.class);
- assertEquals(5001, obj0.id);
- assertEquals("Jobs", obj0.name);
-
- Model obj1 = JSON.parseObject(jsonVal1, Model.class);
- assertEquals(5382, obj1.id);
- assertEquals("Mary", obj1.name);
-
- Model obj2 = JSON.parseObject(jsonVal2, Model.class);
- assertEquals(2341, obj2.id);
- assertEquals("Bob", obj2.name);
在fastjson-1.2.12版本中,JSONField支持一个新的配置项jsonDirect,它的用途是:当你有一个字段是字符串类型,里面是json格式数据,你希望直接输入,而不是经过转义之后再输出。
- import com.alibaba.fastjson.annotation.JSONField;
-
- public static class Model {
- public int id;
- @JSONField(jsonDirect=true)
- public String value;
- }
- Model model = new Model();
- model.id = 1001;
- model.value = "{}";
-
- String json = JSON.toJSONString(model);
- Assert.assertEquals("{\"id\":1001,\"value\":{}}", json);
fastjson 1.2.0之后的版本支持JSONPath。这是一个很强大的功能,可以在java框架中当作对象查询语言(OQL)来使用。
API:
- package com.alibaba.fastjson;
-
- public class JSONPath {
- // 求值,静态方法
- public static Object eval(Object rootObject, String path);
-
- // 计算Size,Map非空元素个数,对象非空元素个数,Collection的Size,数组的长度。其他无法求值返回-1
- public static int size(Object rootObject, String path);
-
- // 是否包含,path中是否存在对象
- public static boolean contains(Object rootObject, String path) { }
-
- // 是否包含,path中是否存在指定值,如果是集合或者数组,在集合中查找value是否存在
- public static boolean containsValue(Object rootObject, String path, Object value) { }
-
- // 修改制定路径的值,如果修改成功,返回true,否则返回false
- public static boolean set(Object rootObject, String path, Object value) {}
-
- // 在数组或者集合中添加元素
- public static boolean array_add(Object rootObject, String path, Object... values);
- }
建议缓存JSONPath对象,这样能够提高求值的性能
JSONPATH | 描述 |
$ | 根对象,例如$.name |
[num] | 数组访问,其中num是数字,可以是负数。例如$[0].leader.departments[-1].name |
[num0,num1,num2...] | 数组多个元素访问,其中num是数字,可以是负数,返回数组中的多个元素。例如$[0,3,-2,5] |
[start:end] | 数组范围访问,其中start和end是开始小表和结束下标,可以是负数,返回数组中的多个元素。例如$[0:5] |
[start:end :step] | 数组范围访问,其中start和end是开始小表和结束下标,可以是负数;step是步长,返回数组中的多个元素。例如$[0:5:2] |
[?(key)] | 对象属性非空过滤,例如$.departs[?(name)] |
[key > 123] | 数值类型对象属性比较过滤,例如$.departs[id >= 123],比较操作符支持=,!=,>,>=,<,<= |
[key = '123'] | 字符串类型对象属性比较过滤,例如$.departs[name = '123'],比较操作符支持=,!=,>,>=,<,<= |
[key like 'aa%'] | 字符串类型like过滤, 例如$.departs[name like 'sz*'],通配符只支持% 支持not like |
[key rlike 'regexpr'] | 字符串类型正则匹配过滤, 例如departs[name like 'aa(.)*'], 正则语法为jdk的正则语法,支持not rlike |
[key in ('v0', 'v1')] | IN过滤, 支持字符串和数值类型 例如: $.departs[name in ('wenshao','Yako')] $.departs[id not in (101,102)] |
[key between 234 and 456] | BETWEEN过滤, 支持数值类型,支持not between 例如: $.departs[id between 101 and 201] $.departs[id not between 101 and 201] |
length() 或者 size() | 数组长度。例如$.values.size() 支持类型java.util.Map和java.util.Collection和数组 |
. | 属性访问,例如$.name |
.. | deepScan属性访问,例如$..name |
* | 对象的所有属性,例如$.leader.* |
['key'] | 属性访问。例如$['name'] |
['key0','key1'] | 多个属性访问。例如$['id','name'] |
以下两种写法的语义是相同的:
- $.store.book[0].title
-
- $['store']['book'][0]['title']
JSONPath | 语义 |
$ | 根对象 |
$[-1] | 最后元素 |
$[:-2] | 第1个至倒数第2个 |
$[1:] | 第2个之后所有元素 |
$[1,2,3] | 集合中1,2,3个元素 |
- public void test_entity() throws Exception {
- Entity entity = new Entity(123, new Object());
-
- Assert.assertSame(entity.getValue(), JSONPath.eval(entity, "$.value"));
- Assert.assertTrue(JSONPath.contains(entity, "$.value"));
- Assert.assertTrue(JSONPath.containsValue(entity, "$.id", 123));
- Assert.assertTrue(JSONPath.containsValue(entity, "$.value", entity.getValue()));
- Assert.assertEquals(2, JSONPath.size(entity, "$"));
- Assert.assertEquals(0, JSONPath.size(new Object[], "$"));
- }
-
- public static class Entity {
- private Integer id;
- private String name;
- private Object value;
-
- public Entity() {}
- public Entity(Integer id, Object value) { this.id = id; this.value = value; }
- public Entity(Integer id, String name) { this.id = id; this.name = name; }
- public Entity(String name) { this.name = name; }
-
- public Integer getId() { return id; }
- public Object getValue() { return value; }
- public String getName() { return name; }
-
- public void setId(Integer id) { this.id = id; }
- public void setName(String name) { this.name = name; }
- public void setValue(Object value) { this.value = value; }
- }
读取集合多个元素的某个属性
- List<Entity> entities = new ArrayList<Entity>();
- entities.add(new Entity("wenshao"));
- entities.add(new Entity("ljw2083"));
-
- List<String> names = (List<String>)JSONPath.eval(entities, "$.name"); // 返回enties的所有名称
- Assert.assertSame(entities.get(0).getName(), names.get(0));
- Assert.assertSame(entities.get(1).getName(), names.get(1));
返回集合中多个元素
- List<Entity> entities = new ArrayList<Entity>();
- entities.add(new Entity("wenshao"));
- entities.add(new Entity("ljw2083"));
- entities.add(new Entity("Yako"));
-
- List<Entity> result = (List<Entity>)JSONPath.eval(entities, "[1,2]"); // 返回下标为1和2的元素
- Assert.assertEquals(2, result.size());
- Assert.assertSame(entities.get(1), result.get(0));
- Assert.assertSame(entities.get(2), result.get(1));
按范围返回集合的子集
- List<Entity> entities = new ArrayList<Entity>();
- entities.add(new Entity("wenshao"));
- entities.add(new Entity("ljw2083"));
- entities.add(new Entity("Yako"));
-
- List<Entity> result = (List<Entity>)JSONPath.eval(entities, "[0:2]"); // 返回下标从0到2的元素
- Assert.assertEquals(3, result.size());
- Assert.assertSame(entities.get(0), result.get(0));
- Assert.assertSame(entities.get(1), result.get(1));
- Assert.assertSame(entities.get(2), result.get(1));
通过条件过滤,返回集合的子集
- List<Entity> entities = new ArrayList<Entity>();
- entities.add(new Entity(1001, "ljw2083"));
- entities.add(new Entity(1002, "wenshao"));
- entities.add(new Entity(1003, "yakolee"));
- entities.add(new Entity(1004, null));
-
- List<Object> result = (List<Object>) JSONPath.eval(entities, "[id in (1001)]");
- Assert.assertEquals(1, result.size());
- Assert.assertSame(entities.get(0), result.get(0));
根据属性值过滤条件判断是否返回对象,修改对象,数组属性添加元素
- Entity entity = new Entity(1001, "ljw2083");
- Assert.assertSame(entity , JSONPath.eval(entity, "[id = 1001]"));
- Assert.assertNull(JSONPath.eval(entity, "[id = 1002]"));
-
- JSONPath.set(entity, "id", 123456); //将id字段修改为123456
- Assert.assertEquals(123456, entity.getId().intValue());
-
- JSONPath.set(entity, "value", new int[0]); //将value字段赋值为长度为0的数组
- JSONPath.arrayAdd(entity, "value", 1, 2, 3); //将value字段的数组添加元素1,2,3
接下来看:
- Map root = Collections.singletonMap("company", //
- Collections.singletonMap("departs", //
- Arrays.asList( //
- Collections.singletonMap("id",
- 1001), //
- Collections.singletonMap("id",
- 1002), //
- Collections.singletonMap("id", 1003) //
- ) //
- ));
-
- List<Object> ids = (List<Object>) JSONPath.eval(root, "$..id");
- assertEquals(3, ids.size());
- assertEquals(1001, ids.get(0));
- assertEquals(1002, ids.get(1));
- assertEquals(1003, ids.get(2));
以上就暂时介绍这么多了。下次有时间在整理吧。
有问题可以在下面评论,技术问题可以私聊我。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。