摘要:本文介绍了如何在Java中使用GSON进行JSON的序列化和反序列化操作。
环境
Windows 10 企业版 LTSC 21H2
Java 1.8
1 简介
Jackson是一个高性能的JSON处理库,用于将Java对象与JSON数据格式进行相互转换。它提供了灵活的API,方便开发者在Java应用程序中处理JSON数据。
2 基础使用
核心组件:
- jackson-core:提供底层的API接口。
- jackson-annotations:提供丰富的注解。
- jackson-databind:提供数据绑定功能,包含上面两个组件。
在pom.xml中添加依赖:
pom.xml1 2 3 4 5
| <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.1</version> </dependency>
|
导入jackson-databind后,会自动导入jackson-core和jackson-annotations到项目中。
定义Java类:
Student.java1 2 3 4 5 6
| public class Student { private String name; private int age; private List<String> hobbies; }
|
序列化:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static void main(String[] args) { Student student = new Student(); student.setName("张三"); student.setAge(20); student.setHobbies(Arrays.asList("阅读", "编程", "运动")); ObjectMapper objectMapper = new ObjectMapper(); try { String json = objectMapper.writeValueAsString(student); System.out.println("序列化结果: " + json); } catch (JsonProcessingException e) { e.printStackTrace(); } }
|
反序列化:
java1 2 3 4 5 6 7 8 9 10 11 12 13
| public static void main(String[] args) { String json = "{\"name\":\"张三\",\"age\":20,\"hobbies\":[\"阅读\",\"编程\",\"运动\"]}"; ObjectMapper objectMapper = new ObjectMapper(); try { Student student = objectMapper.readValue(json, Student.class); System.out.println("反序列化结果: " + student.getName() + ", " + student.getAge() + ", " + student.getHobbies()); } catch (IOException e) { e.printStackTrace(); } }
|
3 处理泛型
使用TypeReference处理泛型:
java1 2 3 4 5 6 7 8 9 10 11 12 13
| public static void main(String[] args) throws IOException { Student student = new Student(); student.setName("张三"); List<Student> studentList = new ArrayList<>(); studentList.add(student); ObjectMapper objectMapper = new ObjectMapper(); String jsonString = objectMapper.writeValueAsString(studentList); System.out.println(jsonString); List<Student> jsonList = objectMapper.readValue(jsonString, new TypeReference<List<Student>>(){}); System.out.println(jsonList.get(0).getName()); }
|
4 流式处理
4.1 序列化
使用JsonGenerator类实现序列化。
常用方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public void writeObjectFieldStart(String fieldName) throws IOException;
public abstract void writeStartObject() throws IOException;
public abstract void writeEndObject() throws IOException;
public void writeArrayFieldStart(String fieldName) throws IOException;
public abstract void writeStartArray() throws IOException;
public abstract void writeEndArray() throws IOException;
public abstract void writeFieldName(String name) throws IOException;
public abstract void writeBoolean(boolean state) throws IOException;
public abstract void writeString(String text) throws IOException;
public abstract void writeNull() throws IOException;
public void writeBooleanField(String fieldName, boolean value) throws IOException;
public void writeNumberField(String fieldName, int value) throws IOException;
public void writeNumberField(String fieldName, long value) throws IOException;
public void writeNumberField(String fieldName, float value) throws IOException;
public void writeNumberField(String fieldName, double value) throws IOException;
public void writeStringField(String fieldName, String value) throws IOException;
public void writeNullField(String fieldName) throws IOException;
public abstract void flush() throws IOException;
|
自动序列化:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static void main(String[] args) { Student student = new Student(); student.setName("张三"); student.setAge(20); student.setHobbies(Arrays.asList("阅读", "编程", "运动")); ObjectMapper objectMapper = new ObjectMapper(); try (StringWriter stringWriter = new StringWriter(); JsonGenerator jsonGenerator = objectMapper.getFactory().createGenerator(stringWriter)) { objectMapper.writeValue(jsonGenerator, student); System.out.println("序列化结果: " + stringWriter); } catch (Exception e) { e.printStackTrace(); } }
|
手动序列化:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public static void main(String[] args) { Student student = new Student(); student.setName("张三"); student.setAge(20); student.setHobbies(Arrays.asList("阅读", "编程", "运动")); ObjectMapper objectMapper = new ObjectMapper(); try (StringWriter stringWriter = new StringWriter(); JsonGenerator jsonGenerator = objectMapper.getFactory().createGenerator(stringWriter)) { jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("name", student.getName()); jsonGenerator.writeNumberField("age", student.getAge()); jsonGenerator.writeArrayFieldStart("hobbies"); for (String hobby : student.getHobbies()) { jsonGenerator.writeString(hobby); } jsonGenerator.writeEndArray(); jsonGenerator.writeEndObject(); jsonGenerator.flush(); System.out.println("序列化结果: " + stringWriter); } catch (Exception e) { e.printStackTrace(); } }
|
4.2 反序列化
使用JsonParser类实现反序列化。
常用方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public abstract JsonToken nextToken() throws IOException;
public abstract String getCurrentName() throws IOException;
public boolean getBooleanValue() throws IOException;
public abstract int getIntValue() throws IOException;
public abstract long getLongValue() throws IOException;
public abstract float getFloatValue() throws IOException;
public abstract double getDoubleValue() throws IOException;
public abstract String getText() throws IOException;
public abstract JsonParser skipChildren() throws IOException;
|
自动反序列化:
java1 2 3 4 5 6 7 8 9 10 11
| public static void main(String[] args) { String json = "{\"name\":\"张三\",\"age\":20,\"hobbies\":[\"阅读\",\"编程\",\"运动\"]}"; ObjectMapper objectMapper = new ObjectMapper(); try (StringReader stringReader = new StringReader(json); JsonParser jsonParser = objectMapper.getFactory().createParser(stringReader)) { Student student = objectMapper.readValue(jsonParser, Student.class); System.out.println("反序列化结果: " + student.getName() + ", " + student.getAge() + ", " + student.getHobbies()); } catch (Exception e) { e.printStackTrace(); } }
|
手动反序列化:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public static void main(String[] args) { String json = "{\"name\":\"张三\",\"age\":20,\"hobbies\":[\"阅读\",\"编程\",\"运动\"]}"; ObjectMapper objectMapper = new ObjectMapper(); try (StringReader stringReader = new StringReader(json); JsonParser jsonParser = objectMapper.getFactory().createParser(stringReader)) { Student student = new Student(); jsonParser.nextToken(); while (jsonParser.nextToken() != JsonToken.END_OBJECT) { String fieldName = jsonParser.getCurrentName(); jsonParser.nextToken(); switch (fieldName) { case "name": student.setName(jsonParser.getText()); break; case "age": student.setAge(jsonParser.getIntValue()); break; case "hobbies": List<String> hobbies = new ArrayList<>(); while (jsonParser.nextToken() != JsonToken.END_ARRAY) { hobbies.add(jsonParser.getText()); } student.setHobbies(hobbies); break; default: jsonParser.skipChildren(); break; } } System.out.println("反序列化结果: " + student.getName() + ", " + student.getAge() + ", " + student.getHobbies()); } catch (Exception e) { e.printStackTrace(); } }
|
5 修改配置
修改ObjectMapper默认配置。
常用方法:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public ObjectMapper configure(SerializationFeature f, boolean state);
public ObjectMapper configure(DeserializationFeature f, boolean state);
public ObjectMapper setDefaultPropertyInclusion(JsonInclude.Include incl);
public ObjectMapper setDefaultPropertyInclusion(JsonInclude.Value incl);
public ObjectMapper setDateFormat(DateFormat dateFormat);
public ObjectMapper setTimeZone(TimeZone tz);
public ObjectMapper registerModule(Module module);
|
SerializationFeature常用取值:
- SerializationFeature.INDENT_OUTPUT:序列化时格式化输出,默认禁用,启用后格式化输出。
- SerializationFeature.WRITE_NULL_MAP_VALUES:序列化时保留值为null的键值对,默认启用,禁用后忽略值为null的键值对。
- SerializationFeature.WRITE_EMPTY_JSON_ARRAYS:序列化时保留空数组,默认启用,禁用后忽略空数组。
- SerializationFeature.WRITE_DATES_AS_TIMESTAMPS:序列化时将日期转为时间戳,默认启用,禁用后输出字符串。
DeserializationFeature常用取值:
- DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES:反序列化时如果存在对象未定义字段则抛出异常,默认启用,禁用后忽略未定义字段。
- DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT:反序列化时将空字符串转换为null,默认禁用,启用后将空字符串转换为null。
JsonInclude.Include常用取值:
- ALWAYS:处理所有属性,默认值。
- NON_NULL:排除属性值为null的属性。
- NON_ABSENT:排除属性值为null的属性,排除在逻辑上不存在的属性。
- NON_EMPTY:排除属性值为null的属性,排除在逻辑上不存在的属性,排除空字符串,排除空集合和空数组。
- NON_DEFAULT:排除属性值为默认值的属性。
示例:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static void main(String[] args) throws IOException { Student student = new Student(); student.setName("张三"); student.setAge(20); student.setHobbies(Arrays.asList("阅读", "编程", "运动")); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) .configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); objectMapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT); objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd")); String jsonString = objectMapper.writeValueAsString(student); System.out.println("序列化结果: " + jsonString); Student jsonObject = objectMapper.readValue(jsonString, Student.class); System.out.println("反序列化结果: " + jsonObject.getName() + ", " + jsonObject.getAge() + ", " + jsonObject.getHobbies()); }
|
6 字段处理
6.1 指定键名
6.1.1 双向可用
使用@JsonProperty注解指定Java字段名对应的JSON键名。
指定JSON键名:
java1 2 3 4
| public class Student { @JsonProperty("student_name") private String name; }
|
反序列化支持多个JSON键名,以最后的值为准:
java1 2 3 4 5
| public class Student { @JsonProperty("student_name") @JsonAlias({"student-name", "student.name"}) private String name; }
|
6.1.2 单向可用
只在序列化或反序列化生效:
- 使用@JsonGetter注解指定Java字段名对应的JSON键名,只在序列化生效。
- 使用@JsonSetter注解指定Java字段名对应的JSON键名,只在反序列化生效。
指定JSON键名:
java1 2 3 4 5 6 7 8 9 10 11
| public class Student { @JsonGetter("student_name") public String getName() { return name; }
@JsonSetter("student_name") public void setName(String name) { this.name = name; } }
|
6.2 忽略字段
使用@JsonIgnore注解忽略Java字段,不参与序列化和反序列化。
忽略Java字段:
java1 2 3 4
| public class Student { @JsonIgnore private String name; }
|
使用@JsonIgnoreProperties注解忽略Java字段,不参与序列化和反序列化。支持使用ignoreUnknown属性在反序列化时忽略未定义字段。
忽略Java字段:
java1 2 3 4 5 6
| @JsonIgnoreProperties(value = {"name"}, ignoreUnknown = true) public class Student { private String name; private int age; private List<String> hobbies; }
|
7 自定义处理
7.1 序列化
通过SimpleModule模块继承StdSerializer类实现自定义序列化:
StudentSerializer.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class StudentSerializer extends StdSerializer<Student> { protected StudentSerializer() { super(Student.class); }
@Override public void serialize(Student student, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeStartObject(); jsonGenerator.writeStringField("name", student.getName()); jsonGenerator.writeNumberField("age", student.getAge()); jsonGenerator.writeArrayFieldStart("hobbies"); for (String hobby : student.getHobbies()) { jsonGenerator.writeString(hobby); } jsonGenerator.writeEndArray(); jsonGenerator.writeEndObject(); } }
|
使用自定义序列化器:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public static void main(String[] args) { Student student = new Student(); student.setName("张三"); student.setAge(20); student.setHobbies(Arrays.asList("阅读", "编程", "运动")); StudentSerializer studentSerializer = new StudentSerializer(); SimpleModule module = new SimpleModule(); module.addSerializer(Student.class, studentSerializer); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(module); try { String json = objectMapper.writeValueAsString(student); System.out.println("序列化结果: " + json); } catch (IOException e) { e.printStackTrace(); } }
|
7.2 反序列化
通过SimpleModule模块继承StudentDeserializer类实现自定义反序列化:
StudentDeserializer.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class StudentDeserializer extends StdDeserializer<Student> { protected StudentDeserializer() { super(Student.class); }
@Override public Student deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { Student student = new Student(); while (jsonParser.nextToken() != JsonToken.END_OBJECT) { String fieldName = jsonParser.getCurrentName(); jsonParser.nextToken(); switch (fieldName) { case "name": student.setName(jsonParser.getText()); break; case "age": student.setAge(jsonParser.getIntValue()); break; case "hobbies": List<String> hobbies = new ArrayList<>(); while (jsonParser.nextToken() != JsonToken.END_ARRAY) { hobbies.add(jsonParser.getText()); } student.setHobbies(hobbies); break; default: jsonParser.skipChildren(); break; } } return student; } }
|
使用自定义反序列化器:
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static void main(String[] args) { String json = "{\"name\":\"张三\",\"age\":20,\"hobbies\":[\"阅读\",\"编程\",\"运动\"]}"; StudentDeserializer studentDeserializer = new StudentDeserializer(); SimpleModule module = new SimpleModule(); module.addDeserializer(Student.class, studentDeserializer); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModule(module); try { Student student = objectMapper.readValue(json, Student.class); System.out.println("反序列化结果: " + student.getName() + ", " + student.getAge() + ", " + student.getHobbies()); } catch (IOException e) { e.printStackTrace(); } }
|
条