json 解析

本文介绍iOS平台上的JSON解析方法,重点讲解NSJSONSerialization类的使用技巧。包括如何生成JSON格式数据及将JSON数据转换为Foundation对象的过程。


JSON数据结构以其轻量化的结构体和良好的可读性被越来越广泛的运用,特别在移动开发上,手机的流量是宝贵资源,更要求使用轻量级的数据格式进行数据传输。关于在iOS平台上进行JSON解析,已经有很多第三方的开源项目,比如SBJson、JSONFramwork等,用的也非常广泛,自从iOS5.0以后,苹果推出了SDK自带的JSON解决方案NSJSONSerialization,这是一个非常好用的JSON生成和解析工具,效率也是比其他第三方开源项目的高很多,详情可查看Developer Guider


关于NSJSONSerialization,官方文档中有如下介绍:

You use the NSJSONSerialization class to convert JSON to Foundation objects and convert Foundation objects to JSON.

An object that may be converted to JSON must have the following properties:

  • The top level object is an NSArray or NSDictionary.

  • All objects are instances of NSStringNSNumberNSArrayNSDictionary, or NSNull.

  • All dictionary keys are instances of NSString.

  • Numbers are not NaN or infinity.

我们能利用NSJSONSerialization将JSON转换成Foundation对象,也能将Foundation对象转换成JSON,转换成JSON的对象必须具有如下属性:

  • 顶层对象必须是NSArray或者NSDictionary
  • 所有的对象必须是NSString、NSNumber、NSArray、NSDictionary、NSNull的实例
  • 所有NSDictionary的key必须是NSString类型
  • 数字对象不能是非数值或无穷
接下来看看如何使用,首先是如何生成JSON格式的数据:
我这里选用项目中的代码片段来进行简要介绍,以下显示了登陆请求JSON格式数据的生成

NSDictionary中的key就是json字符串中的key,object就是json字符串中的value,isValidJSONObject:方法是检测Foundation对象能否合法转换为JSON对象,dataWithJSONObject:options:error 方法是将Foundation对象转换为JSON对象,参数NSJSONWritingPrettyPrinted的意思是将生成的json数据格式化输出,这样可读性高,不设置则输出的json字符串就是一整行。

    NSError *error;
    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://m.weather.com.cn/data/101010100.html"]];
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    
    NSDictionary *weatherInfoDic = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:
                                    &error];
    NSDictionary *weatherInfo = [weatherInfoDic objectForKey:@"weatherinfo"];
    
    self.weather.text = [NSString stringWithFormat:@"%@\n%@\n%@\n%@\n%@\n",[weatherInfo objectForKey:@"city"],[weatherInfo objectForKey:@"date_y"],[weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"weather1"],[weatherInfo objectForKey:@"temp1"]];



以上代码打印结果如下:

2013-12-11 14:38:52.799 jsonTest[604:a0b] Register json:{
  "_id" : "test",
  "word" : "passWord",
  "loginName" : "username"
}


