1、JSON简介
json(JavaScript Object Notation),JavaScript对象表示法。json作为数据格式的一种,有很多优势,下面例子可帮大家更好的理解json格式:
Person p = new Person();
p.setName("张三");
p.setAge(23);
p.setGender("男");
var p = {"name":"张三","age":23,"gender":"男"};
可以看到,json本质就是将java对象转换之后的字符串,对象内容通过k,v键值对的形式表示。
- json现在多用于存储和交换文本信息的语法
- 进行数据的传输
- JSON 比 XML 更小、更快,更易解析
因此,在日常开发中json数据的解析就是必不可少的技能包。
2、JSON解析框架简介
- Jsonlib:是以前 Java 常用的一个 Json 库,最后的版本是 2.4,分别提供了 JDK 1.3 和 1.5 的支持,最后更新时间是 2010年12月14日。由于解析json时会对当前解析位置到末尾进行subString的操作,所以在解析较长的字符串时大量的 CPU 和内存消耗。因此现已不推荐使用;
- GSON:由Google提供的开源库(下面会详细介绍);
- FastJSON:由Alibaba提供的开源库(下面会详细介绍);
- Jackson:SpringMVC内置解析器(下面会详细介绍)。
1、GSON
maven
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
基本用法
1、创建实例
new Gson()
Gson gson = new Gson();
GsonBuilder.build()
GsonBuilder builder = new GsonBuilder();
Gson gson = builder.create();
2、java对象->json
String json = gson.toJson(java对象);
//上面的json直接控制台输出没有格式,可以这样
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
String json = gson.toJson(java对象);
3、json->java对象
Employee empObject = gson.fromJson(jsonString, Employee.class);
4、JSON array --> Java array/list
User[] userArray = gson.fromJson(userJson, User[].class);
5、JSON array-->List
String userJson = "[{'name': 'Alex','id': 1}, " + "{'name': 'Brian','id':2}, " + "{'name': 'Charles','id': 3}]";
Gson gson = new Gson();
java.lang.reflect.Type userListType = new TypeToken<ArrayList<User>>() {
}.getType();
ArrayList<User> userArray = gson.fromJson(userJson, userListType);
for (User user : userArray) {
System.out.println(user);
}
6、JSON array-->成员变量
数组成员变量
String departmentJson = "{'id' : 1, "
+ "'name': 'HR',"
+ "'users' : ["
+ "{'name': 'Alex','id': 1}, "
+ "{'name': 'Brian','id':2}, "
+ "{'name': 'Charles','id': 3}]}";
Gson gson = new Gson();
Department department = gson.fromJson(departmentJson, Department.class);
System.out.println(department);
list成员变量
String departmentJson = "{'id' : 1, "
+ "'name': 'HR',"
+ "'users' : ["
+ "{'name': 'Alex','id': 1}, "
+ "{'name': 'Brian','id':2}, "
+ "{'name': 'Charles','id': 3}]}";
Gson gson = new Gson();
Department2 department = gson.fromJson(departmentJson, Department2.class);
System.out.println(department);
7、JSON <---->Set
Set-->JSON
Set<String> userSet = new HashSet<String>();
userSet.add("Alex");
userSet.add("Brian");
userSet.add("Charles");
Gson gson = new Gson();
String jsonString= gson.toJson(userSet);
System.out.println(jsonString);
JSON-->Set
String jsonString = "['Alex','Brian','Charles','Alex']";
Gson gson = new Gson();
java.lang.reflect.Type setType = new TypeToken<HashSet<String>>(){}.getType();
Set<String> userSet = gson.fromJson(jsonString, setType);
System.out.println(userSet);
8、null
实体类有为空的字段,转为json时会忽略,为此行为允许使用更紧凑的JSON输出格式。
怎么允许空值?
Gson gson = new GsonBuilder()
.serializeNulls()
.create();
9、JsonParser()
创建JsonParser
JsonParser parser = new JsonParser();
转化JSON
JsonParser类提供3种方法来提供JSON作为源并将其解析为JsonElements树。
- JsonElement parse(JsonReader json)–使用JsonReader读取JSON作为令牌流,并从JSON流中返回下一个值作为分析树。
- JsonElement parse(java.io.Reader json)–使用指定的阅读器读取JSON并将JSON字符串解析为解析树。
- JsonElement parse(java.lang.String json)–将指定的JSON字符串解析为解析树。
如果指定的文本不是有效的JSON,则这三个方法都将抛出JsonParseException和JsonSyntaxException。
JsonElement, JsonObject 和JsonArray
通过:
JsonElement jsonElement = new JsonParser().parse(json);
将json转为JsonElement后可通过以下方法判断具体类型:(返回值:boolean):
jsonElement.isJsonObject(); //是否为对象
jsonElement.isJsonArray(); //是否为数组
jsonElement.isJsonNull(); //是否为空
jsonElement.isJsonPrimitive(); //是否为java基本类型
然后可以解析为具体类型:
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonArray jsonArray = jsonElement.getAsJsonArray();
然后对JsonObject通过get方法提取字段
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class Main
{
public static void main(String[] args) throws Exception
{
String json = "{'id': 1001, "
+ "'firstName': 'Lokesh',"
+ "'lastName': 'Gupta',"
+ "'email': 'howtodoinjava@gmail.com'}";
JsonElement jsonElement = new JsonParser().parse(json);
JsonObject jsonObject = jsonElement.getAsJsonObject();
System.out.println( jsonObject.get("id") );
System.out.println( jsonObject.get("firstName") );
System.out.println( jsonObject.get("lastName") );
System.out.println( jsonObject.get("email") );
}
}
此外还有getAsJsonObject,getAsInt等方法
JsonParser jsonParser = new JsonParser();
JsonElement jsonElement = jsonParser.parse(response);
JsonObject jsonObject = jsonElement.getAsJsonObject();
JsonObject data = jsonObject.getAsJsonObject("data");
jsonObject.get("status").getAsInt()
2、FastJSON
maven
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.23</version>
</dependency>
序列化(java---json)
1.基本的序列化
String objJson = JSON.toJSONString(Object object);
Map<String, Object> map = new HashMap<String, Object>();
map.put("key1", "One");
map.put("key2", "Two");
String mapJson = JSON.toJSONString(map);
2.优化输出
//第二个参数布尔为true时,json为有格式的字符串
String objJson = JSON.toJSONString(Object object, boolean prettyFormat);
3.多特性
String objJson = JSON.toJSONString(Object object, SerializerFeature... features)
传入一个对象和SerializerFeature类型的可变变量。SerializerFeature是一个枚举。
- 日期格式化:
//缺省会转为long 1401370199040
String dateJson = JSON.toJSONString(new Date());
//SerializerFeature.WriteDateUseDateFormat 默认格式
//"2014-05-29 21:36:24"
String dateJson = JSON.toJSONString(new Date(), SerializerFeature.WriteDateUseDateFormat);
//指定日期格式
//"2014-05-29 21:47:00.154"
String dateJson = JSON.toJSONStringWithDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
- 使用单引号(正常是双引号)
String listJson = JSON.toJSONString(list, SerializerFeature.UseSingleQuotes);
- 输出Null字段,缺省不输出null
String listJson = JSON.toJSONString(map, SerializerFeature.WriteMapNullValue);
//输出
//{"a":null,"b":1}
反序列化(json---java)
1.对象
User user1 = JSON.parseObject(userJson, User.class);
2.集合
List<Map> list1 = JSON.parseArray(listJson, Map.class);
List<User> list1 = JSON.parseArray(listJson, User.class);
3.JSONObject/JSONArray()
JSONObject/JSONAArray 是 JSON 的子类
JSONObject对象
- 获取基本类型
String str = jsonObject.getString("str");
Long long = jsonObject.getLong("long");
Date date = jsonObject.getDate("date");
byte[] byte = jsonObject.getBytes("byte");
......
- 获取对象
User user = jsonObject.getObject(userJson, User.class);
Object o = jsonObject.get(object);//可以传任意类型
- 获取JSONObject对象
JSONObject jsonObject = jsonObject.getJSONObject("jsonObject");
- 获取JSONArray对象
JSONArray jsonArray = jsonObject.getJSONArray("jsonArray");
- 骚操作
JSONObject底层实现了Map,所以可以使用Map API对JSONObject对象操作,如:put,isEmpty,remove
JSONArray对象
- 获取基本类型(返回第几位置处的数据)
Long long = jsonArray.getLong(1);
String str = jsonArray.getString(1);
Date date = jsonArray.getDate(1);
- 获取对象
Object o = jsonArray.get(1);
User user = jsonArray.getObject(1, User.class);
- 获取JSONObject对象
JSONObject jsonObject = jsonArray.getJSONObject(1);
- 获取JSONArray对象
JSONArray jsonArray1 = jsonArray.getJSONArray(1);
- 骚操作
JSONArray底层实现了List接口,所以可以使用List API操作JSONArray对象,如:add,size,clear,contains
代码示例解析:
String user = "{\"id\":12,\"name\":\"wei\",\"teacher\":{\"name\":\"kasa\",\"age\":77},\"student\":[{\"id\":2,\"name\":\"lily\",\"age\":12},{\"id\":3,\"name\":\"mary\",\"age\":23}]}";
JSONObject jsonObject = JSON.parseObject(user);
Long id = jsonObject.getLong("id");
String name = jsonObject.getString("name");
JSONObject jsonObjectTeacher = jsonObject.getJSONObject("teacher");
String teacherName = jsonObjectTeacher.getString("name");
JSONArray jsonArray = jsonObject.getJSONArray("student");
for (Object o : jsonArray){
JSONObject j = (JSONObject) o;
Long studentId = j.getLong("id");
String studentName = j.getString("name");
}
String userString = "{\"id\":2,\"name\":\"lily\",\"age\":12}";
//json字符串转javabean
User user = JSON.parseObject(userString, new TypeReference<User>(){});
//javabean转json字符串
String userJsonString = JSON.toJSONString(user);
//javabean转jsonObject
JSONObject jsonObject = (JSONObject) JSON.toJSON(user);
String userArrayString = "[{\"id\":2,\"name\":\"lily\",\"age\":12},{\"id\":3,\"name\":\"mary\",\"age\":23}]";
//jsonArray转javabean集合
ArrayList<User> userList = JSON.parseObject(userArrayString, new TypeReference<ArrayList<User>>(){});
//对象转map
Map<String,Object> map = JSON.parseObject(JSON.toJSONString(user), new TypeReference<Map<String,Object>>(){});
//map转对象
org.apache.commons.beanutils.BeanUtils.populate(obj, map);
3、JackSon
maven
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.2</version>
</dependency>
当SpringBoot项目中引入以下依赖时不用再引入jackson依赖(内置)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
序列化(java---json)
1、writeValueAsString(obj)
作用:将java对象转为字符串
User user = new User();
user.setId("111");
user.setName("zs");
ObjectMapper objectMapper = new ObjectMapper();
String userJson = objectMapper.writeValueAsString(user);
System.out.println(userJson);
2、writeValue(参数1,obj)
作用:将java对象转为为json并传入参数中
参数1:
- File:将obj对象转换为JSON字符串,并保存到指定的文件中;
- Writer:将obj对象转换为JSON字符串,并将json数据填充到字符输出流中;
- OutputStream:将obj对象转换为JSON字符串,并将json数据填充到字节输出流中。
反序列化(json---java)
readValue(参数1,Class)
作用:将参数1中的json转为java对象
参数1:
- String:将字符串转为参数2 class 的对象
- File:将File对象里的json转为class对象
- ......
参数2:
- 普通java类
- 集合(需要借助TypeReference<T> 实现)
示例:
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<>();
map.put("age", 25);
map.put("name", "yitian");
map.put("interests", new String[]{"pc games", "music"});
String text = mapper.writeValueAsString(map);
System.out.println(text);
Map<String, Object> map2 = mapper.readValue(text, new TypeReference<Map<String, Object>>() {
});
System.out.println(map2);
JsonNode root = mapper.readTree(text);
String name = root.get("name").asText();
int age = root.get("age").asInt();
System.out.println("name:" + name + " age:" + age);
结果:
{"name":"yitian","interests":["pc games","music"],"age":25}
{name=yitian, interests=[pc games, music], age=25}
name:yitian age:25
Jackson配置
// 美化输出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
// 允许序列化空的POJO类
// (否则会抛出异常)
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 把java.util.Date, Calendar输出为数字(时间戳)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 在遇到未知属性的时候不抛出异常
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 强制JSON 空字符串("")转换为null对象值:
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
// 在JSON中允许C/C++ 样式的注释(非标准,默认禁用)
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
// 允许没有引号的字段名(非标准)
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// 允许单引号(非标准)
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// 强制转义非ASCII字符
mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
// 将内容包裹为一个JSON属性,属性名由@JsonRootName注解指定
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
注解配置
- 属性使用的注解
@JsonProperty("NickName")//序列化后的json字段为NickName
private String name;
@JsonIgnore //标注的字段不参与序列化
- 实体类使用的注解
1、
//实体类使用的注解,用于序列化的时候忽略指定的一系列属性,或者反序列化的时候忽略未知的属性(没有getter/setter的属性)。
@JsonIgnoreProperties
序列化的时候,@JsonIgnoreProperties({"prop1", "prop2"}),忽略列表中的属性。
反序列化的时候,@JsonIgnoreProperties(ignoreUnknown=true),忽略没有get/set的属性。
2、
//实体类使用的注解,表示该类被忽略。
@JsonIgnoreType
- 公用注解
1、
//实体类/属性使用的注解,用于忽略NULL的属性,空的属性或者NULL的类。
@JsonInclude
2、
//实体类/属性使用的注解,在序列化或者反序列化的时候,指定属性格式化日期/时间。
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",
timezone = "GMT+8")
private Date birthday;
SpringBoot中使用
引入依赖后,直接在yml文件中就可以配置