文章目录
- 一、json格式
- 1.1 用途
- 1.2 语法
- 1.3 常见格式
- 二、fastjson常用类
- 2.1 JSONObject
- 2.2 JSONArray
- 三、序列化和反序列化
- 3.1 默认序列化与反序列化
- 3.2 序列化的扩展
- 3.3 自定义序列化SerializeFilter
- 3.4 @JSONField 注解
- 3.5 复习Jackson
一、json格式
1.1 用途
- 一种轻量级的数据交换格式
- 用于数据传输和存储
json格式用于数据传输,常见的如前后端数据交互。而用于数据存储,常见的如一些NoSQL 数据库(如 MongoDB)用json格式来存储数据。
1.2 语法
json即大括号包围的一些键值对的集合,每个键值对之间用逗号分隔,键值对的键的类型一定是String,键值对的值的类型可以是:
- 字符串、数字、布尔
- 空值null
- 一个对象
{
"name": "Alice",
"age": 25,
"isStudent": false
}
- 数组,且数组里元素的类型可以是上面提到的json类型中的任意一种
["apple", "banana", "cherry"]
[
{
"name": "Alice",
"age": 25
},
{
"name": "Bob",
"age": 30
}
]
1.3 常见格式
就上面提到的json类型,常见的json串,如:
- 简单对象
{
"key1": "value1",
"key2": "value2"
}
- 嵌套对象
{
"person": {
"name": "Alice",
"age": 25
},
"address": {
"street": "123 Main St",
"city": "Springfield"
}
}
- 数组
{
"fruits": ["apple", "banana", "cherry"],
"numbers": [1, 2, 3, 4]
}
二、fastjson常用类
用于json结构的操作、json串和对象之间的序列化与反序列化的一个库
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
2.1 JSONObject
- 用于创建、读取、修改和管理 JSON
- JSONObject,结构上,看成是
Map<String,Object>
源码:三个构造方法如下
基本使用:增删改键值对
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
// 向json里添加键值对
jsonObject.put("name", "Tom");
jsonObject.put("age", 24);
jsonObject.put("isStudent", true);
jsonObject.put("hobby", new String[]{"reading", "music"});
// 修改json里的键值对
jsonObject.put("name", "TomPlus");
// 移除json里的键值对
jsonObject.remove("age");
// 转String格式
System.out.println(jsonObject.toJSONString());
}
JSON 字符串转JSONObject对象
public class Demo {
public static void main(String[] args) {
String jsonString = "{\"name\":\"TomPlus\",\"age\":24,\"isStudent\":true,\"hobby\":[\"reading\",\"music\"]}";
// Json串解析为JSONObject对象
JSONObject jsonObject = JSONObject.parseObject(jsonString);
// 访问数据
String name = jsonObject.getString("name");
int age = jsonObject.getIntValue("age");
Boolean isStudent = jsonObject.getBoolean("isStudent");
// 数组类型,String[].class
String[] hobby = jsonObject.getObject("hobby", String[].class);
System.out.println(hobby[0]);
}
}
2.2 JSONArray
JSONArray,即JSONObject的集合,List<Object>
相关方法:
此外,JSONAarray是支持Stream流的:
JSONArray jsonArray = new JSONArray();
jsonArray.add("test");
jsonArray.add("code");
JSONObject jsonObject = new JSONObject();
jsonArray.add(jsonObject);
jsonArray.remove(2);
jsonArray.forEach(System.out::println);
List<String> list = jsonArray.stream()
.map(e -> e + " stream")
.collect(Collectors.toList());
System.out.println(list);
三、序列化和反序列化
fastjson有个抽象类,其是JSONObject类的父类
JSON类常用的方法:
class JSON {
// 将字符串解析成JSONObject
static JSONObject parseObject(String str);
// 将字符串解析成JSONArray
static JSONArray parseArray(String str);
// 将字符串解析成Java对象
static T parseObject(byte[] utf8Bytes, Class<T> objectClass);
// 将Java对象输出成字符串
static String toJSONString(Object object);
// 将Java对象输出成UTF8编码的byte[]
static byte[] toJSONBytes(Object object);
}
3.1 默认序列化与反序列化
序列化默认会调用类的Getter方法:
// 序列化
String text = JSON.toJSONString(obj);
如果类没有Getter,序列化的结果是空的:
Person person = new Person("Tom", 24);
String str = JSON.toJSONString(person);
System.out.println(str);
反序列化成对象:默认调用无参构造来创建对象:
Person person = JSON.parseObject("{...}", Person.class); //反序列化
示例:
String objectStr = "{\"age\":24,\"name\":\"Tom\"}";
Person result = JSON.parseObject(objectStr, Person.class);
System.out.println(result);
3.2 序列化的扩展
直接使用枚举类SerializerFeature,里面可以选择序列化的一些扩展:
- SerializerFeature.BeanToArray:序列化时,不再返回正常的json串,而是返回一个数组,数组中存的是Java对象的熟性的值:
- SerializerFeature.WriteNullStringAsEmpty:序列化时,值为null的,处理成""
一些其他枚举值:
3.3 自定义序列化SerializeFilter
实现FastJson的SerializeFilter接口,进行高度的定制化自定义序列化。以下实现几个SerializeFilter的常用实现类:
- PropertyFilter用于序列化时过滤掉特定的属性
public class MyPropertyFilter implements PropertyFilter {
@Override
public boolean apply(Object object, String name, Object value) {
// 例如,排除所有值为 null 的属性
return value != null;
}
}
// 示例
Person person = new Person();
// 设置属性
String jsonString = JSON.toJSONString(person, new MyPropertyFilter());
- NameFilter用于序列化时修改字段的名称
public class MyNameFilter implements NameFilter {
@Override
public String process(Object object, String name, Object value) {
// 例如,将字段名转为大写
return name.toUpperCase();
}
}
- ValueFilter用于序列化时,修改字段的值
public class MyValueFilter implements ValueFilter {
@Override
public Object process(Object object, String name, Object value) {
// 例如,将所有字符串值转为大写
if (value instanceof String) {
return ((String) value).toUpperCase();
}
return value;
}
}
- ContextValueFilter,多了个提供当前序列化上下文的信息,例如当前对象的类、字段
// 根据字段类型做相应的处理
public class MyContextValueFilter implements ContextValueFilter {
@Override
public Object process(BeanContext context, Object object, String name, Object value) {
return object;
}
}
ContextValueFilter举例:这里直接用内部类了
public static void main(String[] args) {
Person person = new Person(24,"Tom");
// 后面的反序列化操作,可以传多个
String str = JSON.toJSONString(person, new ContextValueFilter() {
@Override
public Object process(BeanContext beanContext, Object obj, String key, Object value) {
try {
Field field = beanContext.getBeanClass().getDeclaredField(key);
Class<?> type = field.getType();
if (type.equals(String.class)) {
return "plus " + value;
} else if (type.equals(int.class)) {
return (Integer)value * 2;
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return value;
}
});
System.out.println(str);
}
3.4 @JSONField 注解
注解的属性:
- name:指定序列化时JSON 中字段的名称
- serializeUsing:指定自定义的序列化器
- deserializeUsing:指定自定义的反序列化器
- format:用于指定日期时间的格式
- ordinal:指定序列化得到的json串中,字段的顺序
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
public class MyClass {
// 将 myField 映射为 JSON 中的 my_name 字段
@JSONField(name = "my_name")
private String myField;
@JSONField(format = "yyyy-MM-dd")
private java.util.Date myDate;
// getters and setters
}
// 使用示例
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
obj.setMyField("example");
obj.setMyDate(new java.util.Date());
String json = JSON.toJSONString(obj);
System.out.println(json); // 输出:{"my_name":"example","myDate":"2024-09-01"}
MyClass parsedObj = JSON.parseObject(json, MyClass.class);
System.out.println(parsedObj.getMyField()); // 输出:example
}
}
3.5 复习Jackson
-
序列化与反序列化的自定义,还可以通过Jackson框架(
ObjectMapper
)的注解:@JsonCreator和@JsonValule -
Jackson和FastJson都是处理json串,做序列化和反序列化的,前者对注解的支持完善些,后者则是轻量
-
SpringBoot项目中,默认的序列化框架是Jackson,这一点,从spring-web-starter往下跟就可以发现,或者使用SpringBoot的自动装配,来看其核心类ObjectMapper是否为空判定
@RunWith(SpringRunner.class)
@SpringBootTest
public class JsonTest {
@Autowired
private ObjectMapper objectMapper;
@Test
public void testJacksonObjectMapper() {
assertNotNull(objectMapper);
}
}
- 如果要使用 Fastjson 或其他 JSON 处理库,必须自定义配置来替换 Jackson。如通过配置 FastjsonHttpMessageConverter 来替换默认的 Jackson 转换器