下面是如何将json格式的数据转化为foundation对象类型。


    NSError *error;
   
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"
http://m.weather.com.cn/data/101010100.html"]];
    NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
   
    NSDictionary *weatherInfoDic = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:
                                    &error];
    NSDictionary *weatherInfo = [weatherInfoDic objectForKey:@"weatherinfo"];
   
    self.weather.text = [NSString stringWithFormat:@"
%@\n%@\n%@\n%@\n%@\n",[weatherInfo objectForKey:@"city"],[weatherInfo objectForKey:@"date_y"],

    [weatherInfo objectForKey:@"week"],[weatherInfo objectForKey:@"weather1"],[weatherInfo objectForKey:@"temp1"]];

   

    NSLog(@"weatherInfo 字典里面的内容为-->%@",weatherInfoDic);


    结果打印为:

     2013-12-11 14:38:52.797 jsonTest[604:a0b] weatherInfo 字典里面的内容为--> {
    weatherinfo =     {
        city = "\U5317\U4eac";
        "city_en" = beijing;
        cityid = 101010100;
        date = "";
        "date_y" = "2013\U5e7412\U670811\U65e5";
        fchh = 11;
        fl1 = "\U5c0f\U4e8e3\U7ea7\U8f6c3-4\U7ea7";
        fl2 = "3-4\U7ea7";
        fl3 = "\U5c0f\U4e8e3\U7ea7";
        fl4 = "\U5c0f\U4e8e3\U7ea7";
        fl5 = "\U5c0f\U4e8e3\U7ea7";
        fl6 = "\U5c0f\U4e8e3\U7ea7";
        fx1 = "\U5fae\U98ce";
        fx2 = "\U5317\U98ce";
        img1 = 0;
        img10 = 1;
        img11 = 1;
        img12 = 99;
        img2 = 99;
        img3 = 0;
        img4 = 99;
        img5 = 0;
        img6 = 99;
        img7 = 0;
        img8 = 99;
        img9 = 0;
        "img_single" = 0;
        "img_title1" = "\U6674";
        "img_title10" = "\U591a\U4e91";
        "img_title11" = "\U591a\U4e91";
        "img_title12" = "\U591a\U4e91";
        "img_title2" = "\U6674";
        "img_title3" = "\U6674";
        "img_title4" = "\U6674";
        "img_title5" = "\U6674";
        "img_title6" = "\U6674";
        "img_title7" = "\U6674";
        "img_title8" = "\U6674";
        "img_title9" = "\U6674";
        "img_title_single" = "\U6674";
        index = "\U8f83\U51b7";
        index48 = "\U51b7";
        "index48_d" = "\U5929\U6c14\U51b7\Uff0c\U5efa\U8bae\U7740\U68c9\U670d\U3001\U7fbd\U7ed2\U670d\U3001\U76ae\U5939\U514b\U52a0\U7f8a\U6bdb\U886b\U7b49\U51ac\U5b63\U670d\U88c5\U3002\U5e74\U8001\U4f53\U5f31\U8005\U5b9c\U7740\U539a\U68c9\U8863\U3001\U51ac\U5927\U8863\U6216\U539a\U7fbd\U7ed2\U670d\U3002";
        "index48_uv" = "\U5f31";
        "index_ag" = "\U6781\U4e0d\U6613\U53d1";
        "index_cl" = "\U9002\U5b9c";
        "index_co" = "\U8f83\U8212\U9002";
        "index_d" = "\U5efa\U8bae\U7740\U539a\U5916\U5957\U52a0\U6bdb\U8863\U7b49\U670d\U88c5\U3002\U5e74\U8001\U4f53\U5f31\U8005\U5b9c\U7740\U5927\U8863\U3001\U5462\U5916\U5957\U52a0\U7f8a\U6bdb\U886b\U3002";
        "index_ls" = "\U57fa\U672c\U9002\U5b9c";
        "index_tr" = "\U9002\U5b9c";
        "index_uv" = "\U4e2d\U7b49";
        "index_xc" = "\U9002\U5b9c";
        st1 = 5;
        st2 = "-4";
        st3 = 2;
        st4 = "-5";
        st5 = 4;
        st6 = "-4";
        temp1 = "6\U2103~-3\U2103";
        temp2 = "3\U2103~-6\U2103";
        temp3 = "4\U2103~-6\U2103";
        temp4 = "5\U2103~-4\U2103";
        temp5 = "5\U2103~-4\U2103";
        temp6 = "5\U2103~-3\U2103";
        tempF1 = "42.8\U2109~26.6\U2109";
        tempF2 = "37.4\U2109~21.2\U2109";
        tempF3 = "39.2\U2109~21.2\U2109";
        tempF4 = "41\U2109~24.8\U2109";
        tempF5 = "41\U2109~24.8\U2109";
        tempF6 = "41\U2109~26.6\U2109";
        weather1 = "\U6674";
        weather2 = "\U6674";
        weather3 = "\U6674";
        weather4 = "\U6674";
        weather5 = "\U6674\U8f6c\U591a\U4e91";
        weather6 = "\U591a\U4e91";
        week = "\U661f\U671f\U4e09";
        wind1 = "\U5fae\U98ce\U8f6c\U5317\U98ce3-4\U7ea7";
        wind2 = "\U5317\U98ce3-4\U7ea7";
        wind3 = "\U5fae\U98ce";
        wind4 = "\U5fae\U98ce";
        wind5 = "\U5fae\U98ce";
        wind6 = "\U5fae\U98ce";
    };
}

   


NSJSONReadingMutableLeaves 所在枚举中包含的值为:

  NSJSONReadingMutableContainers 
  NSJSONReadingMutableLeaves 
  NSJSONReadingAllowFragments



以下 为  JSONObjectWithData: options: error: 方法的注释。

/* Create a Foundation object from JSON data.

Set theNSJSONReadingAllowFragments option if the parser shouldallow top-level objects that are not an NSArray or NSDictionary.Setting theNSJSONReadingMutableContainers option will make the parsergenerate mutable NSArrays and NSDictionaries

Setting theNSJSONReadingMutableLeaves option will make the parsergenerate mutable NSString objects.

If an error occurs during the parse, then the error parameter will be set and the result will be nil.
  The data must be in one of the 5 supported encodings listed in the JSON specification: UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE. The data may or may not have a BOM. The most efficient encoding to use for parsing is UTF-8, so if you have a choice in encoding the data passed to this method, use UTF-8.
 */


