# JSON
fastjson转对象过程比jackson要快,但是在转换列表时,jackson要比fastjson快。
# org.json
引入org.json.jar
JSONObject jsonObject = new JSONObject(responseStr);
System.out.println(jsonObject.get("playUrl"));
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
引入alibaba JSON
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
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));
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>
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;
}
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));
}
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)]
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
2
3
4
5
6
或者
private static final ObjectMapper MAPPER = new ObjectMapper().findAndRegisterModules();
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>
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;
}
}
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