本文中代码中为了使字符串的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;
}