本文中代码中为了使字符串的Json阅读好看,采用了JDK13新增的 Text Blocks
测试代码均在JDK 17 环境中执行,实际使用场景无需使用最新的JDK
同时采用了lombok简化pojo
Jackson
Jackson为spring的默认json序列化工具
相关学习地址:
https://hub.fastgit.org/FasterXML/jackson-docs
https://www.baeldung.com/jackson
https://www.baeldung.com/jackson-annotations
依赖
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.0</version> </dependency>
基本使用
Jackson的核心处理对象是ObjectMapper
前置对象和初始化
ObjectMapper objectMapper = new ObjectMapper(); @AllArgsConstructor @NoArgsConstructor @Data public static class TestVo{ private String name; private int age; private Date time; }
对象与json字符串互转
@Test public void test_object() throws JsonProcessingException { TestVo vo = new TestVo("young", 20, new Date()); System.out.println(objectMapper.writeValueAsString(vo)); // {"name":"young","age":20,"time":1634723171329} String jsonStr = """ { "name":"young", "age":20, "time":1634722851440 } """; System.out.println(objectMapper.readValue(jsonStr, TestVo.class)); // TestJackson.TestVo(name=young, age=20, time=Wed Oct 20 17:40:51 CST 2021) }
集合与json字符串互转
@Test public void test_collection() throws JsonProcessingException { List<TestVo> collect = IntStream.rangeClosed(1, 5) .mapToObj(e -> new TestVo(RandomStringUtils.randomAlphabetic(5, 10), e, new Date())) .collect(Collectors.toList()); String jsonStr = objectMapper.writeValueAsString(collect); System.out.println(jsonStr); // [{"name":"lPpvlLqfz","age":1,"time":1634723691263},{"name":"oMmvjF","age":2,"time":1634723691263},{"name":"TwVcLW","age":3,"time":1634723691263},{"name":"pjbcZ","age":4,"time":1634723691263},{"name":"SznBEwCz","age":5,"time":1634723691263}] List<TestVo> testVos = objectMapper.readValue(jsonStr, new TypeReference<List<TestVo>>() {}); System.out.println(testVos); // [TestJackson.TestVo(name=lPpvlLqfz, age=1, time=Wed Oct 20 17:54:51 CST 2021), TestJackson.TestVo(name=oMmvjF, age=2, time=Wed Oct 20 17:54:51 CST 2021), TestJackson.TestVo(name=TwVcLW, age=3, time=Wed Oct 20 17:54:51 CST 2021), TestJackson.TestVo(name=pjbcZ, age=4, time=Wed Oct 20 17:54:51 CST 2021), TestJackson.TestVo(name=SznBEwCz, age=5, time=Wed Oct 20 17:54:51 CST 2021)] }
json对象操作
@Test public void test_jsonObject() throws JsonProcessingException { String json = """ { "name":"young", "age":20, "addressInfoList": [ { "address":"a" },{ "address":"b" } ] } """; JsonNode jsonNode = objectMapper.readTree(json); System.out.println(jsonNode.get("name").asText()); System.out.println(jsonNode.get("age").asInt()); JsonNode addressInfoList = jsonNode.get("addressInfoList"); Iterator<JsonNode> elements = addressInfoList.elements(); while (elements.hasNext()) { System.out.println(elements.next().get("address").asText()); } }
常用全局配置
输出格式化
默认情况下,json的输出是没有缩进的,可以通过配置进行开启,以下两种方法任选一个即可
objectMapper.enable(SerializationFeature.INDENT_OUTPUT); objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);
@Test public void test_INDENT_OUTPUT() throws JsonProcessingException { TestVo vo = new TestVo("young", 20, new Date()); ObjectMapper om = new ObjectMapper(); om.enable(SerializationFeature.INDENT_OUTPUT); System.out.println(om.writeValueAsString(vo)); /* { "name" : "young", "age" : 20, "time" : 1641353231867 } */ }
禁用未知属性错误
反序列化时,如果遇到未知的属性(没有属性,没有setter,没有handler处理)就会抛出异常UnrecognizedPropertyException
。
@Data public static class TestVo2{ private String name ; } @Test public void test_UnrecognizedProperty() throws JsonProcessingException { String json = """ { "name":"young", "age":15 } """; TestVo2 s = objectMapper.readValue(json,TestVo2.class); System.out.println(s); } com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "age" (class com.example.TestJackson$TestVo2), not marked as ignorable (one known property: "name"]) at [Source: (String)"{ "name":"young", "age":15 } "; line: 3, column: 13] (through reference chain: com.example.TestJackson$TestVo2["age"])
可以通过以下代码进行禁用
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
@Test public void test_UnrecognizedProperty() throws JsonProcessingException { String json = """ { "name":"young", "age":15 } """; objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); TestVo2 s = objectMapper.readValue(json,TestVo2.class); System.out.println(s); // TestJackson.TestVo2(name=young) }
允许序列化空对象
Jackson在执行序列化操作时,默认的字段属性发现规则是,所有被public修饰的字段、所有被public修饰的getter。没有可序列化的属性时,就会抛出异常InvalidDefinitionException: No serializer found for class...
。
public static class TestVo2{ private String name = "young"; } @Test public void test_EmptyBean() throws JsonProcessingException { TestVo2 testVo2 = new TestVo2(); String s = objectMapper.writeValueAsString(testVo2); System.out.println(s); } com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.example.TestJackson$TestVo2 and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)
可以通过以下代码进行禁用
objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
public static class TestVo2{ private String name = "young"; } @Test public void test_EmptyBean() throws JsonProcessingException { TestVo2 testVo2 = new TestVo2(); objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); String s = objectMapper.writeValueAsString(testVo2); System.out.println(s); // {} }
将空字符串反序列为null POJO
默认情况下,空字符串不能反序列化为null对象,会抛出异常
@Data public static class TestVo2{ private String name ; } @Test public void test_EmptyString() throws JsonProcessingException { String json = """ { "aaa":"" } """; Map<String,TestVo2> map = objectMapper.readValue(json, new TypeReference<Map<String,TestVo2>>() { }); System.out.println(map); } com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot coerce empty String ("") to `com.example.TestJackson$TestVo2` value (but could if coercion was enabled using `CoercionConfig`) at [Source: (String)"{ "aaa":"" } "; line: 2, column: 11] (through reference chain: java.util.LinkedHashMap["aaa"])
可以通过以下代码进行禁用
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
@Test public void test_EmptyString() throws JsonProcessingException { String json = """ { "aaa":"" } """; objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); Map<String,TestVo2> map = objectMapper.readValue(json, new TypeReference<Map<String,TestVo2>>() { }); System.out.println(map); // {aaa=null} }
常用注解
@JsonIgnore
作用在字段上,使jackson在序列化与反序列化时忽略该属性
@Data public static class TestVo3{ private String name; @JsonIgnore private Date date; } @Test public void test_JsonIgnore() throws JsonProcessingException { TestVo3 testVo3 = new TestVo3(); testVo3.setDate(new Date()); testVo3.setName("hahaha"); String s = objectMapper.writeValueAsString(testVo3); System.out.println(s); // {"name":"hahaha"} String json = """ { "name":"hahaha", "date":"1641353231867" } """; TestVo3 value = objectMapper.readValue(json, TestVo3.class); System.out.println(value); // TestJackson.TestVo3(name=hahaha, date=null) }
@JsonProperty
作用于类上,可以忽略指定属性的序列化与反序列化,如
@JsonIgnoreProperties({"name","age","title"})
也可以注明过滤掉未知的属性,如
@JsonIgnoreProperties(ignoreUnknown=true)
@JsonIgnoreProperties(value = {"name"}) @Data public static class TestVo3{ private String name; private Date date; } @Test public void test_JsonProperty() throws JsonProcessingException { TestVo3 testVo3 = new TestVo3(); testVo3.setDate(new Date()); testVo3.setName("hahaha"); String s = objectMapper.writeValueAsString(testVo3); System.out.println(s); // {"date":1641354740292} String json = """ { "name":"hahaha", "date":"1641353231867" } """; TestVo3 value = objectMapper.readValue(json, TestVo3.class); System.out.println(value); // TestJackson.TestVo3(name=null, date=Wed Jan 05 11:27:11 CST 2022) }
@JsonProperty
作用在字段上,可以将json与实体中的字段进行映射,如
@Data public static class TestVo3{ @JsonProperty("userName") private String name; private Date date; } @Test public void test_JsonProperty() throws JsonProcessingException { TestVo3 testVo3 = new TestVo3(); testVo3.setDate(new Date()); testVo3.setName("hahaha"); String s = objectMapper.writeValueAsString(testVo3); System.out.println(s); // {"date":1641354824675,"userName":"hahaha"} String json = """ { "userName":"hahaha", "date":"1641353231867" } """; TestVo3 value = objectMapper.readValue(json, TestVo3.class); System.out.println(value); // TestJackson.TestVo3(name=hahaha, date=Wed Jan 05 11:27:11 CST 2022) }
@JsonFormat
作用为字段上,在jackson进行序列化时对字段值进行格式化,如
@Data public static class TestVo3{ @JsonProperty("userName") private String name; @JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss",timezone = "GMT+8") private Date date; } @Test public void test_JsonFormat() throws JsonProcessingException { TestVo3 testVo3 = new TestVo3(); testVo3.setDate(new Date()); testVo3.setName("hahaha"); String s = objectMapper.writeValueAsString(testVo3); System.out.println(s); // {"date":"2022-01-05 11-55-49","userName":"hahaha"} }
@JsonDeserialize
设置类或字段的反序列化操作
创建反序列化处理器
public class TestJsonDeserializer extends JsonDeserializer { @Override public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { String text = jsonParser.getText(); if (StringUtils.isNotBlank(text)){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { return simpleDateFormat.parse(text); } catch (ParseException e) { e.printStackTrace(); return null; } } return null; } }
在字段上标注要使用的反序列化处理器
@Data public static class TestVo3{ private String name; @JsonDeserialize(using = TestJsonDeserializer.class) private Date date; }
调用readValue
@Test public void test_JsonDeserialize() throws JsonProcessingException { String json = """ { "name":"hahaha", "date":"2000-10-01 10:00:00" } """; TestVo3 value = objectMapper.readValue(json, TestVo3.class); System.out.println(value); // TestJackson.TestVo3(name=hahaha, date=Sun Oct 01 10:00:00 CST 2000) }
@JsonSerialize
设置类或字段的自定义序列化操作,与反序列化使用方法类似
Gson
Google提供的用于处理json序列化和反序列化的工具
依赖
<dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.9.0</version> </dependency>
创建实例
创建Gson对象有两种方式
Gson gson = new Gson();
GsonBuilder builder = new GsonBuilder(); Gson gson = build.create();
对象序列化与反序列化
定义一个对象
@Data @AllArgsConstructor @NoArgsConstructor static class TestVo{ private String name; private int age; private String birth; }
Gson gson = new Gson(); TestVo vo = new TestVo("young", 10, LocalDate.now().toString()); String json = gson.toJson(vo); // {"name":"young","age":10,"birth":"2022-05-18"} System.out.println(json); TestVo testVo = gson.fromJson(json, TestVo.class); // TestVo(name=young, age=10, birth=2022-05-18) System.out.println(testVo);
格式化输出
GsonBuilder builder = new GsonBuilder(); Gson gson = builder.setPrettyPrinting().create(); TestVo vo = new TestVo("young", 10, LocalDate.now().toString()); String json = gson.toJson(vo); System.out.println(json);
{ "name": "young", "age": 10, "birth": "2022-05-18" }
数组
[ { "name": "Alex", "id": 1 }, { "name": "Brian", "id": 2 }, { "name": "Charles", "id": 3 } ]
@Data @AllArgsConstructor @NoArgsConstructor static class User { private String name; private Integer id; }
User[] users = new Gson().fromJson(jsonArr, User[].class); for (User user : users) { System.out.println(user); }
List<User> userList = new Gson().fromJson(jsonArr, new TypeToken<List<User>>(){}.getType()); for (User user : userList) { System.out.println(user); }
Null值处理
Gson默认会忽略空对象字段,如需让Json输入null字段,需进行设置
Gson gson = new GsonBuilder().serializeNull().create();
版本支持
@Since注解:表示属性从哪个版本开始支持
@Until注解:表示属性从哪个版本开始移除
@Data @AllArgsConstructor @NoArgsConstructor static class TestVo{ @Since(1.0) private String name; @Since(1.1) private int age; @Since(1.2) @Until(1.4) private String birth; }
序列化
Gson gson = new GsonBuilder().setVersion(1.0).create(); TestVo vo = new TestVo("young", 10, LocalDate.now().toString()); // {"name":"young"} System.out.println(gson.toJson(vo)); gson = new GsonBuilder().setVersion(1.1).create(); // {"name":"young","age":10} System.out.println(gson.toJson(vo)); gson = new GsonBuilder().setVersion(1.2).create(); // {"name":"young","age":10,"birth":"2022-05-18"} System.out.println(gson.toJson(vo)); gson = new GsonBuilder().setVersion(1.3).create(); // {"name":"young","age":10,"birth":"2022-05-18"} System.out.println(gson.toJson(vo)); gson = new GsonBuilder().setVersion(1.4).create(); // {"name":"young","age":10} System.out.println(gson.toJson(vo));
反序列化
Gson gson = new GsonBuilder().setVersion(1.3).create(); // {"name":"young","age":10,"birth":"2022-05-18"} String json = gson.toJson(vo); gson = new GsonBuilder().setVersion(1.0).create(); // TestVo(name=young, age=0, birth=null) System.out.println(gson.fromJson(json,TestVo.class));
字段名映射
@SerializedName
- value:序列化或反序列化是所需的字段名称
- alternate:反序列化时字段的代替名称,如果有多个字段匹配一个属性,则Gson将使用最后处理的那个
@Data @AllArgsConstructor @NoArgsConstructor static class User { @SerializedName(value = "newName",alternate = {"name1","name2"}) private String name; @SerializedName(value = "newId",alternate = {"id1","id2"}) private Integer id; }
User young = new User("young", 1); Gson gson = new Gson(); // {"newName":"young","newId":1} System.out.println(gson.toJson(young)); String json = "{\"name2\":\"young\",\"id1\":10}"; // User(name=young, id=10) System.out.println(gson.fromJson(json, User.class)); json = "{\"name2\":\"young\",\"newId\":5,\"id1\":10}"; // User(name=young, id=10) System.out.println(gson.fromJson(json, User.class)); json = "{\"name2\":\"young\",\"id1\":10,\"newId\":5}"; // User(name=young, id=5) System.out.println(gson.fromJson(json, User.class));
排除或忽略字段
@Expose
@Expose注解可以用于指定序列化或反序列化时是否需要进行排除
- serialize:序列化时是否包含该字段,true为包含
- deserialize:反序列化是是否包含该字段,true为包含
同时需要开启该注解,开启后,未标记该标签的字段不会被序列化和反序列化
@Data @AllArgsConstructor @NoArgsConstructor static class User { @Expose(serialize = false) private String name; private Integer id; }
User young = new User("young", 1); // {"name":"young","id":1} System.out.println(new Gson().toJson(young)); // {} System.out.println(new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(young));
transient关键字
给属性增加transient关键字修饰,则该字段既不参与序列化也不参与反序列化
根据修饰符排除
excludeFieldsWithModifiers()方法可以排除指定修饰符的字段
new GsonBuilder().excludeFieldsWithModifiers(Modifier.STATIC).create();
自定义排除策略
创建自定义排除策略的类,并且实现ExclusionStrategy
接口
// 自定义注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface GsonExclude { } // 自定义排除策略 public class MyExclusionStrategy implements ExclusionStrategy { @Override public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(GsonExclude.class)!=null; } @Override public boolean shouldSkipClass(Class<?> clazz) { return clazz.isAnnotationPresent(GsonExclude.class); } }
当shouldSkipField或shouldSkipClass任一条件满足时,序列化和反序列化时将对属性进行排除
@Data @AllArgsConstructor @NoArgsConstructor static class User { @GsonExclude private String name; private Integer id; } @Test public void testExclusionStrategy(){ Gson gson = new GsonBuilder().setExclusionStrategies(new MyExclusionStrategy()).create(); // {"id":2} System.out.println(gson.toJson(new User("young", 2))); }
GsonBuilder
PrettyPrinting 格式化JSON
FieldNamingPolicy 命名标准
在序列化时对JSON字段名称提供集中标准命名约定
如果使用了@SerializedName,那么@SerializedName对应的字段将覆盖FieldNamingPolicy
- FieldNamingPolicy.IDENTITY:默认策略,字段名称不变
- FieldNamingPolicy.LOWER_CASE_WITH_DASHES:将Java字段名称从驼峰大小写形式改为小写的字段名称,每个单词之间用破折号(-)分隔
- FieldNamingPolicy.LOWER_CASE_WITH_DOTS:将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用点(.)分隔
- FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES:将Java字段名称从其驼峰大小写形式修改为小写的字段名称,其中每个单词都用下划线(_)分隔
- FieldNamingPolicy.UPPER_CAMEL_CASE:确保序列化为JSON格式的Java字段名称的第一个“字母”大写
- FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES:确保在将Java字段名称的第一个“字母”序列化为JSON格式时将其大写,并且单词之间将使用空格分隔
serializeNulls()空值的序列化
setExclusionStrategies设置自定义排除策略
setLenient()宽松的JSON语法规则
如果JSON违反结构规则之一,它将抛出MalformedJsonException。如果我们将lenient设置为true,则它将忽视某些违规行为,并尝试读取格式不正确的JSON
自定义序列化及反序列化操作
自定义序列化
需实现JsonSerializer接口,然后注册到GsonBuilder中
例如将Boolean类型序列化时转换为0和1
public class MyJsonSerializer implements JsonSerializer<Boolean> { @Override public JsonElement serialize(Boolean src, Type typeOfSrc, JsonSerializationContext context) { if (src){ return new JsonPrimitive(1); }else { return new JsonPrimitive(0); } } }
@Data @AllArgsConstructor @NoArgsConstructor static class User { private String name; private Integer id; private Boolean flag; } @Test public void testJsonSerializer(){ Gson gson = new GsonBuilder().registerTypeAdapter(Boolean.class, new MyJsonSerializer()).create(); // {"name":"name","id":20,"flag":1} System.out.println(gson.toJson(new User("name", 20, true))); }
自定义反序列化
需实现JsonDeserializer接口,然后注册到GsonBuilder中
@Data @AllArgsConstructor @NoArgsConstructor static class TestVo{ private String name; private int age; private LocalDate birth; }
public class MyJsonDeserializer implements JsonDeserializer<GsonTest.TestVo> { @Override public GsonTest.TestVo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = json.getAsJsonObject(); LocalDate localDate = LocalDate.of( jsonObject.get("year").getAsInt(), jsonObject.get("month").getAsInt(), jsonObject.get("day").getAsInt()); return new GsonTest.TestVo( jsonObject.get("name").getAsString(), jsonObject.get("age").getAsInt(), localDate); } }
@Test public void testDeserializer(){ String json = "{\"name\":\"hahaha\",\"age\":50,\"year\":2022,\"month\":5,\"day\":18}"; Gson gson = new GsonBuilder().registerTypeAdapter(TestVo.class, new MyJsonDeserializer()).create(); // TestVo(name=hahaha, age=50, birth=2022-05-18) System.out.println(gson.fromJson(json, TestVo.class)); }
解析json字符串
使用JsonParser
https://github.com/google/gson/blob/master/gson/src/test/java/com/google/gson/JsonParserTest.java
Fastjson(todo)
fastjson是阿里巴巴开源的json处理工具
依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.79</version> </dependency>
基本使用
对象和json字符串互转
@AllArgsConstructor @NoArgsConstructor @Data public static class TestVo { private String name; private int age; private Date time; } @Test public void test_Object(){ TestVo testVo = new TestVo("yonug", 28, new Date()); String s = JSONObject.toJSONString(testVo); System.out.println(s); // {"age":28,"name":"yonug","time":1641360720757} String json = """ { "age":28, "name":"yonug", "time":1641360602911 } """; TestVo vo = JSONObject.parseObject(json, TestVo.class); System.out.println(vo); // TestFastJson.TestVo(name=yonug, age=28, time=Wed Jan 05 13:30:02 CST 2022) }
集合和json字符串互转
@Test public void test_Array(){ List<TestVo> collect = IntStream.rangeClosed(1, 5) .mapToObj(e -> new TestVo(RandomStringUtils.randomAlphabetic(5, 10), e, new Date())) .collect(Collectors.toList()); String s = JSONArray.toJSONString(collect); System.out.println(s); // [{"age":1,"name":"iLuef","time":1641360921164},{"age":2,"name":"Jutus","time":1641360921164},{"age":3,"name":"XaIxF","time":1641360921164},{"age":4,"name":"BMDhp","time":1641360921164},{"age":5,"name":"toYORjcow","time":1641360921164}] List<TestVo> testVos = JSONArray.parseArray(s, TestVo.class); System.out.println(testVos); // [TestFastJson.TestVo(name=iLuef, age=1, time=Wed Jan 05 13:35:21 CST 2022), TestFastJson.TestVo(name=Jutus, age=2, time=Wed Jan 05 13:35:21 CST 2022), TestFastJson.TestVo(name=XaIxF, age=3, time=Wed Jan 05 13:35:21 CST 2022), TestFastJson.TestVo(name=BMDhp, age=4, time=Wed Jan 05 13:35:21 CST 2022), TestFastJson.TestVo(name=toYORjcow, age=5, time=Wed Jan 05 13:35:21 CST 2022)] }
json对象操作
@Test public void test_jsonObject(){ String json = """ { "name":"young", "age":20, "addressInfoList": [ { "address":"a" },{ "address":"b" } ] } """; JSONObject jsonObject = JSONObject.parseObject(json); String name = jsonObject.getString("name"); // young int age = jsonObject.getIntValue("age"); // 28 JSONArray addressInfoList = jsonObject.getJSONArray("addressInfoList"); for (int i = 0; i < addressInfoList.size(); i++) { JSONObject object = addressInfoList.getJSONObject(i); String address = object.getString("address"); // a b } }
常用注解
@JSONField
可以配置在属性上
@JSONField(ordinal=1)//配置序列化的字段顺序(1.1.42版本之后才支持) @JSONField(serialize=false) //是否参与序列化:该字段不输出 但是如果加了final,这个字段就无法被过滤 @JSONField(derialize=false) //是否参与反序列化:该字段不输出 但是如果加了final,这个字段就无法被过滤 @JSONField(format="yyyy-MM-dd HH:mm:ss") //日期按照指定格式序列化 @JSONField(name="别名");//使用字段别名 @JSONField(serialzeFeatures={SerialzeFeatures属性});//序列化规则 @JSONField(parseFeatures={Features属性});//反序列化规则
SerializerFeature属性
public enum SerializerFeature { /** * 输出key时是否使用双引号,默认为true */ QuoteFieldNames, /** * 使用单引号而不是双引号,默认为false */ UseSingleQuotes, /** * 是否输出值为null的字段,默认为false */ WriteMapNullValue, /** * 用枚举toString()值输出 */ WriteEnumUsingToString, /** * 用枚举name()输出 */ WriteEnumUsingName, /** * Date使用ISO8601格式输出,默认为false */ UseISO8601DateFormat, /** * @since 1.1 * List字段如果为null,输出为[],而非null */ WriteNullListAsEmpty, /** * @since 1.1 * 字符类型字段如果为null,输出为"",而非null */ WriteNullStringAsEmpty, /** * @since 1.1 * 数值字段如果为null,输出为0,而非null */ WriteNullNumberAsZero, /** * @since 1.1 * Boolean字段如果为null,输出为false,而非null */ WriteNullBooleanAsFalse, /** * @since 1.1 * 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true */ SkipTransientField, /** * @since 1.1 * 按字段名称排序后输出。默认为false */ SortField, /** * @since 1.1.1 * 把\t做转义输出,默认为false(不推荐,已删除) */ @Deprecated WriteTabAsSpecial, /** * @since 1.1.2 * 结果是否格式化,默认为false */ PrettyFormat, /** * @since 1.1.2 * 序列化时写入类型信息,默认为false。反序列化时需用到 */ WriteClassName, /** * @since 1.1.6 * 消除对同一对象循环引用的问题,默认为false */ DisableCircularReferenceDetect, /** * @since 1.1.9 * 对斜杠"/"进行转义 */ WriteSlashAsSpecial, /** * @since 1.1.10 * 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false */ BrowserCompatible, /** * @since 1.1.14 * 全局修改日期格式,默认为false。JSON.DEFFAULT_DATE_FORMAT = “yyyy-MM-dd”;JSON.toJSONString(obj, SerializerFeature.WriteDateUseDateFormat); */ WriteDateUseDateFormat, /** * @since 1.1.15 */ NotWriteRootClassName, /** * @since 1.1.19 * 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false */ DisableCheckSpecialChar, /** * @since 1.1.35 * 将对象转为array输出 */ BeanToArray, /** * @since 1.1.37 */ WriteNonStringKeyAsString, /** * @since 1.1.42 */ NotWriteDefaultValue, /** * @since 1.2.6 */ BrowserSecure, /** * @since 1.2.7 */ IgnoreNonFieldGetter, /** * @since 1.2.9 */ WriteNonStringValueAsString, /** * @since 1.2.11 */ IgnoreErrorGetter; }
Feature属性
public enum Feature { /** * 这个特性,决定了解析器是否将自动关闭那些不属于parser自己的输入源。 * 如果禁止,则调用应用不得不分别去关闭那些被用来创建parser的基础输入流InputStream和reader; * 如果允许,parser只要自己需要获取closed方法(当遇到输入流结束,或者parser自己调用 JsonParder#close方法),就会处理流关闭。 * 注意:这个属性默认是true,即允许自动关闭流 */ AutoCloseSource, /** * 该特性决定parser将是否允许解析使用Java/C++ 样式的注释(包括'/'+'*' 和'//' 变量)。 * 由于JSON标准说明书上面没有提到注释是否是合法的组成,所以这是一个非标准的特性;尽管如此,这个特性还是被广泛地使用。 * 注意:该属性默认是false,因此必须显式允许,即通过JsonParser.Feature.ALLOW_COMMENTS 配置为true。 */ AllowComment, /** * 这个特性决定parser是否将允许使用非双引号属性名字, (这种形式在Javascript中被允许,但是JSON标准说明书中没有)。 * 注意:由于JSON标准上需要为属性名称使用双引号,所以这也是一个非标准特性,默认是false的。 * 同样,需要设置JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES为true,打开该特性。 */ AllowUnQuotedFieldNames, /** * 该特性决定parser是否允许单引号来包住属性名称和字符串值。 * 注意:默认下,该属性也是关闭的。需要设置JsonParser.Feature.ALLOW_SINGLE_QUOTES为true */ AllowSingleQuotes, /** * 该特性决定JSON对象属性名称是否可以被String#intern 规范化表示。如果允许,则JSON所有的属性名将会 intern() ; * 如果不设置,则不会规范化,默认下,该属性是开放的。此外,必须设置CANONICALIZE_FIELD_NAMES为true * 关于intern方法作用:当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串 (该对象由 equals(Object) 方法确定),则返回池中的字符串。 * 否则,将此 String 对象添加到池中, 并且返回此 String 对象的引用。 */ InternFieldNames, /** * 这个设置为true则遇到字符串符合ISO8601格式的日期时,会直接转换成日期类。 */ AllowISO8601DateFormat, /** * 允许多重逗号,如果设为true,则遇到多个逗号会直接跳过。 * {"a":1,,,"b":2} */ AllowArbitraryCommas, /** * 这个设置为true则用BigDecimal类来装载数字,否则用的是double; */ UseBigDecimal, /** * @since 1.1.2 * 忽略不匹配 */ IgnoreNotMatch, /** * @since 1.1.3 * 如果你用fastjson序列化的文本,输出的结果是按照fieldName排序输出的,parser时也能利用这个顺序进行优化读取。这种情况下,parser能够获得非常好的性能 */ SortFeidFastMatch, /** * @since 1.1.3 * 禁用ASM */ DisableASM, /** * @since 1.1.7 * 禁用循环引用检测 */ DisableCircularReferenceDetect, /** * @since 1.1.10 * 对于没有值的字符串属性设置为空串 */ InitStringFieldAsEmpty, /** * @since 1.1.35 * 支持数组to对象 */ SupportArrayToBean, /** * @since 1.2.3 * 属性保持原来的顺序 */ OrderedField, /** * @since 1.2.5 * 禁用特殊字符检查 */ DisableSpecialKeyDetect, /** * @since 1.2.9 * 使用对象数组 */ UseObjectArray; }