JSON
参考自菜鸟教程:Java 中 JSON 的使用 | 菜鸟教程 (runoob.com)
JSON 简介
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
在javaScrip 一切皆为对象,任何js支持的类型,都可以用JSON来表示
JSON 格式
都以键值对的形式表示, 即 key: value
对象都用 {} 形式为: {"属性1":属性1的值,"属性2":属性2的值,"属性3":属性3的值}
数组(即使包含了多个对象)都用 [] , 形式为:
[{"对象1的属性1":对象1的属性1的值,"对象1的属性2":对象1的属性2的值},{"对象2的属性1":对象2的属性1的值,"对象2的属性2":对象2的属性2的值}]
JSON 转换
在JavaScript中:
1 2 3 4 5 6 7 8
|
JSON.stringify(user);
let user_text = '{"name":"mm" ,"age":"20","sex":"女"}'; JSON.parse(user2_text);
|
在Java第三方JSON处理库:
Java中并没有内置JSON的解析,因此使用JSON需要借助第三方类库。
下面是几个常用的 JSON 解析类库:
本人强烈推荐Jackson , 因为FastJson存在很多安全漏洞,并且线程不安全
Jackson
参考: 史上最全的Jackson框架使用教程_程序员资源社区的博客-CSDN博客
依赖导入
1 2 3 4 5 6 7
|
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.14.1</version> </dependency>
|
快速入门
Jackson 最常用的 API 就是基于”对象绑定” 的 ObjectMapper。下面是一个 ObjectMapper 的使用的简单示例。
准备一个实体类Person, 注意: Jackson的反序列化依赖于无参构造,所以实体类一定要有无参构造
1 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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| import java.util.Date;
public class Person {
private String name; private Integer age; private Date date; private int height;
public Person(String name, Integer age, Date date, int height) { this.name = name; this.age = age; this.date = date; this.height = height; }
public Person() { }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public Date getDate() { return date; }
public void setDate(Date date) { this.date = date; }
public int getHeight() { return height; }
public void setHeight(int height) { this.height = height; }
@Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", date=" + date + ", height=" + height + '}'; } }
|
进行单元测试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| ObjectMapper mapper = new ObjectMapper(); Person person = new Person("Tom", 40, new Date(), 170);
System.out.println("序列化..."); String jsonString = null; try {
jsonString = mapper.writeValueAsString(person); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(jsonString);
System.out.println("反序列化..."); Person deserializedPerson = null; try { deserializedPerson = mapper.readValue(jsonString, Person.class); } catch (JsonProcessingException e) { e.printStackTrace(); } System.out.println(deserializedPerson); }
|
打印结果:
1 2 3 4
| 序列化... {"name":"Tom","age":40,"date":1676962157783,"height":170} 反序列化... Person{name='Tom', age=40, date=Tue Feb 21 14:49:17 CST 2023, height=170}
|
总结:
ObjectMapper 通过 writeValue 系列方法将 java 对象序列化为 json,并将 json 存储成不同的格式,String(writeValueAsString),Byte Array(writeValueAsString),Writer, File,OutStream 和 DataOutput。
ObjectMapper 通过 readValue 系列方法从不同的数据源像 String , Byte Array, Reader,File,URL, InputStream 将 json 反序列化为 java 对象。
统一配置
在调用 writeValue 或调用 readValue 方法之前,往往需要设置 ObjectMapper 的相关配置信息。这些配置信息应用 java 对象的所有属性上。示例如下:
1 2 3 4 5 6 7 8 9 10
| mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT);
|
更多配置信息可以查看 Jackson 的 DeserializationFeature,SerializationFeature 和 Include。
注解个性化处理
Jackson 根据它的默认方式序列化和反序列化 java 对象,若根据实际需要,灵活的调整它的默认方式,可以使用 Jackson 的注解。常用的注解及用法如下。
| 注解 |
用法 |
| @JsonProperty |
用于属性,把属性的名称序列化时转换为另外一个名称。示例:@JsonProperty(“birth_date”) private Date birthDate |
| @JsonIgnore |
可用于字段、getter/setter、构造函数参数上,作用相同,都会对相应的字段产生影响。使相应字段不参与序列化和反序列化。 |
| @JsonIgnoreProperties |
该注解是类注解。该注解在Java类和JSON不完全匹配的时候使用。 |
| @JsonNaming |
类注解。序列化的时候该注解可将驼峰命名的字段名转换为下划线分隔的小写字母命名方式。反序列化的时候可以将下划线分隔的小写字母转换为驼峰命名的字段名。示例:@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) |
| @JsonFormat |
用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例:@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm”) public Date getBirthDate() |
| @JsonRootName |
类注解。需开启mapper.enable(SerializationFeature.WRAP_ROOT_VALUE),用于序列化时输出带有根属性名称的 JSON 串,形式如 {“root_name”:{“id”:1,”name”:”zhangsan”}}。但不支持该 JSON 串反序列化。 |
| @JsonPropertyOrder |
用于类, 和 @JsonProperty 的index属性类似,指定属性在序列化时 json 中的顺序 , 示例:@JsonPropertyOrder({ “birth_Date”, “name” }) public class Person |
| @JsonCreator |
用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。示例:@JsonCreator public Person(@JsonProperty(“name”)String name) {…} |
| @JsonAnySetter |
用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中 @JsonAnySetter public void set(String key, Object value) { map.put(key, value); } |
| @JsonAnyGetter |
用于方法 ,获取所有未序列化的属性 public Map<String, Object> any() { return map; } |
属性可视化
JackSon 默认不是所有的属性都可以被序列化和反序列化。默认的属性可视化的规则如下:
- 若该属性修饰符是 public,该属性可序列化和反序列化。
- 若属性的修饰符不是 public,但是它的 getter 方法和 setter 方法是 public,该属性可序列化和反序列化。因为 getter 方法用于序列化, 而 setter 方法用于反序列化。
- 若属性只有 public 的 setter 方法,而无 public 的 getter 方 法,该属性只能用于反序列化。
若想更改默认的属性可视化的规则,需要调用 ObjectMapper 的方法 setVisibility。
下面的示例使修饰符为 protected 的属性 name 也可以序列化和反序列化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static class People { public int age; protected String name; } @Test public void test7() throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); People people = new People(); people.name = "Tom"; people.age = 40; System.out.println("序列化"); String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(people); System.out.println(jsonString); System.out.println("反序列化"); People deserializedPerson = mapper.readValue(jsonString, People.class); System.out.println(deserializedPerson); }
|
属性过滤
在将 Java 对象序列化为 json 时 ,有些属性需要过滤掉,不显示在 json 中 ,除了使用 @JsonIgnore 过滤单个属性或用 @JsonIgnoreProperties 过滤多个属性之外, Jackson 还有通过代码控制的方式。
自定编写一个属性过滤器:
1 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
| @JsonFilter("myFilter") public interface MyFilter { } @Test public void test8() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(Person.class, MyFilter.class); SimpleBeanPropertyFilter newFilter = SimpleBeanPropertyFilter.serializeAllExcept("age"); SimpleBeanPropertyFilter newFilter2 = new SimpleBeanPropertyFilter() { @Override public void serializeAsField(Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer) throws Exception { if (!writer.getName().equals("age")) { writer.serializeAsField(pojo, jgen, provider); } } }; FilterProvider filterProvider = new SimpleFilterProvider().addFilter("myFilter", newFilter); Person person = new Person(); person.setName("Tom"); person.setAge(40); person.setDate(new Date()); String jsonString = mapper.setFilterProvider(filterProvider).writeValueAsString(person); System.out.println(jsonString); }
|
运行结果:
1
| {"name":"Tom","date":1595780842754}
|
日期处理
不同类型的日期类型,JackSon 的处理方式也不同。
普通日期
对于日期类型为 java.util.Calendar, java.util.GregorianCalendar, java.sql.Date, java.util.Date, java.sql.Timestamp,若不指定格式,在 json 文件中将序列化为 long 类型的数据。显然这种默认格式,可读性差,转换格式是必要的。
JackSon 有很多方式转换日期格式。
- 注解方式,使用
@JsonFormat 注解指定日期格式。
- ObjectMapper 方式,调用 ObjectMapper 的方法
setDateFormat,将序列化为指定格式的 string 类型的数据。
Local日期
对于日期类型为 java.time.LocalDate, java.time.LocalDateTime,还需要添加代码 mapper.registerModule(new JavaTimeModule()),同时添加相应的依赖 jar 包。
导入依赖:
1 2 3 4 5
| <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.9.1</version> </dependency>
|
对于 Jackson 2.5 以下版本,需要添加代码 mapper.registerModule(new JSR310Module ())。使用示例:
1 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 37 38
| @Data public static class Student { private String name; private LocalDateTime date; } @Test public void test4() throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(JavaTimeModule()); Student student = new Student(); student.setName("Tom"); student.setDate(LocalDateTime.now()); System.out.println("序列化"); String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(student); System.out.println(jsonString); System.out.println("反序列化"); Student deserializedPerson = mapper.readValue(jsonString, Student.class); System.out.println(deserializedPerson); } private Module JavaTimeModule() { JavaTimeModule module = new JavaTimeModule(); String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; String DATE_FORMAT = "yyyy-MM-dd"; String TIME_FORMAT = "HH:mm:ss"; module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT))); module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_FORMAT))); module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern((TIME_FORMAT)))); module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT))); module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DATE_FORMAT))); module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(TIME_FORMAT))); return module; }
|
Joda日期
对于日期类型为 org.joda.time.DateTime,还需要添加代码 mapper.registerModule(new JodaModule()),同时添加相应的依赖 jar 包
1 2 3 4 5
| <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-joda</artifactId> <version>2.9.1</version> </dependency>
|
对象集合
Jackson 对泛型反序列化也提供很好的支持
List
对于 List 类型 ,可以调用 constructCollectionType 方法来序列化,也可以构造 TypeReference 来序列化。
使用示例:
- 构造mapper和数据:
1 2 3 4 5 6 7 8 9 10
| ObjectMapper mapper = new ObjectMapper(); List<Person> list = new ArrayList<>(); for (int i = 0; i < 3; i++) { Person person = new Person(); person.setName("Tom"); person.setAge(new Random().nextInt(100)); person.setDate(new Date()); list.add(person); }
|
序列化
1 2 3
| System.out.println("序列化..."); String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(list); System.out.println(jsonInString);
|
通过调用 constructCollectionType 方法来反序列化
1 2 3 4
| System.out.println("反序列化:使用 javaType"); CollectionType javaType = mapper.getTypeFactory().constructCollectionType(List.class, Person.class); List<Person> personList = mapper.readValue(jsonInString, javaType); System.out.println(personList);
|
构造 TypeReference 来反序列化
1 2 3
| System.out.println("反序列化:使用 TypeReference"); List<Person> personList2 = mapper.readValue(jsonInString, new TypeReference<List<Person>>() {}); System.out.println(personList2);
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 序列化... [ { "name" : "Tom", "age" : 94, "date" : 1676964663518, "height" : 0 }, { "name" : "Tom", "age" : 5, "date" : 1676964663518, "height" : 0 }, { "name" : "Tom", "age" : 60, "date" : 1676964663518, "height" : 0 } ] 反序列化:使用 javaType [Person{name='Tom', age=94, date=Tue Feb 21 15:31:03 CST 2023, height=0}, Person{name='Tom', age=5, date=Tue Feb 21 15:31:03 CST 2023, height=0}, Person{name='Tom', age=60, date=Tue Feb 21 15:31:03 CST 2023, height=0}] 反序列化:使用 TypeReference [Person{name='Tom', age=94, date=Tue Feb 21 15:31:03 CST 2023, height=0}, Person{name='Tom', age=5, date=Tue Feb 21 15:31:03 CST 2023, height=0}, Person{name='Tom', age=60, date=Tue Feb 21 15:31:03 CST 2023, height=0}]
|
Map
对于 map 类型, 与 List 的实现方式相似。
1 2 3 4 5 6 7 8 9 10
| ObjectMapper mapper = new ObjectMapper(); Map<String, Person> map = new HashMap<>(); for (int i = 0; i < 3; i++) { Person person = new Person(); person.setName("Tom"); person.setAge(new Random().nextInt(100)); person.setDate(new Date()); map.put("key" + i, person); }
|
1
| String jsonInString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
|
- 通过调用
constructCollectionType 方法来反序列化
1 2 3 4 5
| System.out.println("反序列化: 使用 javaType");
MapType javaType = mapper.getTypeFactory().constructMapType(HashMap.class, String.class, Person.class); Map<String, Person> personMap = mapper.readValue(jsonInString, javaType); System.out.println(personMap);
|
1 2 3
| System.out.println("反序列化: 使用 TypeReference"); Map<String, Person> personMap2 = mapper.readValue(jsonInString, new TypeReference<Map<String, Person>>() {}); System.out.println(personMap2);
|
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 序列化... { "key1" : { "name" : "Tom", "age" : 57, "date" : 1676964964761, "height" : 0 }, "key2" : { "name" : "Tom", "age" : 76, "date" : 1676964964761, "height" : 0 }, "key0" : { "name" : "Tom", "age" : 80, "date" : 1676964964760, "height" : 0 } } 反序列化: 使用 javaType {key1=Person{name='Tom', age=57, date=Tue Feb 21 15:36:04 CST 2023, height=0}, key2=Person{name='Tom', age=76, date=Tue Feb 21 15:36:04 CST 2023, height=0}, key0=Person{name='Tom', age=80, date=Tue Feb 21 15:36:04 CST 2023, height=0}} 反序列化: 使用 TypeReference {key1=Person{name='Tom', age=57, date=Tue Feb 21 15:36:04 CST 2023, height=0}, key2=Person{name='Tom', age=76, date=Tue Feb 21 15:36:04 CST 2023, height=0}, key0=Person{name='Tom', age=80, date=Tue Feb 21 15:36:04 CST 2023, height=0}}
|
Array 和 Collection 的处理与 List,Map 相似,这里不再赘述。
树模型处理
Jackson 也提供了树模型(tree model)来生成和解析 json。若想修改或访问 json 部分属性,树模型是不错的选择。树模型由 JsonNode 节点组成。程序中常常使用 ObjectNode,ObjectNode 继承于 JsonNode,示例如下:
1 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
| ObjectMapper mapper = new ObjectMapper(); ObjectNode personNode = mapper.createObjectNode(); personNode.put("name", "Tom"); personNode.put("age", 40); ObjectNode addressNode = mapper.createObjectNode(); addressNode.put("zip", "000000"); addressNode.put("street", "Road NanJing"); personNode.set("address", addressNode); System.out.println("构建 ObjectNode:\n" + personNode.toString()); JsonNode searchNode = personNode.path("name"); System.out.println("查找子节点 name:\n" + searchNode.asText()); ((ObjectNode) personNode).remove("address"); System.out.println("删除后的 ObjectNode:\n" + personNode.toString()); JsonNode rootNode = mapper.readTree(personNode.toString()); System.out.println("Json 转 JsonNode:\n" + rootNode); Person person = mapper.treeToValue(personNode, Person.class); System.out.println("JsonNode 转对象:\n" + person); JsonNode node = mapper.valueToTree(person); System.out.println("对象转 JsonNode:\n" + node);
|
自定义序列类(不常用)
当 Jackson 默认序列化和反序列化的类不能满足实际需要,可以自定义新的序列化和反序列化的类。
自定义序列化类:
自定义的序列化类需要直接或间接继承 StdSerializer 或 JsonSerializer,同时需要利用 JsonGenerator 生成 json,重写方法 serialize(),
示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static class CustomSerializer extends StdSerializer<Person> { protected CustomSerializer() { super(Person.class); } @Override public void serialize(Person person, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeStartObject(); jgen.writeNumberField("age", person.getAge()); jgen.writeStringField("name", person.getName()); jgen.writeStringField("msg", "已被自定义序列化"); jgen.writeEndObject(); } }
|
JsonGenerator 有多种 write 方法以支持生成复杂的类型的 json,比如 writeArray,writeTree 等 。若想单独创建 JsonGenerator,可以通过 JsonFactory() 的 createGenerator。
自定义反序列化类:
自定义的反序列化类需要直接或间接继承 StdDeserializer 或 StdDeserializer,同时需要利用 JsonParser 读取 json,重写方法 deserialize,示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public static class CustomDeserializer extends StdDeserializer<Person> { protected CustomDeserializer() { super(Person.class); } @Override public Person deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonNode node = jp.getCodec().readTree(jp); Person person = new Person(); int age = (Integer) ((IntNode) node.get("age")).numberValue(); String name = node.get("name").asText(); person.setAge(age); person.setName(name); return person; } }
|
JsonParser 提供很多方法来读取 json 信息, 如 isClosed(), nextToken(), getValueAsString()等。若想单独创建 JsonParser,可以通过 JsonFactory() 的 createParser。
使用自定义序列类
定义好自定义序列化类和自定义反序列化类,若==想在程序中调用它们,还需要注册到 ObjectMapper 的 Module,==示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule("myModule"); module.addSerializer(new CustomSerializer()); module.addDeserializer(Person.class, new CustomDeserializer()); mapper.registerModule(module);
Person person = new Person(); person.setName("Tom"); person.setAge(40); person.setDate(new Date()); System.out.println("序列化"); String jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
System.out.println(jsonString); System.out.println("反序列化"); Person deserializedPerson = mapper.readValue(jsonString, Person.class);
|
封装工具类
根据上述知识点,我们可以对Jackson进行再次封装成一个工具类,方便我们进行使用:
本工具类拥有mapperFactory系列方法用于生成mapper对象, 可以进行自定义的配置, 同时, 工具类还提供了很多简便的转换json的方法
JsonUtility.java
1 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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
| import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import java.text.SimpleDateFormat; import java.util.Collection;
public class JsonUtility {
private static final String failJsonInfo = "{\"code\":\"500\", \"msg\": \"Conversion failure\"}";
private void serializationConfig(ObjectMapper mapper){ this.serializationConfig(mapper,"yyyy-MM-dd HH:mm:ss", false, false); } private void serializationConfig(ObjectMapper mapper, String dataFormat){ this.serializationConfig(mapper,dataFormat, false, false); } private void serializationConfig(ObjectMapper mapper, boolean isIgnoreNull, boolean isIgnoreDefault){ this.serializationConfig(mapper,"yyyy-MM-dd HH:mm:ss", isIgnoreNull, isIgnoreDefault); }
private void serializationConfig(ObjectMapper mapper, String dataFormat, boolean isIgnoreNull, boolean isIgnoreDefault){ mapper.setDateFormat(new SimpleDateFormat(dataFormat)); if (isIgnoreNull) { mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); } if (isIgnoreDefault){ mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT); } }
private void deSerializationConfig(ObjectMapper mapper, boolean isIgnoreUnknownProperty){ if (isIgnoreUnknownProperty){ mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } else { mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); } }
public ObjectMapper mapperFactory(){ ObjectMapper mapper = new ObjectMapper(); this.serializationConfig(mapper); return mapper; } public ObjectMapper mapperFactory(String dataFormat){ ObjectMapper mapper = new ObjectMapper(); this.serializationConfig(mapper, dataFormat); return mapper; }
public ObjectMapper mapperFactory(boolean isIgnoreNull,boolean isIgnoreDefault){ ObjectMapper mapper = this.mapperFactory("yyyy-MM-dd HH:mm:ss", isIgnoreNull, isIgnoreDefault, true); return mapper; }
public ObjectMapper mapperFactory(String dataFormat,boolean isIgnoreNull,boolean isIgnoreDefault){ ObjectMapper mapper = this.mapperFactory(dataFormat, isIgnoreNull, isIgnoreDefault, true); return mapper; } public ObjectMapper mapperFactory(String dataFormat,boolean isIgnoreNull,boolean isIgnoreDefault,boolean isIgnoreUnknownProperty){ ObjectMapper mapper = new ObjectMapper(); this.serializationConfig(mapper, dataFormat, isIgnoreNull, isIgnoreDefault); this.deSerializationConfig(mapper, isIgnoreUnknownProperty); return mapper; }
public String jsonParser_ByObject(ObjectMapper mapper, Object object){ return this.jsonParser_ByObject(mapper, object,false); }
public String jsonParser_ByObject(ObjectMapper mapper, Object object, boolean isFormat){ String jsonString = JsonUtility.failJsonInfo; try { if (isFormat){ jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object); } else{ jsonString = mapper.writeValueAsString(object); } } catch (JsonProcessingException e) { System.err.println(object+"转换json失败!"); e.printStackTrace(); } return jsonString; }
public Object objectParser_ByJSON(ObjectMapper mapper, String jsonString, Class aClass){ Object o = null; try { o = mapper.readValue(jsonString, aClass); } catch (JsonProcessingException e) { System.err.println(jsonString+"解析失败!"); e.printStackTrace(); } return o; }
public <E> Collection collectionParser_ByJSON(ObjectMapper mapper, String jsonString, TypeReference<E> type){ Collection collection = null; try { collection = (Collection) mapper.readValue(jsonString, type); } catch (JsonProcessingException e) { System.err.println(jsonString+"解析失败!指定解析的类型为:"+type); e.printStackTrace(); } return collection; }
public JsonNode readJsonToNode(ObjectMapper mapper, String jsonString){ JsonNode jsonNode = null; try { jsonNode = mapper.readTree(jsonString); } catch (JsonProcessingException e) { System.err.println(jsonString+"解析失败!"); e.printStackTrace(); } return jsonNode; }
public Object readNodeToObject(ObjectMapper mapper, JsonNode jsonNode, Class aClass){ Object object = null; try { object = mapper.treeToValue(jsonNode, aClass); } catch (JsonProcessingException e) { System.err.println(jsonNode+"节点转换失败!"); e.printStackTrace(); } return object; }
public void setAttribute(ObjectNode node, String key, Object value) throws Exception { String type = null; type = value instanceof String ? "String" : type; type = value instanceof Integer ? "int" : type; type = value instanceof Double ? "double" : type; type = value instanceof Boolean ? "boolean" : type; if (type == null){ throw new Exception("value 不能为 null !"); } switch (type){ case "String": { node.put(key, (String) value); break; } case "int": { node.put(key, (Integer) value); break; } case "double": { node.put(key, (Double) value); break; } case "boolean": { node.put(key, (Boolean) value); break; } default: { throw new Exception("value参数类型错误!只能为int, double, String, boolean"); } } }
public void setNodeAttribute(ObjectNode node, String key, ObjectNode value){ node.set(key, value); }
public void removeAttribute(ObjectNode objectNode, String key){ objectNode.remove(key); }
public JsonNode findNode(JsonNode jsonNode, String key){ return jsonNode.path(key); } }
|
FastJson
依赖导入
1 2 3 4 5 6
| <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
|
流程说明:
java变量 <--> JSON对象 <--> 字符串
将java变量转换为JSON
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public void testJson() { JSONObject object = new JSONObject(); object.put("string","string"); object.put("int",2); object.put("boolean",true); List<Integer> integers = Arrays.asList(1,2,3); object.put("list",integers); object.put("null",null); System.out.println(object);
}
|
将JSON转换为java变量
1 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
| public void testJson2() { JSONObject object = JSONObject .parseObject("{\"boolean\":true,\"string\":\"string\",\"list\":[1,2,3],\"int\":2}"); String s = object.getString("string"); System.out.println(s); int i = object.getIntValue("int"); System.out.println(i); boolean b = object.getBooleanValue("boolean"); System.out.println(b); List<Integer> integers = JSON.parseArray(object.getJSONArray("list").toJSONString(),Integer.class); integers.forEach(System.out::println); System.out.println(object.getString("null")); }
|
方法使用
| 方法 |
作用 |
JSON.parseObject(String) |
将字符串解析为 JSON 对象 |
JSON.parseArray(String) |
将从字符串解析为 JSON 数组 |
JSON.toJSONString(obj/array) |
将 JSON 对象或 JSON 数组转化为字符串 |
实例:
1 2 3 4 5 6 7 8
| JSONObject obj = JSON.parseObject("{\"runoob\":\"菜鸟教程\"}");
JSONArray arr = JSON.parseArray("[\"菜鸟教程\",\"RUNOOB\"]\n");
String objStr = JSON.toJSONString(obj);
String arrStr = JSON.toJSONString(arr);
|