Json

JSON: 是JavaScript Object Notation(JavaScript 对象表示法),它是一种数据交换格式。

JSON 是存储和交换文本信息的语法。类似 XML。

JSON 比 XML 更小、更快,更易解析。

 

JSON基础结构

因为JSON使用JavaScript语法,所以无需额外的软件就能处理JavaScript中的JSON。

JSON还规定了字符集必须是UTF-8 。为了统一解析,JSON的字符串规定必须用双引号"",Object的键也必须用双引号""

在JSON中,一共就这么几种数据类型:

  • number:和JavaScript的number完全一致;
  • boolean:就是JavaScript的truefalse
  • string:就是JavaScript的string;
  • null:就是JavaScript的null;
  • array:就是JavaScript的Array表示方式——[]
  • object:就是JavaScript的{ ... }表示方式。

把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。

如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了。

JSON对象结构

语法:var obj = {"键" : "值","键" : "值","键" : "值"}

说明:obj 指的是json对象,对象结构以 { 开头,到 } 结束。其中键名和值之间用冒号构成对,键值对用逗号分隔。

注意,这里的键名是字符串,但是值可以是数字、字符串、布尔值、数组、对象和null。

JSON数组结构

语法:var arr = [ {"键名" : "值","键名" : "值"}, {"键名" : "值","键名" : "值"} ]

说明:arr指的是json数组,数组结构是以 [ 开始,到 ] 结束。在JSON数组中,每一对 { } 相当于一个JSON对象。

 

特殊情况

1. JSON 不能存储 Date 对象。

① 如果要存储 Date 对象,需要将其转换为字符串。之后再将字符串转换为 Date 对象。

var text = '{ "name":"Runoob", "birthday":"2013-12-14"}';
var obj = JSON.parse(text);
obj.birthday = new Date(obj.birthday); 
$('#demo').text("姓名: " obj.name + "生日: " + obj.birthday);

② js将从后台得到的时间戳(毫秒数)转换为日期格式。

var date = new Date( data.time ) ; //括号里的data就是后端传回来的格式有问题的时间数据
dateFormat= date .toLocaleString(); //默认格式为" 年 / 月 / 日 上/ 下午 时:分:秒 "

如果希望转换为" 年-月-日 时:分:秒 "的格式,可以自己定义一个方法。

function add0(m) {
    return m < 10 ? '0' + m : m;
}
function formatDate(timeStamp) {
    let time = new Date(timeStamp),
    y = time.getFullYear(),
    m = time.getMonth() + 1,
    d = time.getDate(),
    h = time.getHours(),
    mm = time.getMinutes(),
    s = time.getSeconds();
    return y + '-' + add0(m) + '-' + add0(d) + ' ' + add0(h) + ':' + add0(mm) + ':' + add0(s); 
    //顾名思义,将小于10的时间前面加个0,即9:5:43改成09:05:43
}
}

2. JSON 不允许包含函数,但你可以将函数作为字符串存储,之后再将字符串转换为函数。

var text = '{ "name":"Runoob", "alexa":"function () {return 10000;}", "site":"www.runoob.com"}';
var obj = JSON.parse(text);
obj.alexa = eval("(" + obj.alexa + ")");
document.getElementById("demo").innerHTML = obj.name + " Alexa 排名:" + obj.alexa();

 

JSON序列化与反序列化

JSON,大部分是用来处理JavaScript和Web服务端之间的数据交换,把后台Web服务端的数据传递到前台,然后使用JavaScript语法进行处理,例如Ajax等。

由于JSON语法是Javascript语法的子集,JavaScript函数 eval() 可用于将JSON文本转换为JavaScript对象。

 

前端中的JSON序列化

1. JavaScript对象序列化成JSON格式的字符串

var obj= {
    name: 'mephisto',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};

① var str = obj.toJSONString();
② var str = JSON.stringify(obj);  

要输出得好看一些,可以加上参数,按缩进输出:

