java解析json jackson gson fastjson json-lib
java解析json 常用的类库有 jackson gson FastJson Json-lib
综合来讲 Jackson性能较好
Gosn 功能最全
fastjson速度较快 但安全漏洞较多
json-lib
(1) jackson使用
jackson
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.0</version>
</dependency>
(1.1) 对象转字符串
/**
* 对象转字符串
*/
@Test
public void writeObjectAsString() {
ObjectMapper objectMapper = new ObjectMapper();
UserVo user = getUserVo();
String json = null;
try {
json = objectMapper.writeValueAsString(user);
} catch (JsonProcessingException e) {
log.error("", e);
}
// {"id":2305843116587876352,"name":"李四","age":20,"birthday":1591402080000,"email":"lisi@gmail.com","address":["北京","天津"],"arr":["A","b"]}
log.info("json:{}", json);
}
/**
* @return
*/
public UserVo getUserVo() {
UserVo user = new UserVo();
Long x = 100L + Integer.MAX_VALUE + 1 << 30;
log.info("id:{}", x);
user.setId(x);
user.setName("李四");
user.setEmail("lisi@gmail.com");
user.setAge(20);
try {
SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = dateformat.parse("2020-06-06 08:08:00");
user.setBirthday(date);
} catch (ParseException e) {
log.error("", e);
}
List<String> list = Arrays.asList("北京", "天津");
user.setAddress(list);
String[] arr = {"A", "b"};
user.setArr(arr);
return user;
}
class UserVo {
private Long id;
private String name;
private Integer age;
private Date birthday;
private String email;
private List<String> address;
private String[] arr;
// 省略 getter setter
}
(1.2) 字符串转对象
/**
* 字符串转对象
*/
@Test
public void readStringAsObject() {
String json = "{\"id\":2305843116587876352,\"name\":\"李四\",\"age\":20,\"birthday\":1591402080000,\"email\":\"lisi@gmail.com\",\"address\":[\"北京\",\"天津\"],\"arr\":[\"A\",\"b\"]}\n";
ObjectMapper objectMapper = new ObjectMapper();
UserVo userVo = null;
try {
userVo = objectMapper.readValue(json, UserVo.class);
} catch (JsonProcessingException e) {
log.error("", e);
} catch (IOException e) {
log.error("", e);
}
log.info("{} {} {} {} {} {} {} ", userVo.getId(), userVo.getAddress(), userVo.getAge(), userVo.getArr(), userVo.getBirthday(), userVo.getEmail(), userVo.getName());
}
(1.3) 集合转字符串
/**
* 集合转字符串
*/
@Test
public void writeListAsString() {
List<UserVo> list = getUserList();
String json = null;
try {
json = objectMapper.writeValueAsString(list);
} catch (JsonProcessingException e) {
log.error("", e);
}
// [{"id":1,"name":"李四","age":null,"birthday":null,"email":null,"address":["北京","天津"],"arr":["A","b"]},{"id":2,"name":"张三","age":null,"birthday":null,"email":null,"address":["河北","山东"],"arr":["C","中文"]}]
log.info("json:{}", json);
}
/**
* @return
*/
public List<UserVo> getUserList() {
List<UserVo> list = new ArrayList(2);
UserVo user = new UserVo();
user.setId(1L);
user.setName("李四");
List<String> addrs = Arrays.asList("北京", "天津");
user.setAddress(addrs);
String[] arr = {"A", "b"};
user.setArr(arr);
UserVo user2 = new UserVo();
user2.setId(2L);
user2.setName("张三");
List<String> addrs2 = Arrays.asList("河北", "山东");
user2.setAddress(addrs2);
String[] arr2 = {"C", "中文"};
user2.setArr(arr2);
list.add(user);
list.add(user2);
return list;
}
(2.4) 字符串转集合
/**
* 字符串转集合
*/
@Test
public void readStringAsList() {
String json = "[{\"id\":1,\"name\":\"李四\",\"age\":null,\"birthday\":null,\"email\":null,\"address\":[\"北京\",\"天津\"],\"arr\":[\"A\",\"b\"]},{\"id\":2,\"name\":\"张三\",\"age\":null,\"birthday\":null,\"email\":null,\"address\":[\"河北\",\"山东\"],\"arr\":[\"C\",\"中文\"]}]";
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, UserVo.class);
//如果是Map类型 mapper.getTypeFactory().constructParametricType(HashMap.class, String.class, Bean.class);
List<UserVo> list = null;
try {
list = objectMapper.readValue(json, javaType);
} catch (JsonProcessingException e) {
log.error("", e);
} catch (IOException e) {
log.error("", e);
}
for (UserVo userVo : list) {
log.info("{} {} {} {} {} {} {} ", userVo.getId(), userVo.getAddress(), userVo.getAge(), userVo.getArr(), userVo.getBirthday(), userVo.getEmail(), userVo.getName());
}
}
/**
* 字符串转集合
*/
@Test
public void readStringAsList() {
String json = "[{\"id\":1,\"name\":\"李四\",\"age\":null,\"birthday\":null,\"email\":null,\"address\":[\"北京\",\"天津\"],\"arr\":[\"A\",\"b\"]},{\"id\":2,\"name\":\"张三\",\"age\":null,\"birthday\":null,\"email\":null,\"address\":[\"河北\",\"山东\"],\"arr\":[\"C\",\"中文\"]}]";
JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, UserVo.class);
//如果是Map类型 mapper.getTypeFactory().constructParametricType(HashMap.class, String.class, Bean.class);
List<UserVo> list = null;
try {
list = objectMapper.readValue(json, javaType);
} catch (JsonProcessingException e) {
log.error("", e);
} catch (IOException e) {
log.error("", e);
}
for (UserVo userVo : list) {
log.info("{} {} {} {} {} {} {} ", userVo.getId(), userVo.getAddress(), userVo.getAge(), userVo.getArr(), userVo.getBirthday(), userVo.getEmail(), userVo.getName());
}
}
(2) gson
(3) fastjson
使用 fastjson 时遇到的问题
java.lang.VerifyError
java.lang.VerifyError: (class: com/alibaba/fastjson/parser/deserializer/FastjsonASMDeserializer_3_ErpOrderResVo, method: deserialze signature: (Lcom/alibaba/fastjson/parser/DefaultJSONParser;Ljava/lang/reflect/Type;Ljava/lang/Object;I)Ljava/lang/Object;) Accessing value from uninitialized register 85
at java.lang.Class.getDeclaredConstructors0(Native Method)
fastjson 32个字段时反序列化报错的问题
1.2.28 32整数倍个字段 OOM bug
32个字段时反序列化报错
(3) 老办法
以下是老方法/笨办法
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xxxx.file.FileUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* @version V1.0
* @date 2017-09-21 21:48
*/
public class JsonTest {
private static final Logger logger = LoggerFactory.getLogger(JsonTest.class);
public static void main(String[] args) {
String str = null;
String filePath = "doc/html/xiecheng/crawler_flights_bj-yc-2017-09-23_result.json";
try {
str = FileUtil.readFile2String(filePath);
} catch (IOException e) {
logger.error("", e);
}
JSONObject json = JSONObject.parseObject(str);
JSONArray fisArray = json.getJSONArray("fis");
int size = fisArray.size();
for(int i = 0; i < size; i++){
JSONObject oneFlight = (JSONObject) fisArray.get(i);
logger.info(i +": {}", oneFlight);
}
}
/**
*
* @param str
*/
public List<Map<String, String>> parserJson(String str) {
if (StringUtil.isEmpty(str)) {
logger.error("json为空");
return null;
}
JSONObject json = JSONObject.parseObject(str);
// 航空公司
JSONObject als = (JSONObject) json.get("als");
logger.info("符合要求的航空公司:{}", als);
Set<Map.Entry<String, Object>> set = als.entrySet();
logger.info("set:{}", set);
JSONObject apb = (JSONObject) json.get("apb");
logger.info("符合要求的机场:{}", apb);
// 中转组合,暂时不考虑,业务上也暂时不需要,稍微有点复杂,时间允许可以解析
// json.get("tf");
// 直航
JSONArray fisArray = json.getJSONArray("fis");
if (fisArray == null || fisArray.isEmpty()) {
logger.error("fisArray结果为空");
return null;
}
int size = fisArray.size();
if (size == 0) {
logger.error("fisArray 里元素个数为0");
return null;
}
List<Map<String, String>> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
Map<String, String> dataMap = new HashMap<>(16);
//
JSONObject oneFlight = (JSONObject) fisArray.get(i);
logger.debug(i + ": {}", oneFlight);
// 到达城市代码
String acc = (String) oneFlight.get("acc");
dataMap.put("acc", acc);
// 目的地
String acn = (String) oneFlight.get("acn");
dataMap.put("acn", acn);
// 航空公司
String alc = (String) oneFlight.get("alc");
String flightCompany = null;
if (als.containsKey(alc)) {
flightCompany = als.getString(alc);
}
dataMap.put("alc", flightCompany);
// 到达机场
String apbn = (String) oneFlight.get("apbn");
dataMap.put("apbn", apbn);
// 到达时间
String at = (String) oneFlight.get("at");
dataMap.put("at", at);
// 到达城市代码
String dcc = (String) oneFlight.get("dcc");
dataMap.put("dcc", dcc);
// 出发地
String dcn = (String) oneFlight.get("dcn");
dataMap.put("dcn", dcn);
// 出发机场
String dpbn = (String) oneFlight.get("dpbn");
dataMap.put("dpbn", dpbn);
// 航站楼
String dsmsn = (String) oneFlight.get("dsmsn");
dataMap.put("dsmsn", dsmsn);
// 出发时间
String dt = (String) oneFlight.get("dt");
dataMap.put("dt", dt);
// 航班号
String fn = (String) oneFlight.get("fn");
dataMap.put("fn", fn);
// 实际票价
String lp = oneFlight.get("lp").toString();
dataMap.put("lp", lp);
JSONObject confort = oneFlight.getJSONObject("confort");
String historyPunctualityArr = (String) confort.get("HistoryPunctualityArr");
if (StringUtil.isNotEmpty(historyPunctualityArr)) {
dataMap.put("historyPunctualityArr", historyPunctualityArr.replace("%", ""));
}
logger.info("本条航班数据:{}", dataMap);
list.add(dataMap);
}
return list;
} // end method
}
References
[1] Java几种常用JSON库性能比较
[2] jackson-docs
[3] jackson-object-mapper-tutorial