从以上①、② 、③点的说明中,我们应该能很清楚的知道该参数的作用。





   


   










### JSON 数据解析方法 #### 1. Java 中解析 JSON 数据的方法 在 Java 开发中,常用的 JSON 解析方法包括使用 **Jackson**、**Gson** 和 **Fastjson** 等库来处理 JSON 数据。 - **Jackson** 是一个高性能的 JSON 解析库,支持将 JSON 字符串转换为 Java 对象,也可以将 Java 对象序列化为 JSON 字符串。使用 `ObjectMapper` 类可以实现 JSON解析与生成。 - **Gson** 是 Google 提供的一个用于解析和生成 JSON 的库,适用于 Java 对象与 JSON 数据之间的转换。它提供了 `fromJson()` 和 `toJson()` 方法来实现数据的转换。 - **Fastjson** 是阿里巴巴开发的一个高性能 JSON 库,支持将 JSON 字符串解析为 Java 对象,也可以将 Java 对象转换为 JSON 字符串。它提供了 `parseObject()` 和 `parseArray()` 方法来处理 JSON 数据[^1]。 #### 2. 前端解析 JSON 数据的方法 在前端开发中,JavaScript 提供了内置的 JSON 解析方法。 - 使用 `JSON.parse()` 方法可以将 JSON 字符串解析为 JavaScript 对象。例如,`const jsonObj = JSON.parse(jsonStr);`,其中 `jsonStr` 是一个 JSON 格式的字符串。 - 解析后的 JSON 对象可以像普通对象一样进行访问和操作。例如,可以通过 `jsonObj.length` 来获取数组长度,或者通过 `jsonObj.key` 来访问特定字段的值[^2]。 #### 3. JSON 语法与结构 JSON 数据由键值对组成,支持多种数据类型,包括字符串、数字、布尔值、对象、数组和 `null`。 - 示例 JSON 数据: ```json { "name": "zhangsan", "age": 28, "badperson": true, "child": { "name": "zhangxiaosan", "age": 8 }, "job": ["React", "JavaScript"], "wages": null } ``` 该 JSON 对象包含字符串、数字、布尔值、嵌套对象、数组和 `null` 值。在解析过程中,需要确保 JSON 数据格式正确,否则会导致解析失败[^3]。 ### JSON 数据解析常见问题 #### 1. JSON 格式错误 JSON 数据必须遵循严格的格式规范,否则会导致解析失败。常见的格式错误包括缺少逗号、引号不匹配、括号不闭合等。例如,字段名和字符串值必须使用双引号包裹,布尔值和 `null` 不需要引号。 - 错误示例: ```json { name: "zhangsan", age: 28 } // 字段名未使用双引号包裹 ``` - 正确示例: ```json { "name": "zhangsan", "age": 28 } ``` #### 2. 数据类型不匹配 在解析 JSON 数据时,如果目标对象的字段类型与 JSON 数据中的值类型不匹配,可能会导致解析错误或数据丢失。例如,JSON 数据中的数字值被解析为字符串类型,或者布尔值被解析为字符串。 - 解决方法:确保目标对象的字段类型与 JSON 数据中的值类型一致,或者在解析时进行类型转换。 #### 3. 嵌套结构处理不当 JSON 数据可能包含嵌套的对象或数组,处理嵌套结构时需要逐层解析。例如,解析嵌套对象时,需要先获取外层对象,再获取内层对象的字段。 - 示例代码(使用 Jackson 解析嵌套对象): ```java ObjectMapper objectMapper = new ObjectMapper(); String jsonStr = "{ \"name\": \"zhangsan\", \"child\": { \"name\": \"zhangxiaosan\", \"age\": 8 } }"; JsonNode jsonNode = objectMapper.readTree(jsonStr); String childName = jsonNode.get("child").get("name").asText(); // 获取嵌套对象中的字段值 ``` #### 4. 异常处理 在解析 JSON 数据时,可能会遇到异常情况,例如空指针异常、类型转换异常等。为了避免程序崩溃,需要添加异常处理逻辑。 - 示例代码(使用 Gson 解析 JSON 数据并处理异常): ```java try { String jsonStr = "{ \"name\": \"zhangsan\", \"age\": 28 }"; Person person = new Gson().fromJson(jsonStr, Person.class); } catch (JsonSyntaxException e) { System.out.println("JSON 解析失败: " + e.getMessage()); } ``` #### 5. 性能优化 在处理大量 JSON 数据时,解析性能可能会成为瓶颈。为了提高解析效率,可以选择高性能的 JSON 解析库,例如 Jackson 或 Fastjson。此外,避免在循环中频繁解析 JSON 数据,尽量将解析结果缓存起来以减少重复解析的开销。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值