JSON.stringify(mephisto, null, '  ');
{
  "name": "mephisto",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

第二个参数用于控制如何筛选对象的键值,如果我们只想输出指定的属性,可以传入Array;

JSON.stringify(mephisto, ['name', 'skills'], '  ');
{
  "name": "小明",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}

 还可以传入一个函数,这样对象的每个键值对都会被函数先处理:

function convert(key, value) {
    if (typeof value === 'string') {
        return value.toUpperCase();
    }
    return value;
}

JSON.stringify(xiaoming, convert, '  ');

上面的代码把所有属性值都变成大写:

{
  "name": "mephisto",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" MIDDLE SCHOOL",
  "skills": [
    "JAVASCRIPT",
    "JAVA",
    "PYTHON",
    "LISP"
  ]
}

如果我们还想要精确控制如何序列化,可以给mephisto定义一个toJSON()的方法,直接返回JSON应该序列化的数据:

var xiaoming = {
    name: 'mephisto',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
    toJSON: function () {
        return { // 只输出name和age,并且改变了key:
            'Name': this.name,
            'Age': this.age
        };
    }
};

JSON.stringify(xiaoming); // '{"Name":"mephisto","Age":14}'

2. JSON格式的字符串反序列化成一个JavaScript对象

  var str = '{ "name" : "logo" , "age" : 12}';
                           
① var obj = eval( "(" + str + ")" );    必须把文本包含在括号中,这样才能避免语法错误。
② var obj = JSON.parse(str);
③ var obj = str.parseJSON();    需要JSON.js文件

JSON.parse() 还可以接收一个函数,用来转换解析出的属性:

var obj = JSON.parse('{"name":"小明","age":14}', function (key, value) {
    if (key === 'name') {
        return value + '同学';
    }
    return value;
});
console.log(JSON.stringify(obj)); // {name: '小明同学', age: 14}

 

net.sf.json-lib 解析

Json-lib 需要的 jar 包:

  • commons-beanutils-1.8.3.jar
  • commons-collections-3.2.1.jar
  • commons-lang-2.6.jar
  • commons-logging-1.1.1.jar
  • ezmorph-1.0.6.jar
  • json-lib-2.4-jdk15.jar

依赖:

<dependency>
    <groupId>net.sf.json-lib</groupId>
    <artifactId>json-lib</artifactId>
    <!-- 下面两个必须要写,且jdk15不能写成别的 -->
    <version>2.4</version>    
    <classifier>jdk15</classifier>
</dependency>

序列化: 

  • JavaBean →→→→ JSON格式字符串
Object obj = new Object();
JSONObject jsonObj = JSONObject.fromObject(obj);
String str = jsonObj.toString();
  • Java数组 / List集合 →→→→ JSON格式字符串
Item[] items = {item1,item2,item3};
List<Person> list = new ArrayList<Person>();
JSONArray jsonArr = JSONArray.fromObject(items);
JSONArray jsonArr = JSONArray.fromObject(list);
String str = jsonArr.toString();
  • Java的Map集合 →→→→ JSON格式字符串
Map<String,Item> map = new HashMap<String,Item>();
JSONObject jsonObject = JSONObject.fromMap(map); //方式一
JSONObject jsonObject = JSONObject.fromObject(map); //方式二
String str = jsonObject.toString();

反序列化:

  • JSON格式字符串 →→→→ JavaBean / Map
在将 Json 形式的字符串转换为 JavaBean 的时候需要注意 JavaBean 中必须有无参构造函数。
String jsonObject = "{'name':'李书豪','age':24}";
Person person = (Person) JSONObject.toBean(jsonObject, Person.class);
Map<String, Object> map = (Map<String, Object>) JSONObject.toBean(jsonObject, Map.class);
  • JSON格式字符串 →→→→ Java数组 / List集合
String jsonStr = " [ …… ] ";
JSONArray jsonArr = JSONArray.fromObject(jsonStr);
List<Person> person = (List<Person>) JSONArray.toCollection(jsonArr,Person.class);

 

org.json 解析

 依赖:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <!-- 不写下面的版本会报错 -->
    <version>20170516</version>
</dependency>
  • 序列化:
JSONObject strJson = new JSONObject(jsonStr);    // 传入字符串  
JSONObject beanJson = new JSONObject(student);    // 传入Bean类型  
JSONObject mapJson = new JSONObject(map);    // 传入Map类型  

JSONArray strJson = new JSONArray(jsonStr);    // 传入字符串
JSONArray mapJson = new JSONArray(list);    // 传入Collection类型  
JSONArray arrayJson = new JSONArray(numlist);    // 传入Array类型
  • 反序列化:
JSONObject jObject=jsonArray2.getJSONObject(user);
Student student=new Student(jObject.getInt("id"), jObject.getString("name"),jObject.getInt("age"));

JSONArray jsonArray = new JSONArray(json);  
for (int i = 0; i < jsonArray.length(); i++) {  
    jsonObject = jsonArray.getJSONObject(i);  
    String name = jsonObject.getString("name");  
    int age = jsonObject.getInt("age");  
   }
  • JSONObject 根据Key获取Value值
// 创建JSON解析对象
JSONObject obj = new JSONObject(jsonObj);
// obj.后面有各种数据类型,根据对象来选择使用的数据类型
String name = obj.getString("name");
// 同理如上,这里的age为Int类型,我们就用对应的类型进行解析
int age = obj.getInt("age");
  •  JSONObject 添加JSON
//向json对象中添加JavaBean对象或者任意类型数据
JSONObject testObj2 = jsonObject.put("name", "fyj");
  • JSONArray 遍历
JSONArray jArray = new JSONArray(jsonArr);
for (int i = 0; i < jArray.length; i++) {
    String string = jArray.getString(i);
}
  •  向JSONArray中添加JSON对象
JSONObject obj1 = new JSONObject(object1);
JSONObject obj2 = new JSONObject(object2);
jArray.add(obj1);
jArray.add(obj2);

 

Gson 解析

GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。

主要特点:

  • 快速、高效
  • 代码量少、简洁
  • 面向对象
  • 数据传递和解析方便

Gson提供了fromJson() 和toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化。 

依赖:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
</dependency>

基本类型的序列化

Gson gson = new Gson();
String jsonNumber = gson.toJson(100);       // 100
String jsonBoolean = gson.toJson(false);    // false
String jsonString = gson.toJson("String"); //"String"

Java Bean、List、Map序列化成 Json字符串

Gson gson = new Gson();
String str = gson.toJson(obj);

List<PersonJson> list = new ArrayList<>();
Map<String,PersonJson> map = new HashMap<>();
String str = gson.toJson(list);
String str = gson.toJson(map)

基本类型的反序列化

Gson gson = new Gson();
int i = gson.fromJson("100", int.class); //100
double d = gson.fromJson("99.99", double.class);  //99.99
boolean b = gson.fromJson("true", boolean.class);     // true
String str = gson.fromJson("str", String.class);   // String

 json字符串反序列化为JavaBean

Gson gson = new GsonBuilder().create();
PersonJson p = gson.fromJson(jsonStr,PersonJson.class);

json字符串反序列化为List集合

Gson gson = new GsonBuilder().create();
List<PersonJson> list = gson.fromJson(listJsonStr,new TypeToken<ArrayList<PersonJson>>(){}.getType());

 

Jackson 解析

Jackson是一个简单基于Java应用库,Jackson可以轻松的将Java对象转换成json对象和xml文档,同样也可以将json、xml转换成Java对象。Jackson所依赖的jar包较少,简单易用并且性能也要相对高些,并且Jackson社区相对比较活跃,更新速度也比较快。

主要特点:

  • 容易使用 - jackson API提供了一个高层次外观,以简化常用的用例。
  • 无需创建映射 - API提供了默认的映射大部分对象序列化。
  • 性能高 - 快速,低内存占用,适合大型对象图表或系统。
  • 干净的JSON - jackson创建一个干净和紧凑的JSON结果,这是让人很容易阅读。
  • 不依赖 - 库不需要任何其他的库,除了JDK。
  • 开源代码 - jackson是开源的,可以免费使用。

依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>

创建实体类:

/**
 * @Description: JSON序列化和反序列化User类
 * 
 */
public class User {

    /**
     * JSON注解 Jackson提供了一系列注解,方便对JSON序列化和反序列化进行控制,下面介绍一些常用的注解。
     * 
     * @JsonIgnore 此注解用于属性上,作用是进行JSON操作时忽略该属性。
     * @JsonFormat 此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd
     *             HH-mm-ss")。
     * @JsonProperty 此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name,@JsonProperty("name")。
     */

    @JsonIgnore
    private Integer id;
    @JsonProperty("name")
    private String trueName;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date birthday;
    private String email;
    。。。省略getset方法、toString()方法等

序列化: 

User u1 = new User();
u1.setId(1);
u1.setTrueName("curry");
u1.setAge(30);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
u1.setBirthday(dateFormat.parse("1988-9-21"));
u1.setEmail("138@163.com");
        
/** 
 * ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。 
 * ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。 
 * writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。 
 * writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。 
 * writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。 
 * writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。 
 */
 ObjectMapper mapper = new ObjectMapper();
//User对象转Json,
String jsonValue = mapper.writeValueAsString(u1);
System.out.println(jsonValue);
//输出{"age":30,"birthday":"1988-09-20 16:00:00","email":"138@163.com","name":"curry"}
//List集合转Json
List<User> users = new ArrayList<>();
users.add(u1);
users.add(u2);
String jsonList = mapper.writeValueAsString(users);
System.out.println(jsonList);
//输出[{"age":30,"birthday":"1988-09-20 16:00:00","email":"138@163.com","name":"curry"},{"age":29,"birthday":"1989-09-20 16:00:00","email":"123@qq.com","name":"KD"}]

反序列化:

/** 
 * ObjectMapper支持从byte[]、File、InputStream、字符串等数据的JSON反序列化。 
 */  
String json = " {\"id\":3, \"name\":\"小明\", \"age\":18, \"birthday\":590774400000, \"email\":\"xiaomin@sina.com\"} ";  
ObjectMapper mapper2 = new ObjectMapper();
User user = mapper2.readValue(json, User.class);
System.out.println(user.toString());
//输出User [id=null, trueName=小明, age=18, birthday=Wed Sep 21 00:00:00 CST 1988, email=xiaomin@sina.com]

 

FastJson 解析

fastJson是由阿里巴巴开发的一个Java语言编写的高性能功能完善的JSON库。它采用一种“假定有序快速匹配”的算法,把JSON Parse的性能提升到极致,是目前Java语言中最快的JSON库。fastJson接口简单易用,已经被广泛使用在缓存序列化、协议交互、Web输出、Android客户端等多种应用场景。

主要特点:

  • 快速FAST (比其它任何基于Java的解析器和生成器更快,包括jackson)
  • 强大(支持普通JDK类包括任意Java Bean Class、Collection、Map、Date或enum)
  • 零依赖(没有依赖其它任何类库除了JDK)

依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.37</version>
</dependency>

序列化:

  • 序列化Java Bean
String objJson = JSON.toJSONString(Object object);

// 缺省情况下fastJSON不序列化值为Null的字段
User user = new User();
user.setTrueName("李四");
user.setAge(24);
String userJson = JSON.toJSONString(user);
System.out.println(userJson); //{"age":24,"trueName":"李四"}
user.setId(111);
userJson = JSON.toJSONString(user);
System.out.println(userJson); //{"age":24,"id":111,"trueName":"李四"}
user.setEmail("98@98");
//传入一个boolean值,可以输出格式化后的 JSON 字符串
userJson = JSON.toJSONString(user,true);
System.out.println(userJson);
{
	"age":24,
	"email":"98@98",
	"id":111,
	"trueName":"李四"
}
  • 序列化list集合 
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
         
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("key1", "One");
map1.put("key2", "Two");
         
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("key1", "Three");
map2.put("key2", "Four");
         
list.add(map1);
list.add(map2);
String listJson = JSON.toJSONString(list);
//输出 [{"key1":"One","key2":"Two"},{"key3":"Three","key4":"Four"}]
  • 序列化Map
Map<String, Object> map = new HashMap<String, Object>();
map.put("key1", "One");
map.put("key2", "Two");
String mapJson = JSON.toJSONString(map,true);

 fastJson 的几个常用特性:

  • 日期格式化

fastJson可以直接对日期类型格式化,在缺省的情况下,fastJson会将Date转成long。

String dateJson = JSON.toJSONString(new Date());
System.out.println(dateJson); //1401370199040

使用SerializerFeature特性格式化日期。

String dateJson = JSON.toJSONString(new Date(), SerializerFeature.WriteDateUseDateFormat);
System.out.println(dateJson); //"2014-05-29 21:36:24"

也可以指定输出日期格式。

String dateJson = JSON.toJSONStringWithDateFormat(new Date(), "yyyy-MM-dd HH:mm:ss.SSS");
System.out.println(dateJson); //"2014-05-29 21:47:00.154"
  • 使用单引号
String listJson = JSON.toJSONString(list, SerializerFeature.UseSingleQuotes);
// 输出:[{'key1':'One','key2':'Two'},{'key3':'Three','key4':'Four'}]
  • 格式化
String listJson = JSON.toJSONString(list, SerializerFeature.PrettyFormat);
  • 输出null字段
String listJson = JSON.toJSONString(map, SerializerFeature.WriteMapNullValue);
// {"a":null,"b":1}
  • 序列化时写入类型信息
User user = new User();
user.setAge(18);
user.setUserName("李四");
String listJson = JSON.toJSONString(user, SerializerFeature.WriteClassName);
// 输出结果:{"@type":"User","age":18,"userName":"李四"}
// 由于序列化带了类型信息,使得反序列化时能够自动进行类型识别。

将上面的例子反序列化
User user1 = (User) JSON.parse(listJson);
System.out.println(user1.getAge());
// 输出18
// 如果User序列化时没有加入类型信息(SerializerFeature.WriteClassName),按照上面的做法就会报错(java.lang.ClassCastException)。

反序列化:

  • 对象反序列化
User user1 = JSON.parseObject(userJson, User.class);
System.out.println(user1.getTrueName());
System.out.println(user1);
// 李四
// User [id=111, trueName=李四, age=24, birthday=null, email=98@98]
  • 集合反序列化
List<User> list1 = JSON.parseArray(listJson, User.class);
  • Map反序列化
Map<String, Object> map1 = JSON.parseObject(mapJson, new TypeReference<Map<String, Object>>(){});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
11-01 4万+

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mephisto180502

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值