一、简介

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"
附:
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;
	}
}