# JSON

back:java中常见方法总结

fastjson转对象过程比jackson要快,但是在转换列表时,jackson要比fastjson快。

# org.json

返回顶部

引入org.json.jar

JSONObject jsonObject = new JSONObject(responseStr);
System.out.println(jsonObject.get("playUrl"));
1
2

JSONArray也是类似。

# 序列化反序列化

使用过程中总会有
1.序列化(返回给前端get)时忽略某属性(如Password)
2.反序列化(从前段获取数据set)时忽略某属性(如HashedPassword)

Jackson提供了@Jsonignore这个注解,用于在(反)序列化时,忽略bean的某项属性,在Jackson 1.9的时候,@Jsonignore的语义还有了变化,如下:

  • 1.9之前:
    在Setter方法上加@Jsonignore注解并不会影响Getter方法的调用

  • 1.9之后:
    在Setter方法上加@Jsonignore会导致整个这个属性在序列化过程中被忽略

所以在1.9之后需要使用其他的方法来设置某个属性是否需要(反)序列化:
@JsonProperty(access = Access.WRITE_ONLY)
WRITE_ONLY:仅做反序列化操作。
READ_ONLY:仅做序列化操作。

以上不大好用,建议如下@JsonIgnoreProperties(value="some_field", allowGetters = true, allowSetters = false)

问题:由于jackson在处理collection和map时会自动USE_GETTERS_AS_SETTERS

# fastjson

返回顶部 | 联合阅读fastjson

引入alibaba JSON

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.58</version>
        </dependency>
1
2
3
4
5
6
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.junit.Test;

import java.util.Optional;
public class JsonTest {
    private static String jsonStr;
    static {
//        jsonStr = "{\"name\":23,\"sex\":\"female\"" +
//                ",\"child\":[{\"name\":\"one\",\"age\":12},{\"name\":\"two\",\"age\":21}]}";
        jsonStr = "";
    }
    @Test
    public void testAlibabaJson(){
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        JSONArray jsonArray = jsonObject.getJSONArray("child");
        JSONObject child = jsonArray.getJSONObject(0);
        System.out.println(child.get("name"));
    }

    @Test
    public void testOptionalAlibab(){
        String name = Optional.ofNullable(jsonStr).map(str->JSONObject.parseObject(str))
                .map(json->json.getJSONArray("child"))
                .filter(arr->arr.size()>0)
                .map(arr->arr.getJSONObject(0))
                .map(json->json.getString("name"))
                .orElse("who");
        System.out.println(name);
    }
}

long t7 = System.currentTimeMillis();
        String jsonStrsAli = JSON.toJSONString(testJsonSonEntities
                , SerializerFeature.PrettyFormat
                ,SerializerFeature.WriteNullStringAsEmpty);
//        System.out.println("ali列表转json字符串:"+ jsonStrsAli);
        System.out.println("ali-列表转json字符串耗时:"+ (System.currentTimeMillis()-t7));

        long t8 = System.currentTimeMillis();
        List<TestJsonSonEntity> sons2 = JSON.parseArray(jsonStrsAli,TestJsonSonEntity.class);
        System.out.println("ali-json字符串转列表耗时:"+(System.currentTimeMillis()-t8));
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

SerializerFeature常用属性

