【问题标题】:Objective-C JSON-RPC Request issueObjective-C JSON-RPC 请求问题
【发布时间】:2016-10-27 15:29:11
【问题描述】:

我的 JSON-RPC 查询有问题。

NSString *jsonString = @"{id:1,method:getHolidays,jsonrpc:2.0}";
NSString *requestString = [NSString stringWithFormat:@"%@",jsonString,nil];

NSData *requestData = [NSData dataWithBytes: [jsonString UTF8String] length: [requestString length]];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: [NSURL URLWithString:@"https://neilo.webuntis.com/WebUntis/jsonrpc.do?school=htl_v%C3%B6cklabruck"]];

[request setHTTPMethod: @"POST"];
[request setValue:@"Content-type: application/json" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:requestData];

NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil ];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];

NSLog(@"\n\n\noutput: %@",returnString);

结果我得到这个输出:

{"jsonrpc":"2.0","id":null,"error":{"code":-32700,"message":"解析错误:意外字符('i'(代码 105)):期待双引号在 [Source: org.apache.catalina.connector.CoyoteInputStream@7a1efafd; line: 1, column: 3]"}}

处开始字段名称\n

结果应该是: ->message = not-authenticated

有人知道问题出在哪里吗?

【问题讨论】:

  • NSDictionary *jsonDict = @{@"id":@1,@"method":@"getHolidays",@"jsonrpc":@"2.0"}; NSData *jsonData =[NSJSONSerialization dataWithJSONObject:jsonDict options:0 error:&error];... [request setHTTPBody:jsonData]; 如果您将字符串 JSON 复制/粘贴到 JSON 验证器中,您会发现它无效(字符串周围缺少引号)。它应该是{"id": 1,"method": "getHolidays","jsonrpc": 2.0}NSJSONSerialization 会处理它并简化它,因为它是从字典构造的(更容易更改参数)。
  • 是的,知道了! NSString *jsonString = @"{\"id\":\"1\",\"method\":\"getHolidays\",\"jsonrpc\":\"2.0\"}";
  • 我建议使用 NSJSONSerialization 而不是自己构建 JSON 字符串。它更安全(有错误参数,如果它无效,则更容易修改,尤其是可变NSMutableArray/Dictionary,如果有可以添加或不添加的键)。另外,避免sendSynchronousRequest:returningResponse:error:,更喜欢异步的(使用NSURLSession)。

标签: objective-c json json-rpc


【解决方案1】:

期待双引号开始字段名称:

您的服务器告诉您您的 JSON 无效。

如果您在 JSON 验证器(例如 http://jsonlint.com/)上测试 {id:1,method:getHolidays,jsonrpc:2.0},它会告诉您。如前所述,它缺少每个字符串(键/值)的引号:{"id": 1,"method": "getHolidays","jsonrpc": 2.0} 是有效的。

所以,正如您尝试的那样,@"{\"id\":\"1\",\"method\":\"getHolidays\",\"jsonrpc\":\"2.0‌​\"}" 有效。

我建议使用NSJSONSerialization,样本未经测试(可能无法编译):

NSDictionary *jsonDict = @{@"id":@1,
                           @"method":@"getHolidays",
                           @"jsonrpc":@"2.0"};
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:0 error:&error];
...
[request setHTTPBody:jsonData];

你不必转义"(如\"),如果你的参数有条件,比如说if(someReason){doNotPutmethodKeyInJSON},用NSMutableDictionary,这样更容易,也更容易阅读(尤其是带有所有\" 的新字符串使得更难阅读可能存在问题的地方) 此外,如果 JSON 无效,您可以阅读error

我不知道你把代码放在哪里,但如果它是主线程,那会阻塞 UI,所以避免使用 sendSynchronousRequest:returningResponse:error:,更喜欢异步调用(在 NSURLSession 的帮助下)

【讨论】:

  • 感谢您的快速回复,但我不太明白您对 NSURL 会话的意思
  • 这是一个异步处理网络调用的类。有关于它的教程,文档等。
猜你喜欢
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多