【日常业务开发】常用JSON库API
Gson
GSON 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库,可以快速的将一个 Json 字符转成一个 Java 对象,或者将一个 Java 对象转化为 Json 字符串。SpringBoot默认对gson已经存在了版本控制。可以指定version版本覆盖boot默认版本。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
Java 对象转 Json字符串(序列化)
String toJson(Object src) | 将指定的对象序列化为其等效的Json表示形式,当指定的对象不是泛型类型时,应使用此方法,如果对象是泛型类型,请改用 toJson(object,type). |
---|---|
String toJson(Object src, Type typeOfSrc) | 将指定的对象(包括泛型类型的对象)序列化为其等效的Json表示形式,对于非泛型对象,请改用{@link#toJson(Object)} |
String toJson(JsonElement jsonElement) | 将 JsonElement 转换为其等效的JSON表示形式。 |
JsonElement toJsonTree(Object src) | 将指定的对象序列化为 JsonElement 的等效表示形式,当指定的对象不是泛型类型时,应使用此方法;如果对象是泛型类型,请改用{@link#toJsonTree(object,type)} |
@Data
public class Teacher {
private Integer id;
private String name;
List<Student> students;
}
@Data
public class Student {
private Integer id;
private String name;
private Integer age;
}
@Test
public void testToJson() {
Teacher teacher = new Teacher();
Student student = new Student();
ArrayList<Student> students = new ArrayList<>();
student.setId(1001);
student.setName("SpringBoot");
student.setAge(20);
students.add(student);
teacher.setId(1);
teacher.setName("Spring");
teacher.setStudents(students);
Gson gson = new Gson();
String str = gson.toJson(teacher);
System.out.println(str);
}
Json字符串转Java 对象(反序列化)
T fromJson(String json, Class classOfT) | 将指定的 Json 反序列化为指定类的对象,如果指定的类是泛型类型,则使用 fromJson(String, Type)方法。 |
---|---|
T fromJson(String json, Type typeOfT) | 将指定的 Json 反序列化为指定类型的对象,如果指定的对象是泛型类型,则此方法很有用,对于非泛型对象,请改用 fromJson(String json, Class classOfT) |
T fromJson(JsonElement json, Class classOfT) | 将指定的 json 元素反序列化为指定类型的对象,如果指定的类是泛型类型,则使用 fromJson(JsonElement, Type) 方法。 |
T fromJson(JsonElement json, Type typeOfT) | |
T fromJson(Reader json, Class classOfT) | |
T fromJson(Reader json, Type typeOfT) | 将从指定字符输入流读取的Json反序列化为指定类的对象 |
/**
* fromJson方法做与 toJson 相反的操作,将 json 格式的字符串转为基本数据类型、 POJO 对象、List、Map 、JsonElement 等
*/
@Test
public void testFromJson() {
String str = "{\"id\":1,\"name\":\"Spring\",\"students\":[{\"id\":1001,\"name\":\"SpringBoot\",\"age\":20}]}";
Gson gson = new Gson();
Teacher teacher = gson.fromJson(str, Teacher.class);
System.out.println(teacher);
}
FastJson
fastjson 是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>
FASTJSON v2
是FASTJSON
项目的重要升级,FASTJSON v2
性能有了很大提升,目标是为下一个十年提供一个高性能的JSON
库。通过同一套API
,
- 支持JSON/JSONB两种协议,JSONPath是一等公民。
- 支持全量解析和部分解析。
- 支持Java服务端、客户端Android、大数据场景。
- 支持Kotlin
- 支持Android (2.0.3.android)
- 支持Graal Native-Image (2.0.3.graal)
在 fastjson v2 中,package 和 1.x 不一样,是 com.alibaba.fastjson2,如果你之前用的是fastjson1,大多数情况直接更包名就即可
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.20</version>
</dependency>
JSON**.**parseObject() | 将JSON 解析为JSONObject |
---|---|
JSON**.parseArray(**text) | 将JSON 解析为JSONArray |
JSON**.parseObject(text,** User.class) | 将JSON 解析为Java 对象 |
JSON**.toJSONString(**data); | 将Java 对象序列化为JSON |
Java 对象转 Json字符串(序列化)
@Test
public void testToJSONString() {
Teacher teacher = new Teacher();
Student student = new Student();
ArrayList<Student> students = new ArrayList<>();
student.setId(1001);
student.setName("SpringBoot");
student.setAge(20);
students.add(student);
teacher.setId(1);
teacher.setName("Spring");
teacher.setStudents(students);
String string = JSON.toJSONString(teacher);
System.out.println(string);
}
Json字符串转Java 对象(反序列化)
@Test
public void testParseObject() {
String str = "{\"id\":1,\"name\":\"Spring\",\"students\":[{\"id\":1001,\"name\":\"SpringBoot\",\"age\":20}]}";
Teacher teacher = JSON.parseObject(str, Teacher.class);
System.out.println(teacher);
}
Jackson
Jackson是当前用的比较广泛的,用来序列化和反序列化json的Java开源框架。Jackson社区相对比较活跃,更新速度也比较快, 从Github中的统计来看,Jackson是最流行的json解析器之一,Spring MVC的默认json解析器便是Jackson。
Jackson优点很多:
- Jackson 所依赖的jar包较少,简单易用。
- 与其他 Java 的 json 的框架 Gson 等相比,Jackson 解析大的 json 文件速度比较快。
- Jackson 运行时占用内存比较低,性能比较好
- Jackson 有灵活的 API,可以很容易进行扩展和定制。
目前最新版本是2.9.4,Jackson 的核心模块由三部分组成:
- jackson-core 核心包,提供基于”流模式”解析的相关 API,它包括 JsonPaser 和 JsonGenerator。Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
- jackson-annotations 注解包,提供标准注解功能;
- jackson-databind 数据绑定包,提供基于”对象绑定” 解析的相关 API( ObjectMapper )和”树模型” 解析的相关 API(JsonNode);基于”对象绑定” 解析的 API 和”树模型”解析的 API 依赖基于”流模式”解析的 API。
Java 对象转 Json字符串(序列化)
String writeValueAsString(Object value) | 1、用于将任何 Java 对象(如 POJO、List、Set、Map等)序列化为 json 字符串,如果对象中某个属性的值为 null,则默认也会序列化为 null;2、如果 value 为 null,返回序列化的结果也返回 null |
---|---|
byte[] writeValueAsBytes(Object value) | 将 java 对象序列化为 字节数组 |
writeValue(File resultFile, Object value) | 将 java 对象序列化并输出指定文件中 |
writeValue(OutputStream out, Object value) | 将 java 对象序列化并输出到指定字节输出流中 |
writeValue(Writer w, Object value) | 将 java 对象序列化并输出到指定字符输出流中 |
@Test
public void testWriteValueAsString() throws JsonProcessingException {
Teacher teacher = new Teacher();
Student student = new Student();
ArrayList<Student> students = new ArrayList<>();
student.setId(1001);
student.setName("SpringBoot");
student.setAge(20);
students.add(student);
teacher.setId(1);
teacher.setName("Spring");
teacher.setStudents(students);
ObjectMapper objectMapper = new ObjectMapper();
String str = objectMapper.writeValueAsString(teacher);
System.out.println(str);
}
Json字符串转Java 对象(反序列化)
1、通常转对象使用方式是 objectMapper.readValue(String jsonStr, Class<T> clazz)
2、转List、Map使用方式是 objectMapper.readValue(String jsonStr, TypeReference<T> valueTypeRef)
; 例子如下:
- List: objectMapper.readValue(json, new TypeReference<List>() {});
- Map: objectMapper.readValue(json, new TypeReference<Map<String, Teacher>>() {});
Java Bean对象
T readValue(String content, Class valueType) | 1、从给定的 JSON 字符串反序列化为 Java 对象;2、content 为空或者为 null,都会报错 3、valueType 表示反序列化的结果对象,可以是任何 java 对象,比如 POJO、List、Set、Map 等等. |
---|---|
T readValue(byte[] src, Class valueType) | 将 json 内容的字节数组反序列化为 java 对象 |
T readValue(File src, Class valueType) | 将本地 json 内容的文件反序列化为 java 对象 |
T readValue(InputStream src, Class valueType) | 将 json 内容的字节输入流反序列化为 java 对象 |
T readValue(Reader src, Class valueType) | 将 json 内容的字符输入流反序列化为 java 对象 |
T readValue(URL src, Class valueType) | 通过网络 url 地址将 json 内容反序列化为 java 对象 |
@Test
public void readValue() throws JsonProcessingException {
String str = "{\"id\":1,\"name\":\"Spring\",\"students\":[{\"id\":1001,\"name\":\"SpringBoot\",\"age\":20}]}";
ObjectMapper objectMapper = new ObjectMapper();
Teacher teacher = objectMapper.readValue(str, Teacher.class);
System.out.println(teacher);
}
List集合对象
第一种写法,可以解析成List对象,但是里面的实体的LinkedHashMap结果的对象
public static void main(String[] args) throws JsonProcessingException {
String str = "[{\"id\":1,\"name\":\"Spring\",\"students\":[{\"id\":1001,\"name\":\"SpringBoot\",\"age\":20}]}]";
ObjectMapper objectMapper = new ObjectMapper();
List list = objectMapper.readValue(str, List.class);
System.out.println(list);
}
第二种写法,可以转成我们想要的JavaBean实体对象,常用这种方式转List集合对象
String str = "[{\"id\":1,\"name\":\"Spring\",\"students\":[{\"id\":1001,\"name\":\"SpringBoot\",\"age\":20}]}]";
ObjectMapper objectMapper = new ObjectMapper();
List<Teacher> teachers = objectMapper.readValue(str, new TypeReference<List<Teacher>>() {});
System.out.println(teachers);
Map对象
String str = "{\"teacher1\":{\"id\":1,\"name\":\"Spring\",\"students\":[{\"id\":1001,\"name\":\"SpringBoot\",\"age\":20}]}," +
"\"teacher2\":{\"id\":2,\"name\":\"JAVA\",\"students\":[{\"id\":1002,\"name\":\"JAVASE\",\"age\":10}]}}";
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Teacher> map = objectMapper.readValue(str, Map.class);
System.out.println(map);
第二种写法:
String str = "{\"teacher1\":{\"id\":1,\"name\":\"Spring\",\"students\":[{\"id\":1001,\"name\":\"SpringBoot\",\"age\":20}]}," +
"\"teacher2\":{\"id\":2,\"name\":\"JAVA\",\"students\":[{\"id\":1002,\"name\":\"JAVASE\",\"age\":10}]}}";
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Teacher> map = objectMapper.readValue(str, new TypeReference<Map<String, Teacher>>() {});
System.out.println(map);
Json 字符串内容反序列化为 Json 节点对象
JsonNode readTree(String content) | 将 JSON 字符串反序列化为 JsonNode 对象,即 json 节点对象 |
---|---|
JsonNode readTree(URL source) | 对网络上的 json 文件进行反序列化为 json 节点对象 |
JsonNode readTree(InputStream in) | 对 json 文件输入流进行反序列化为 json 节点对象 |
JsonNode readTree(byte[] content) | 对 json 字节数组反序列化为 json 节点对象 |
JsonNode readTree(File file) | 将本地 json 文件反序列为为 json 节点对象 |
Java 对象与 Json 节点对象的转换
T convertValue(Object fromValue, Class toValueType) | 将 Java 对象(如 POJO、List、Map、Set 等)序列化为 Json 节点对象。 |
---|---|
T treeToValue(TreeNode n, Class valueType) | json 树节点对象转 Java 对象(如 POJO、List、Set、Map 等等),TreeNode 树节点是整个 json 节点对象模型的根接口。 |
JackJsonUtil
@Slf4j
public class JackJsonUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
// 时间日期格式
private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";
//以静态代码块初始化
static {
//对象的所有字段全部列入序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
//取消默认转换timestamps形式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//忽略空Bean转json的错误
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//所有的日期格式都统一为以下的格式,即yyyy-MM-dd HH:mm:ss
objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
//忽略 在json字符串中存在,但在java对象中不存在对应属性的情况。防止错误
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
/**===========================以下是从JSON中获取对象====================================*/
public static <T> T parseObject(String jsonString, Class<T> object) {
T t = null;
try {
t = objectMapper.readValue(jsonString, object);
} catch (JsonProcessingException e) {
log.error("JsonString转为自定义对象失败:{}", e.getMessage());
}
return t;
}
public static <T> T parseObject(File file, Class<T> object) {
T t = null;
try {
t = objectMapper.readValue(file, object);
} catch (IOException e) {
log.error("从文件中读取json字符串转为自定义对象失败:{}", e.getMessage());
}
return t;
}
//将json数组字符串转为指定对象List列表或者Map集合
public static <T> T parseJSONArray(String jsonArray, TypeReference<T> reference) {
T t = null;
try {
t = objectMapper.readValue(jsonArray, reference);
} catch (JsonProcessingException e) {
log.error("JSONArray转为List列表或者Map集合失败:{}", e.getMessage());
}
return t;
}
/**=================================以下是将对象转为JSON=====================================*/
public static String toJSONString(Object object) {
String jsonString = null;
try {
jsonString = objectMapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
log.error("Object转JSONString失败:{}", e.getMessage());
}
return jsonString;
}
public static byte[] toByteArray(Object object) {
byte[] bytes = null;
try {
bytes = objectMapper.writeValueAsBytes(object);
} catch (JsonProcessingException e) {
log.error("Object转ByteArray失败:{}", e.getMessage());
}
return bytes;
}
public static void objectToFile(File file, Object object) {
try {
objectMapper.writeValue(file, object);
} catch (JsonProcessingException e) {
log.error("Object写入文件失败:{}", e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
/**=============================以下是与JsonNode相关的=======================================*/
//JsonNode和JSONObject一样,都是JSON树形模型,只不过在jackson中,存在的是JsonNode
public static JsonNode parseJSONObject(String jsonString) {
JsonNode jsonNode = null;
try {
jsonNode = objectMapper.readTree(jsonString);
} catch (JsonProcessingException e) {
log.error("JSONString转为JsonNode失败:{}", e.getMessage());
}
return jsonNode;
}
public static JsonNode parseJSONObject(Object object) {
JsonNode jsonNode = objectMapper.valueToTree(object);
return jsonNode;
}
public static String toJSONString(JsonNode jsonNode) {
String jsonString = null;
try {
jsonString = objectMapper.writeValueAsString(jsonNode);
} catch (JsonProcessingException e) {
log.error("JsonNode转JSONString失败:{}", e.getMessage());
}
return jsonString;
}
//JsonNode是一个抽象类,不能实例化,创建JSON树形模型,得用JsonNode的子类ObjectNode,用法和JSONObject大同小异
public static ObjectNode newJSONObject() {
return objectMapper.createObjectNode();
}
//创建JSON数组对象,就像JSONArray一样用
public static ArrayNode newJSONArray() {
return objectMapper.createArrayNode();
}
/**===========以下是从JsonNode对象中获取key值的方法,个人觉得有点多余,直接用JsonNode自带的取值方法会好点,出于纠结症,还是补充进来了*/
public static String getString(JsonNode jsonObject, String key) {
String s = jsonObject.get(key).asText();
return s;
}
public static Integer getInteger(JsonNode jsonObject, String key) {
Integer i = jsonObject.get(key).asInt();
return i;
}
public static Boolean getBoolean(JsonNode jsonObject, String key) {
Boolean bool = jsonObject.get(key).asBoolean();
return bool;
}
public static JsonNode getJSONObject(JsonNode jsonObject, String key) {
JsonNode json = jsonObject.get(key);
return json;
}
}