名称 含义
QuoteFieldNames 输出key时是否使用双引号,默认为true
UseSingleQuotes 使用单引号而不是双引号,默认为false
WriteMapNullValue 是否输出值为null的字段,默认为false
WriteEnumUsingToString Enum输出name()或者original,默认为false
UseISO8601DateFormat Date使用ISO8601格式输出,默认为false
WriteNullListAsEmpty List字段如果为null,输出为[],而非null
WriteNullStringAsEmpty 字符类型字段如果为null,输出为”“,而非null
WriteNullNumberAsZero 数值字段如果为null,输出为0,而非null
WriteNullBooleanAsFalse Boolean字段如果为null,输出为false,而非null
SkipTransientField 如果是true,类中的Get方法对应的Field是transient,序列化时将会被忽略。默认为true
SortField 按字段名称排序后输出。默认为false
WriteTabAsSpecial 把\t做转义输出,默认为false不推荐设为true
PrettyFormat 结果是否格式化,默认为false
WriteClassName 序列化时写入类型信息,默认为false。反序列化是需用到
DisableCircularReferenceDetect 消除对同一对象循环引用的问题,默认为false
WriteSlashAsSpecial 对斜杠’/’进行转义
BrowserCompatible 将中文都会序列化为\uXXXX格式,字节数会多一些,但是能兼容IE 6,默认为false
WriteDateUseDateFormat 全局修改日期格式,默认为false。
DisableCheckSpecialChar 一个对象的字符串属性中如果有特殊字符如双引号,将会在转成json时带有反斜杠转移符。如果不需要转义,可以使用这个属性。默认为false
BeanToArray 将对象转为array输出

# jackson

返回顶部

pom引入方法:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>
1
2
3
4

或者引入jackson.databind.jar

ObjectMapper jsonMapper = new ObjectMapper();
AlarmMsg msg = jsonMapper.readValue(szString, AlarmMsg.class);

