FastJson的简单使用
一、简介
FastJson是一个Java类库,可以将Java对象转为对应的JSON形式,也可以将JSON字符串转换成等效的Java对象。
二、下载与安装
- 下载链接
http://repo1.maven.org/maven2/com/alibaba/fastjson/
- Maven依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
三、常用API
1、parse(text)
将JSON字符串解析为JSONObject或JSONArray
public static Object parse(String text)
- 样例
String text = "{\"name\": \"albert\", \"age\": 28}";
Object obj = JSON.parse(text);
System.out.println(obj.getClass().getTypeName());//com.alibaba.fastjson.JSONObject
2、toJSON(javaObject)
将Java对象转换为JSONObject或JSONArray
public static Object toJSON(Object javaObject)
- 样例
User user = new User("albert", 28);
Object userJson = JSON.toJSON(user);
System.out.println(userJson.getClass().getTypeName());//com.alibaba.fastjson.JSONObject
3、toJSONString(object)
将Java对象转为JSON字符串
public static String toJSONString(Object object)
- 样例
User user = new User("albert", 28);
Object userJson = JSON.toJSON(user);
System.err.println(JSON.toJSONString(user));
- 程序输出
{"age":28,"name":"albert"}
4、toJSONString(object, prettyFormat)
将Java对象转为带格式的JSON字符串
public static String toJSONString(Object object, boolean prettyFormat)
- 样例
User user = new User("albert", 28);
Object userJson = JSON.toJSON(user);
System.out.println(JSON.toJSONString(user, true));
- 程序输出
{
"age":28,
"name":"albert"
}
5、parseObject(text)
将JSON字符串转为JSONObject对象
public static JSONObject parseObject(String text)
- 样例
String text = "{\"name\": \"albert\", \"age\": 28}";
JSONObject jsonObj = JSON.parseObject(text);
6、parseObject(text, clazz)
将JSON字符串转为指定类型的Java对象
public static <T> T parseObject(String text, Class<T> clazz)
- 样例
String text = "{\"name\": \"albert\", \"age\": 28}";
User user = JSON.parseObject(text, User.class);
7、parseArray(text)
将JSON字符串转为JSONArray对象
public static JSONArray parseArray(String text)
- 样例
String arrText = "[{\"name\":\"John\",\"age\":30},{\"name\":\"Beatrice\",\"age\":26}]";
JSONArray jsonArr = JSON.parseArray(arrText);
8、parseArray(text, clazz)
将JSON字符串转为指定类型的Java对象集合
public static <T> List<T> parseArray(String text, Class<T> clazz)
- 样例
String arrText = "[{\"name\":\"John\",\"age\":30},{\"name\":\"Beatrice\",\"age\":26}]";
List<User> users = JSON.parseArray(arrText, User.class);
四、自定义序列化/反序列化
1、使用@JSONField
注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface JSONField
@JSONField(serialize=false)
指定是否序列化某个属性,默认值为true
@JSONField(serialize = false)
private int id;
Item item = new Item();
item.setId(555);
System.out.println(JSON.toJSONString(item));//{}
@JSONField(deserialize = false)
指定是否反序列化某个属性,默认值为true
@JSONField(deserialize = false)
private String number;
String text = "{\"number\":\"json\"}";
Item item = JSON.parseObject(text, Item.class);
System.out.println(item.getNumber());//null
@JSONField(name="xxx")
指定JSON转换时(序列化和反序列化时)的字段名
@JSONField(name="key")
private int id;
String text = "{\"key\":12345}";
Item item = JSON.parseObject(text, Item.class);
System.out.println(item.getId());//12345
item = new Item();
item.setId(555);
System.out.println(JSON.toJSONString(item));//{"key":555}
@JSONField(format="yyyy-MM-dd")
指定序列化和反序列化日期字段时的格式
@JSONField(format="yyyy-MM-dd")
private Date date;
String text = "{\"date\":\"2018-11-11\"}";
Item item = JSON.parseObject(text, Item.class);
System.out.println(item.getDate());//Sun Nov 11 00:00:00 CST 2018
item = new Item();
item.setDate(new Date(1541905871672L));
System.out.println(JSON.toJSONString(item));//{"date":"2018-11-11","key":0} (由于Item类中id为int,所以是0;如果是Integer,则为null时不会转到JSON中)
@JSONField(ordinal = 0)
指定Java类字段转为JSON字符串中的顺序,默认按字段的字母顺序排序。(值为非负数)
@JSONField(ordinal = 1)
private int id;
@JSONField(ordinal = 0)
private String number;
@JSONField(ordinal = 2, format="yyyy-MM-dd")
private Date date;
Item item = new Item(555, "json", new Date(1541905871672L));
System.out.println(JSON.toJSONString(item));
//没有指定顺序时
{"date":"2018-11-11","id":555,"number":"json"}
//设置了顺序时
{"number":"json","id":555,"date":"2018-11-11"}
@JSONField(alternateNames = {"xxx", "yyy"})
反序列化时支持使用多个不同的名称
@JSONField(alternateNames={"key", "name"})
private String number;
Item item = JSON.parseObject("{\"key\":\"number\"}", Item.class);
System.out.println(item.getNumber());//number
item = JSON.parseObject("{\"name\":\"number\"}", Item.class);
System.out.println(item.getNumber());//number
@JSONField(jsonDirect=true)
如果Java对象的一个属性值是JSON,该配置指定在序列化时是否直接输出此JSON值,默认值为false,即会将此JSON值转义
@JSONField(jsonDirect=true)
private String value;
Item item = new Item();
item.setValue("{\"name\":\"albert\"}");
//jsonDirect=false时输出:{"value":"{\"name\":\"albert\"}"}
System.out.println(JSON.toJSONString(item));
//jsonDirect=true时输出:{"value":{"name":"albert"}}
System.out.println(JSON.toJSONString(item));
@JSONField(serializeUsing = Xxx.class, deserializeUsing = Xxx.class)
自定义某个属性序列化或反序列化时的处理类
@JSONField(serializeUsing = ValueSerializer.class, deserializeUsing = ValueSerializer.class)
private String value;
public class ValueSerializer implements ObjectSerializer, ObjectDeserializer{
@Override
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
serializer.write(String.format("(●%s●)", object));
}
@Override
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
String input = parser.getInput();
input = input.replaceFirst("\\(●(.+?)●\\)", "$1");
return (T) input;
}
@Override
public int getFastMatchToken() {
return 0;
}
}
Item item = new Item();
item.setValue("ˇ∀ˇ");
System.out.println(JSON.toJSONString(item));//{"value":"(●ˇ∀ˇ●)"}
item = JSON.parseObject("{\"value\":\"(●'◡'●)\"}", Item.class);
System.out.println(item.getValue());//{"value":"'◡'"}
2、使用SerializeFilter
可以通过实现不同的SerializeFilter来自定义序列化
- PropertyPreFilter
自定义属性是否序列化
Item item = new Item();
item.setId(100);
item.setNumber("no.1");
SerializeFilter filter = new PropertyPreFilter() {
@Override
public boolean apply(JSONSerializer serializer, Object object, String name) {
if("id".equals(name)){
//不序列化id属性
return false;
}
return true;
}
};
System.out.println(JSON.toJSONString(item, filter));//{"number":"no.1"}
- PropertyFilter
自定义属性是否序列化
Item item = new Item();
item.setId(555);
item.setNumber("no.1");
SerializeFilter filter = new PropertyFilter() {
@Override
public boolean apply(Object object, String name, Object value) {
if("id".equals(name)){
//只序列化id值大于100的id属性
return ((Integer) value) > 100;
}
return true;
}
};
System.out.println(JSON.toJSONString(item, filter));//{"id":555,"number":"no.1"}
- NameFilter
自定义属性序列化后的JSON中key的值
Item item = new Item();
item.setId(555);
item.setNumber("no.1");
SerializeFilter filter = new NameFilter() {
@Override
public String process(Object object, String name, Object value) {
if("id".equals(name)){
return "NO.";
}
return name;
}
};
System.out.println(JSON.toJSONString(item, filter));//{"NO.":555,"number":"no.1"}
- ValueFilter
自定义序列化后的JSON中属性的值
Item item = new Item();
item.setId(1);
item.setNumber("no.1");
SerializeFilter filter = new ValueFilter() {
@Override
public Object process(Object object, String name, Object value) {
if("id".equals(name)){
switch(value.toString()){
case "1":
return "one";
case "2":
return "two";
case "3":
return "three";
default:
return value;
}
}
return value;
}
};
System.out.println(JSON.toJSONString(item, filter));//{"id":"one","number":"no.1"}
- BeforeFilter
在序列化Java对象的所有属性前执行某些操作
Item item = new Item();
item.setId(1);
item.setNumber("no.1");
SerializeFilter filter = new BeforeFilter() {
@Override
public void writeBefore(Object object) {
System.out.println("do something...");
writeKeyValue("_first_", "_value_");
}
};
System.out.println(JSON.toJSONString(item, filter));
程序输出:
do something...
{"_first_":"_value_","id":1,"number":"no.1"}
- AfterFilter
在序列化Java对象的所有属性后执行某些操作
Item item = new Item();
item.setId(1);
item.setNumber("no.1");
SerializeFilter filter = new AfterFilter() {
@Override
public void writeAfter(Object object) {
System.out.println("do something...");
writeKeyValue("_last_", "_value_");
}
};
System.out.println(JSON.toJSONString(item, filter));
程序输出:
do something...
{"id":1,"number":"no.1","_last_":"_value_"}
3、使用ParseProcess
可以通过实现不同的ParseProcess接口来自定义反序列化
- ExtraProcessor
处理JSON中在Java对象上没有对应属性的字段
String text = "{\"id\": 666, \"value\":\"amazing\", \"xxx\": \"ext\"}";
ParseProcess process = new ExtraProcessor() {
@Override
public void processExtra(Object object, String key, Object value) {
if("xxx".equals(key)){
Item item = (Item) object;
item.setNumber((String) value);
}
}
};
Item item = JSON.parseObject(text, Item.class, process);
System.out.println(String.format("%s - %s - %s", item.getId(), item.getValue(), item.getNumber()));
程序输出:
666 - amazing - ext
- ExtraTypeProvider
指定JSON中多余字段的类型
class MyExtraProcessor implements ExtraProcessor, ExtraTypeProvider{
@Override
public Type getExtraType(Object object, String key) {
if("ext".equals(key)){
return String.class;
}
return null;
}
@Override
public void processExtra(Object object, String key, Object value) {
if("ext".equals(key)){
Item item = (Item) object;
item.setNumber((String) value);
}
}
}
String text = "{\"id\": 666, \"value\":\"amazing\", \"ext\": false}";
ParseProcess process = new MyExtraProcessor();
Item item = JSON.parseObject(text, Item.class, process);
System.out.println(String.format("%s : %s", item.getNumber().getClass(), item.getNumber()));
程序输出:
class java.lang.String : false
JSON中ext
属性的值是布尔类型的false
,由于在getExtraType()
方法中指定了类型为String,因此processExtra()
方法中取到的ext
属性的值为String类型的"false"
。
附:
-
User类
public class User {
private Integer age;
private String name;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return String.format("%s: %s", this.getName(), this.getAge());
}
}
- Item类
public class Item {
private int id;
private String number;
private String value;
private Date date;
public Item() {}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}