麒麟正青春

 

fastjson2

什么是JSON

网址:https://www.json.org/json-zh.html

JSON是一种轻量级的数据交换格式。它基于ECMAScript的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

简洁和清晰的层次结构是的JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

JSON语法

使用大括号{ }保存对象,每个对象由若干个数据组成;

每个数据由key:value键值对组成;

数据之间使用逗号,分隔;

使用 \ 进行特殊字符的转义

例如:

{"reason":
"success","result":
[{"id":1,"firstLetter":"A","brandName":"奥迪","brandLogo":"http"},
{"id":2,"firstLetter":"A","brandName":"雷克萨斯","brandLogo":"http"},
{"id":3,"firstLetter":"A","brandName":"奔驰","brandLogo":"ghjvh"}]

JSON的用途

JSON作为一种轻量级的数据格式,它的主要用途是在计算机系统之间进行数据的传递。

JSON作为数据传输的格式,有几个显著的优点:

(1)JSON只允许使用UTF-8编码,不存在编码问题;

(2)JSON内容仅包含key-value键值对,格式简单,不存在冗余结构,是一种轻量级结构;

(3)浏览器内置JSON支持,如果把数据用JSON发送给浏览器,可以用JavaScript直接处理;

所以,开发web应用的时候,使用JSON作为数据传输,在浏览器端非常方便。因为JSON非常适合JavaScript处理,所以,绝大多数REST API都选择JSON作为数据传输格式。

在使用Java进行应用程序的开发中,可能会遇到“将Java对象转换成JSON格式”或者“将JSON格式的数据转换成Java对象”的需求。

常用于解析JSON的第三方库有

  • Jackson
  • Gson
  • Fastjson

三、如何应用JSON

在应用JSON时我们最常用Fastjson这个库,Fastjson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化微JSON字符串,也可以从JSON字符串反序列化到JavaBean。

Fastjson主要使用JSON、jsonObject、jsonArrary三个类。其中JSONArray和JSONObject继承自JSON。

JSON类

JSON类的作用主要是用于原始转换,常用方法有:

将Java对象“序列化“(转换)为JSON字符串。

使用:JSON.toJSONString(Object object),如果需要定义json中的key,可以使用@JSONField注解在成员变量进行设置

//实体数据
PoliceStation ps1=new PoliceStation();
		ps1.setName("电子城派出所");
		ps1.setAddr("雁塔区电子二路");
		ps1.setTel("1234567890");
		//序列化:将Java对象转换成json格式的数据
		String s1=JSON.toJSONString(ps1);
		System.out.println(s1);

将JSON字符串反序列化为Java对象

JSON.parseObject(String text)

//反序列化:将json格式的字符串转换成Java对象
		String s2="{\"addr\":\"雁塔区电子二路\",
                        \"name\":\"电子城派出所\",
                         \"tel\":\"1234567890\"}\r\n }";
		PoliceStation ps2= JSON.parseObject(s2,PoliceStation.class);
		System.out.println(ps2);

JSON.parseArray(String text)

// json格式数据
String jsonStr = "[{ \"name\": \"文保分局沪东高校派出所\", \"addr\": \"中山北一路801号\", 			\"tel\": \"22027732\" 		}, { 			\"name\": \"文保分局沪西高校派出所\", 			\"addr\": \"芙蓉江路55号\", 			\"tel\": \"62751704\" 		}, { 			\"name\": \"水上公安局吴淞水上派出所\", 			\"addr\": \"淞浦路187号\", 			\"tel\": \"56671442\" 		}, { 			\"name\": \"水上公安局杨浦水上派出所\", 			\"addr\": \"杨树浦路1291号\", 			\"tel\": \"65898004\" 		}, { 			\"name\": \"水上公安局外滩水上派出所\", 			\"addr\": \"中山东二路8弄3号\", 			\"tel\": \"63305388\" 		}, { 			\"name\": \"水上公安局石洞口水上派出所\", 			\"addr\": \"盛石路18号\", 			\"tel\": \"56152176\" 		}, { 			\"name\": \"轨道分局上海火车站站派出所\", 			\"addr\": \"共和新路2838号\", 			\"tel\": \"56650472\" 		}, { 			\"name\": \"轨道分局徐家汇站派出所\", 			\"addr\": \"沪闵路6707号\", 			\"tel\": \"63189188*70246\" 		}, { 			\"name\": \"轨道分局人民广场站派出所\", 			\"addr\": \"南京西路19号\", 			\"tel\": \"63189188*76369\" 		}, { 			\"name\": \"轨道分局陆家嘴站派出所\", 			\"addr\": \"龙阳路1990号乙\", 			\"tel\": \"63189188*27132\" 		}, { 			\"name\": \"轨道分局宜山路站派出所\", 			\"addr\": \"零陵路668号\", ... \"崇明县公安局新村派出所\", 			\"addr\": \"新村乡新中村新跃160号\", 			\"tel\": \"59650598\" 		}, { 			\"name\": \"崇明县公安局新海派出所\", 			\"addr\": \"新海农场场部北侧\", 			\"tel\": \"59655712\" 		}, { 			\"name\": \"崇明县公安局长征派出所\", 			\"addr\": \"长征农场派出所生活区长征农场场部\", 			\"tel\": \"59311459\" 		}, { 			\"name\": \"崇明县公安局长江派出所\", 			\"addr\": \"东风农场林风公路1579号\", 			\"tel\": \"59641914\" 		}, { 			\"name\": \"崇明县公安局东旺派出所\", 			\"addr\": \"前哨农场前哨公路18号\", 			\"tel\": \"59471109\" 		}, { 			\"name\": \"崇明县公安局东滩湿地保护区治安派出所\", 			\"addr\": \"陈家镇瀛陈公路崇明县团结沙\", 			\"tel\": \"59404611\" 		}, { 			\"name\": \"崇明县公安局长兴派出所\", 			\"addr\": \"长兴镇海舸路659号\", 			\"tel\": \"56851431\" 		}, { 			\"name\": \"崇明县公安局横沙派出所\", 			\"addr\": \"民东路1588号\", 			\"tel\": \"24060670\" 		}]";
List<PoliceStation> stationList = JSON.parseArray(jsonStr, PoliceStation.class);
for(PoliceStation ps : stationList) {
    System.out.println("警局名称:" + ps.getName());
    System.out.println("警局地址:" + ps.getAddr());
    System.out.println("联系电话:" + ps.getTel());
}

常见问题

问题1:FastJson默认过滤null值,不显示null字段

Map<String, Object> map = new HashMap<String, Object>(){
    {
        put("age", 20);
        put("name", "灰灰");
        put("sex", null);
    }
};
System.out.println(JSONObject.toJSONString(map));
//输出结果
{"name:"灰灰","age":20}

解决方法:转换成JSON字符串时,使用Feature枚举值进行设置

Map<String, Object> map = new HashMap<String, Object>(){
    {
        put("age", 20);
        put("name", "灰灰");
        put("sex", null);
    }
};
// 使用Feature类型的枚举值进行设置
System.out.println(JSONObject.toJSONString(map,Feature.WriteMapNullValue));

问题2:控制JSON的字段顺序

//实体类
public class PoliceStation {
	private String name;
	private String addr;
	private String tel;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
}
//测试类
PoliceStation ps = new PoliceStation();
ps.setName("电子城派出所");
ps.setAddr("雁塔区电子二路343号");
ps.setTel("13324554332");
System.out.println(JSON.toJSONString(ps));
//输出结果
{"addr":"雁塔区电子二路343号","name":"电子城派出所","tel":"13324554332"}

解决方法:输出结果与字段定义顺序不一致,需要在定义实体类字段时,使用@JSONField注解的ordinal属性进行顺序配置

import com.alibaba.fastjson2.annotation.JSONField;
public class PoliceStation {
	@JSONField(ordinal = 1)
	private String name;
	@JSONField(ordinal = 2)
	private String addr;
	@JSONField(ordinal = 3)
	private String tel;
}

问题3:控制JSON的Date字段格式

//实体类
// 订单类
public class Order{
    // 订单编号
	private String orderId;
    // 创建日期
	private LocalDateTime creationTime;
	public Order() {
		this.orderId = UUID.randomUUID().toString();
		this.creationTime = LocalDateTime.now();
	}
	public String getOrderId() {
		return orderId;
	}
	public void setOrderId(String orderId) {
		this.orderId = orderId;
	}
	public LocalDateTime getCreationTime() {
		return creationTime;
	}
	public void setCreationTime(LocalDateTime creationTime) {
		this.creationTime = creationTime;
	}
}
//测试类
public class Test {
	public static void main(String[] args) {
		Order order1 = new Order();
		String json = JSON.toJSONString(order1);
		System.out.println(json);
	}
}
//输出结果
{"creationTime":"2022-07-10 19:39:07.377","orderId":"dbee4f0c-ced7-463f-b19b-c83234cbd5b0"}

解决方法:输出日期字段时,默认格式不符合需求时,可以在定义实体类的Date字段,使用@jsonFie注解的format属性进行格式配置

// 订单类
public class Order{
	// 订单编号
	private String orderId;
	// 创建日期
	@JSONField(format = "yyyy-MM-dd HH:mm:ss")
	private LocalDateTime creationTime;
}

////////////////////////////////////////fastjson2.0 ////////////////////////////////////////////////

fastjson2.0 是fastjson的重要升级,目标是为下一个十年提供一个高性能的JSON库,同一套API支持JSON/JSONB两种协议。近期fastjson 再报安全漏洞,直接给我们发送了高危告警,因此升级fastjson迫在眉睫。

FasterXML Jackson是美国FasterXML公司的一款适用于Java的数据处理工具。Jackson-databind是其中的一个具有数据绑定功能的组件。Jackson-databind可以将Java对象转换成json对象,同样也可以将json转换成Java对象。

astjson、jackson 都支持 AutoType 功能,这个功能在序列化的 JSON 字符串中带上类型信息,在反序列化时,不需要传入类型,实现自动类型识别。

Fastjson2Fastjson的升级版,特征:

  • 协议支持:支持JSON/JSONB两种协议
  • 部分解析:可以使用JSONPath进行部分解析获取需要的值
  • 语言支持:Java/Kotlin
  • 场景支持:Android8+/服务端
  • 其他特性支持:Graal Native-ImageJSON Schema

fastjson2 的设计
fastjson2 AutoType 必须显示打开才能使用,没有任何白名单,也不包括任何 Exception 类的白名单。这可以保证缺省配置下是安全的。序列化时带上类型信息,需要使用 JSONWriter.Feature.WriteClassName。比如:

Bean bean = ...;
String jsonString = JSON.toJSONString
(bean, JSONWriter.Feature.WriteClassName);
很多时候,root对象是可以知道类型的,里面的对象字段是基类或者不确定类型,这个时候不输出root对象的类型信息,可以减少序列化结果的大小,也能提升反序列化的性能。

Bean bean = ...;
String jsonString = JSON.toJSONString
(bean, JSONWriter.Feature.WriteClassName,
JSONWriter.Feature.NotWriteRootClassName);
反序列化打开AutoType功能支持自动类型

Bean bean = (Bean) JSON.parseObject
(jsonString, Object.class, JSONReader.Feature.SupportAutoType);
fastjson2 AutoType 支持配置 safeMode,在 safeMode 打开后,显式传入 AutoType 参数也不起作用,具体配置如下:

-Dfastjson2.parser.safeMode=true
fastjson2 AutoType 会经过内置黑名单过滤。该黑名单能拦截大部分常见风险,这个机制不能保证绝对安全,打开 AutoType 不应该在暴露在公网的场景下使用。 

序列化示例代码
使用FastJson2JsonRedisSerializer实现RedisSerializer接口

public class FastJson2JsonRedisSerializer<T>implements RedisSerializer<T>{

public static final Charset DEFAULT_CHARSET= Charset.forName("UTF-8");
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz)
{
  super();
  this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException
{
  if (t == null)
  {
    return new byte[0];
  }
  return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException
{
  if (bytes == null || bytes.length <= 0)
  {
    return null;
  }
  String str = new String(bytes, DEFAULT_CHARSET);
  return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
}

pom文件中引入fastjson2依赖

<dependency>
  <groupId>com.alibaba.fastjson2</groupId>
  <artifactId>fastjson2</artifactId>
  <version>2.0.43</version>
</dependency>

Fastjson Extension扩展模块

如果项目使用SpringFramework等框架,可以使用fastjson-extension模块,使用方式参考 SpringFramework Support

Maven:

<dependency>

  <groupId>com.alibaba.fastjson2</groupId>

   <artifactId>fastjson2-extension-spring5</artifactId>

   <version>2.0.43</version>

</dependency>

<dependency>

   <groupId>com.alibaba.fastjson2</groupId>

   <artifactId>fastjson2-extension-spring6</artifactId>

   <version>2.0.43</version>

</dependency>

 

 常见问题

来自于:https://github.com/alibaba/fastjson2/wiki/fastjson_1_upgrade_cn

4.1. ParserConfig.getGlobalInstance().addAccept()如何兼容

在2.x版本中,ParserConfig添加autoType白名单的功能在ObjectReaderProvider中提供,可以如下的方式配置autoType白名单。

JSONFactory.getDefaultObjectReaderProvider().addAutoTypeAccept("com.mycompany.xxx");
 

4.2. ObjectSerializer 和 ObjectDeserializer 被移除了,有什么新的代替方案

FASTJSON v2中有比较完善的扩展机制,如下:

4.3. 常见的类扩展升级映射

fastjson1fastjson2
com.alibaba.fastjson.parser.ParserConfig com.alibaba.fastjson2.reader.ObjectReaderProvider
com.alibaba.fastjson.parser.deserializer.ExtraProcessor com.alibaba.fastjson2.filter.ExtraProcessor
com.alibaba.fastjson.parser.deserializer.ObjectDeserializer com.alibaba.fastjson2.reader.ObjectReader
com.alibaba.fastjson.serializer.AfterFilter com.alibaba.fastjson2.filter.AfterFilter
com.alibaba.fastjson.serializer.BeforeFilter com.alibaba.fastjson2.filter.BeforeFilter
com.alibaba.fastjson.serializer.ContextValueFilter com.alibaba.fastjson2.filter.ContextValueFilter
com.alibaba.fastjson.serializer.LabelFilter com.alibaba.fastjson2.filter.LabelFilter
com.alibaba.fastjson.serializer.NameFilter com.alibaba.fastjson2.filter.NameFilter
com.alibaba.fastjson.serializer.PascalNameFilter com.alibaba.fastjson2.filter.PascalNameFilter
com.alibaba.fastjson.serializer.PropertyFilter com.alibaba.fastjson2.filter.PropertyFilter
com.alibaba.fastjson.serializer.ObjectSerializer com.alibaba.fastjson2.writer.ObjectWriter
com.alibaba.fastjson.serializer.SerializeConfig com.alibaba.fastjson2.writer.ObjectWriterProvider
com.alibaba.fastjson.serializer.ToStringSerializer com.alibaba.fastjson2.writer.ObjectWriterImplToString
com.alibaba.fastjson.serializer.ValueFilter com.alibaba.fastjson2.filter.ValueFilter
com.alibaba.fastjson.serializer.SerializerFeature com.alibaba.fastjson2.JSONReader.Feature
com.alibaba.fastjson.parser.Feature com.alibaba.fastjson2.JSONWriter.Feature

 

 

 

 

 

 

 

 

 

 

4.4 SerializerFeature.UseISO8601DateFormat在fastjson2的替代方案

fastjson2的JSONWriter.Feature没有和UseISO8601DateFormat的Feature,代替方法是使用format="iso8601",如下:

import com.alibaba.fastjson2.JSON;

String format = "iso8601";
JSON.toJSONString(obj, format);
 

4.5 ## SerializerFeature.DisableCircularReferenceDetect在fastjson2的替代方案

在fastjson2中,代替的是JSONWriter.Feature.ReferenceDetection,但语义相反,缺省不一样。fastjson2中的JSONWriter.Feature.ReferenceDetection缺省是关闭的,而fastjson1是现实打开的。

4.6 SerializerFeature.SortField在fastjson2的替代方案

不需要,在fastjson2中,JSONObject继承自LinkedHashMap,不需要配置这个Feature

4.7 SerializerFeature.WriteDateUseDateFormat在fastjson2的替代方案

在fastjson2中的缺省行为就是使用dateFormat,如果要修改为成和fastjson 1.x一样的行为,需要配置format = "millis",如下:

import com.alibaba.fastjson2.JSON;

String format = "millis";
JSON.toJSONString(obj, format);
 

4.8 全局配置

在fastjson 1.x中,通过JSON.DEFAULT_GENERATE_FEATURE和JSON.DEFAULT_PARSER_FEATURE配置全局选项。这个在fastjson 2中的替代方案是:

package com.alibaba.fastjson2;

interface JSON {
    static void config(JSONReader.Feature... features);
    static void config(JSONWriter.Feature... features);
}

/////////////////////////////fastjson2使用////////////////////////////////////////
来自于:https://blog.csdn.net/xijinno1/article/details/129869584

需要注意的一点是在使用 fastjson2 时导入的包名是 com.alibaba.fastjson2 ,就像下面这样:

import com.alibaba.fastjson2.JSON;

import com.alibaba.fastjson2.JSONObject;

import com.alibaba.fastjson2.JSONArray;

 

json对象与json数组的创建

json对象创建

import com.alibaba.fastjson2.JSONObject;  

public class Demo { 

public static void main(String[] args) {

  JSONObject info = new JSONObject();

info.put("name", "张三");

info.put("age", "18");

info.put("地理", "70");

info.put("英语", "60");

System.out.println(info);

json数组创建

 

import com.alibaba.fastjson2.JSONArray;

public class Demo {

public static void main(String[] args) {

JSONArray array = new JSONArray();

array.add("1班");

array.add("2班");

array.add("3班");

System.out.println(array);

}

}

import com.alibaba.fastjson2.JSONArray;

import com.alibaba.fastjson2.JSONObject;
public class Demo {
public static void main(String[] args) {
JSONObject info1 = new JSONObject();
info1.put("name", "张三");
info1.put("age", "18");
JSONObject info2 = new JSONObject();
info2.put("name", "李四");
info2.put("age", "19");
//把上面创建的两个json对象加入到json数组里
JSONArray array = new JSONArray();
array.add(info1);
array.add(info2);
System.out.println(array);
}
}

json对象取值与json数组遍历取值

json对象取值

 

import com.alibaba.fastjson2.JSONArray;

import com.alibaba.fastjson2.JSONObject;
public class Demo {

public static void main(String[] args) {

JSONArray array = new JSONArray();

array.add("1班");

array.add("2班");

array.add("3班");

JSONObject school = new JSONObject();

school.put("schoolName", "第一中学");

school.put("teacher", "刘梅");

JSONObject info = new JSONObject();

info.put("name", "张三");

info.put("age", "18");

info.put("gradle", array);

info.put("schoolInfo", school);

//从info中取值

System.out.println(info.getString("name")); //张三

System.out.println(info.getIntValue("age"));//18

System.out.println(info.getJSONArray("gradle"));//["1班","2班","3班"]

System.out.println(info.getJSONObject("schoolInfo"));//{"schoolName":"第一中学","teacher":"刘梅"}

}

}

json数组遍历取值

 

import com.alibaba.fastjson2.JSONArray;

import com.alibaba.fastjson2.JSONObject;
public class Demo {

public static void main(String[] args) {

JSONObject info1 = new JSONObject();

info1.put("name", "张三");

info1.put("age", "18");

JSONObject info2 = new JSONObject();

info2.put("name", "李四");

info2.put("age", "19");

JSONArray array = new JSONArray();

array.add(info1);

array.add(info2);

//遍历获取json数组中对象的值

for (int i = 0; i < array.size(); i++) {

  JSONObject json = array.getJSONObject(i);

  System.out.println(json.getString("name"));

  System.out.println(json.getString("age"));

}

}

}

json对象与字符串的转换

json对象与字符串的转换

 

import com.alibaba.fastjson2.JSON;

import com.alibaba.fastjson2.JSONObject;
public class Demo {

public static void main(String[] args) {

JSONObject info = new JSONObject();

info.put("name", "张三");

info.put("age", "18");

info.put("地理", "70");

info.put("英语", "60");

//JSON对象转字符串

String str = JSON.toJSONString(info);

System.out.println(str);

//JSON字符串转JSON对象

JSONObject json = JSONObject.parseObject(str);

System.out.println(json);

}

}

json字符串的字节数组转json对象

 

import com.alibaba.fastjson2.JSON;

import com.alibaba.fastjson2.JSONObject;
public class Demo {

public static void main(String[] args) {

String str = "{\"name\":\"张三\",\"age\":\"18\",\"地理\":\"70\",\"英语\":\"60\"}";

byte[] bytes = str.getBytes();//字符串到字节数组

JSONObject data = JSON.parseObject(bytes);

System.out.println(data);

}

}

json数组与字符串的转换 

import com.alibaba.fastjson2.JSON;

import com.alibaba.fastjson2.JSONArray;
public class Demo {

public static void main(String[] args) {

String text = "[\"张三\",\"李四\",\"王五\"]";

System.out.println(text);

//json字符串转json数组

JSONArray data = JSON.parseArray(text);

//json数组转json字符串

String str = JSONArray.toJSONString(data);

System.out.println(data);

System.out.println(str);

}

}

json字符串转java对象的转换

Student类如下: 

public class Student {

public String name;
public int age;

public String getName() {

  return name;

}

public void setName(String name) {

  this.name = name;

}

public int getAge() {

  return age;

}

public void setAge(int age) {

  this.age = age;

}

public Student(String name, int age) {  

this.name = name;
  this.age = age;

}

json字符串转java对象的转换 

import com.alibaba.fastjson2.JSON;
public class Demo {

public static void main(String[] args) {

Student student = new Student("张三", 18);

//Student对象转JSON字符串

String studentStr = JSON.toJSONString(student);

//JSON字符串转Student对象

Student data = JSON.parseObject(studentStr, Student.class);

System.out.println(studentStr);

}

}

java对象转byte数组转换 

import com.alibaba.fastjson2.JSON;

public class Demo {

public static void main(String[] args) {

Student student = new Student("张三", 18);

//Student对象转字节数组

byte[] text = JSON.toJSONBytes(student);

//字节数组转Student对象

Student data = JSON.parseObject(text, Student.class);

System.out.println(data.getName() + data.getAge());

}

}

json字符串与Map转换

json字符串转Map 

import com.alibaba.fastjson2.JSONObject;

import com.alibaba.fastjson2.TypeReference;
import java.util.Map;

public class Demo {

public static void main(String[] args) {

String str = "{\n" +

"\"gradle\":\"高一\",\n" +

"\"number\":\"2\",\n" +

"\"people\":[{\"name\":\"张三\",\"age\":\"15\",\"phone\":\"123456\"},\n" +

" {\"name\":\"李四\",\"age\":\"16\",\"phone\":\"78945\"}]\n" +

"}";

//json字符串转Map

Map<String, Object> map = JSONObject.parseObject(str, new TypeReference<Map<String, Object>>() {

});

System.out.println(map.get("gradle").toString());

System.out.println(map.get("number").toString());

System.out.println(map.get("people").toString());

}

}

Map转json字符串

(注意:如果直接使用JSON.toJSONString(map)转换,因为"测试1"的值为null,转换的结果就会是 {“测试2”:“hello”}) 

import com.alibaba.fastjson2.JSON;

import com.alibaba.fastjson2.JSONWriter;
import java.util.HashMap;

import java.util.Map;

public class Demo {

public static void main(String[] args) {

Map<String, String> map = new HashMap<>();

map.put("测试1", null);

map.put("测试2", "hello");

//{"测试2":"hello","测试1":null}

String str = JSON.toJSONString(map, JSONWriter.Feature.WriteMapNullValue);

System.out.println(str);

}

}

如果你使用的是老的fastjson1(下述是简单示例,不可使用),可以像下面这样转换:

Map<String, String> map = new HashMap<>();

map.put("测试1", null);
map.put("测试2", "hello");

String str = JSON.toJSONString(map, SerializerFeature.WriteMapNullValue) ;

 

json数组转List 

import com.alibaba.fastjson2.JSONArray;

import com.alibaba.fastjson2.JSONObject;
import java.util.List;

import java.util.Map;

public class Demo {

public static void main(String[] args) {

String str = "{\n" +

"\"gradle\":\"高一\",\n" +

"\"number\":\"2\",\n" +

"\"people\":[{\"name\":\"张三\",\"age\":\"15\",\"phone\":\"123456\"},\n" +

" {\"name\":\"李四\",\"age\":\"16\",\"phone\":\"78945\"}]\n" +

"}";

JSONObject strJson = JSONObject.parseObject(str);

//获取people数组

JSONArray people = strJson.getJSONArray("people");

//json数组转List

List<Map> list = people.toJavaList(Map.class);

System.out.println(str);

}

}

 

如果你使用的是老的fastjson1,可以像下面这样转换:

String str = "{\n" +  

"\"gradle\":\"高一\",\n" +
  "\"number\":\"2\",\n" +

  "\"people\":[{\"name\":\"张三\",\"age\":\"15\",\"phone\":\"123456\"},\n" +

  "         {\"name\":\"李四\",\"age\":\"16\",\"phone\":\"78945\"}]\n" +

"}";

JSONObject strJson = JSONObject.parseObject(str);//字符串转json对象

String people = String.valueOf(strJson.getJSONArray("people"));

List<Map<String, String>> list = (List<Map<String, String>>) JSONArray.parse(people);

 

///////////////////////////////解决Fastjson2 oom(Out Of Memory),支持大对象(LargeObject 1G)json操作//////////////////////////////////////

解决Fastjson2 oom(Out Of Memory),支持大对象(LargeObject 1G)json操作

news/2023/12/20 14:22:11
国内免费可用的ChatGPT镜像推荐,点击查看 https://sourl.cn/DJCHxE

在使用Fastjson中的 JSON.toJSONString时,如果对象数据太大(>64M)会出现Out Of Memory,查看源码发现为JSONWriter中的判断代码

 其中maxArraySize默认最大为64M,如果超过了就会抛出oom错误

 如果fastjson过多的使用内存,也可能导致java堆内存溢出,所以这里建议控制好json对象大小,避免过多过大对象做json操作。

使默认的JSON操作支持到大对象(LargeObject 1G)

也可以使默认的JSON操作支持到大对象(1G),只需要配置好默认上下文对象(context.features)使用方法:

JSON.config(LargeObject, true);

加入到静态代码块或者程序入口,初始化函数等。但是这里要注意如果fastjson过多的使用内存,也可能导致java堆内存溢出。

 

文章来源:https://blog.csdn.net/huang007guo/article/details/132368933
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://lihuaxi.xjx100.cn/news/1459246.html 
 
 

posted on 2023-12-21 14:29  麒麟正青春  阅读(694)  评论(0编辑  收藏  举报

导航