public class AlarmMsg implements Serializable{
    /**
    *
    */
private static final long serialVersionUID = -2191151745560102649L;

@JsonProperty
private AlarmDetail AlarmInfo;
@JsonProperty
private String Name;
@JsonProperty
private String SessionID;

@JsonIgnore
public String getName() {
    return Name;
}
@JsonIgnore
public void setName(String name) {
    Name = name;
}
@JsonIgnore
public String getSessionID() {
    return SessionID;
}
@JsonIgnore
public void setSessionID(String sessionID) {
    SessionID = sessionID;
}
@JsonIgnore
public AlarmDetail getAlarmInfo() {
    return AlarmInfo;
}
@JsonIgnore
public void setAlarmInfo(AlarmDetail alarmInfo) {
    AlarmInfo = alarmInfo;
}
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

# LocalDateTime

实体类

@Getter
@Setter
@ToString
public class TestJsonEntity {
    private String name;
    private String sex;
    private Integer age;
    private int height;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime birthLocalDateTime;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate birthLocalDate;
    private BigDecimal fingerSize;
    private Double footSize;
    private Long handLength;
    @JsonFormat(pattern = "yyyyMMddHHmmss")
    private Date birthDate;
    private List<TestJsonSonEntity> testJsonEntities;
}

@Getter
@Setter
@ToString
public class TestJsonSonEntity {
    private String no;
    private String country;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endDateTime;
}

//测试方法
@Test
    public void testTransfer(){
        TestJsonEntity testJsonEntity = new TestJsonEntity();
        testJsonEntity.setName("深井冰");
        testJsonEntity.setSex("中性");
        testJsonEntity.setAge(20);
        testJsonEntity.setHeight(400);
        testJsonEntity.setBirthLocalDateTime(LocalDateTime.now().minusDays(4));
        testJsonEntity.setBirthLocalDate(LocalDate.now());
        testJsonEntity.setFingerSize(new BigDecimal("50"));
        testJsonEntity.setFootSize(6.02D);
        testJsonEntity.setHandLength(900L);
        testJsonEntity.setBirthDate(new Date());

        List<TestJsonSonEntity> testJsonSonEntities = new ArrayList<>();
        for (int i = 0; i < 3; i++){
            TestJsonSonEntity testJsonSonEntity = new TestJsonSonEntity();
            testJsonSonEntity.setNo("007");
            testJsonSonEntity.setCountry("帝国");
            testJsonSonEntity.setEndDateTime(LocalDateTime.now().plusMonths(3));
            testJsonSonEntities.add(testJsonSonEntity);
        }
        testJsonEntity.setTestJsonEntities(testJsonSonEntities);

        String jsonStr = JsonUtil.objectToJson(testJsonEntity);
        System.out.println("对象转json字符串:"+ jsonStr);
        System.out.println("json字符串转对象:"+JsonUtil.jsonToPojo(jsonStr,TestJsonEntity.class));

        String jsonStrs = JsonUtil.objectToJson(testJsonSonEntities);
        System.out.println("列表转json字符串:"+ jsonStrs);
        System.out.println("json字符串转列表:"+JsonUtil.jsonToList(jsonStrs,TestJsonSonEntity.class));
    }
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
对象转json字符串:{"name":"深井冰","sex":"中性","age":20,"height":400,"birthLocalDateTime":"2019-07-16 20:41:01","birthLocalDate":"2019-07-20","fingerSize":50,"footSize":6.02,"handLength":900,"birthDate":"20190720124101","testJsonEntities":[{"no":"007","country":"帝国","endDateTime":"2019-10-20 20:41:01"},{"no":"007","country":"帝国","endDateTime":"2019-10-20 20:41:01"},{"no":"007","country":"帝国","endDateTime":"2019-10-20 20:41:01"}]}
json字符串转对象:TestJsonEntity(name=深井冰, sex=中性, age=20, height=400, birthLocalDateTime=2019-07-16T20:41:01, birthLocalDate=2019-07-20, fingerSize=50, footSize=6.02, handLength=900, birthDate=Sat Jul 20 20:41:01 CST 2019, testJsonEntities=[TestJsonSonEntity(no=007, country=帝国, endDateTime=2019-10-20T20:41:01), TestJsonSonEntity(no=007, country=帝国, endDateTime=2019-10-20T20:41:01), TestJsonSonEntity(no=007, country=帝国, endDateTime=2019-10-20T20:41:01)])
列表转json字符串:[{"no":"007","country":"帝国","endDateTime":"2019-10-20 20:41:01"},{"no":"007","country":"帝国","endDateTime":"2019-10-20 20:41:01"},{"no":"007","country":"帝国","endDateTime":"2019-10-20 20:41:01"}]
json字符串转列表:[TestJsonSonEntity(no=007, country=帝国, endDateTime=2019-10-20T20:41:01), TestJsonSonEntity(no=007, country=帝国, endDateTime=2019-10-20T20:41:01), TestJsonSonEntity(no=007, country=帝国, endDateTime=2019-10-20T20:41:01)]
1
2
3
4

工具类许增加

@Slf4j
public class JsonUtil {
private static final ObjectMapper MAPPER = new ObjectMapper()
        .registerModule(new ParameterNamesModule())
        .registerModule(new Jdk8Module())
        .registerModule(new JavaTimeModule());// new module, NOT JSR310Module
1
2
3
4
5
6

或者

private static final ObjectMapper MAPPER = new ObjectMapper().findAndRegisterModules();
1

Cannot construct instance of com.yucfeng.Entity.EData (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

确认无参构造函数

# 实用json工具类实现

# jackson工具包

实现对象转json字符串字符串转对象list转json字符串json字符串转list

springboot引入:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
1
2
3
4
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonUtil {
private static Logger log = LoggerFactory.getLogger(JsonUtil.class);
private static final ObjectMapper MAPPER = new ObjectMapper()
        .registerModule(new ParameterNamesModule())
        .registerModule(new Jdk8Module())
        .registerModule(new JavaTimeModule());// new module, NOT JSR310Module
//private static final ObjectMapper MAPPER = new ObjectMapper().findAndRegisterModules();

    /**
     * 将对象转换成json字符串。
     */
public static String objectToJson(Object data) {
    try {
        String string = MAPPER.writeValueAsString(data);
        return string;
    } catch (JsonProcessingException e) {
        e.printStackTrace();
        log.error(e.getMessage());
    }
    return null;
}

    /**
     * 将json结果集转化为对象
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
        e.printStackTrace();
        log.error(e.getMessage());
        }
        return null;
    }

/**
    * 将json数据转换成pojo对象list
    */
public static <T>List<T> jsonToList(String jsonData, Class<T> beanType) {
    JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
    try {
        List<T> list = MAPPER.readValue(jsonData, javaType);
        return list;
    } catch (Exception e) {
        e.printStackTrace();
        log.error(e.getMessage());
    }
    return null;
}

}
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