服务器端的JSON

日期: 2008-07-14 作者:Brett D. McLaughlinSr 来源:TechTarget中国

  在本系列最近发表的一篇文章中,您已经了解了如何将JavaScript对象转变成JSON格式。这种格式很容易用于发送(和接收)与对象甚至对象数组对应的数据。在本系列的最后一篇文章中,您将会学习如何处理以JSON格式发送到服务器的数据以及如何使用相同格式对脚本进行回复。


  JSON的真正价值


  正如在本系列上一篇文章中所描述的那样,JSON是适用于Ajax应用程序的一种有效格式,原因是它使JavaScript对象和字符串值之间得以快速转换。由于Ajax应用程序非常适合将纯文本发送给服务器端程序并对应地接收纯文本,相比不能生成文本的API,能生成文本的API自然更可取;而且,JSON让您能够处理本地JavaScript对象,而无需为如何表示这些对象多费心思。


  XML也可以提供文本方面的类似益处,但用于将JavaScript对象转换成XML的几个现有API没有JSON API成熟;有时,您必须在创建和处理JavaScript对象时格外谨慎以确保所进行的处理能与所选用的XML会话API协作。但对于JSON,情况就大不相同:它能处理几乎所有可能的对象类型,并会返回给您一个非常好的JSON数据表示。


  因此,JSON的最大价值在于可以将JavaScript真的作为JavaScript而非数据格式语言进行处理。您所学到的所有有关使用JavaScript对象的技巧都可以应用到代码中,而无需为如何将这些对象转变成文本而多费心思。这之后,可以进行如下所示的简单JSON方法调用:


  String myObjectInJSON = myObject.toJSONString();
 
  现在就可以将结果文本发送给服务器了。


  将JSON发给服务器


  将JSON发给服务器并不难,但却至关重要,而且还有一些重要的选择要做。但是,一旦决定使用JSON,所要做的这些选择就会十分简单而且数量有限,所以您需要考虑和关注的事情不多。重要的是能够将JSON字符串发送给服务器,而且最好能做到尽快和尽可能简单。


  通过GET以名称/值对发送JSON


  将JSON数据发给服务器的最简单方法是将其转换成文本,然后以名称/值对的值的方式进行发送。请务必注意,JSON格式的数据是相当长的一个对象,看起来可能会如清单1所示:


  清单1. JSON格式的简单JavaScript对象
               
  var people =  { “programmers”: [    { “firstName”: “Brett”,   ”lastName”:”McLaughlin”,
  ”email”: “brett@newInstance.com” },    { “firstName”: “Jason”,   ”lastName”:”Hunter”,
  ”email”: “jason@servlets.com” },    { “firstName”: “Elliotte”,   ”lastName”:”Harold”,
  ”email”: “elharo@macfaq.com” }   ],  “authors”: [    { “firstName”: “Isaac”,
  ”lastName”: “Asimov”, “genre”: “science fiction” },    { “firstName”: “Tad”,
  ”lastName”: “Williams”, “genre”: “fantasy” },    { “firstName”: “Frank”,
  ”lastName”: “Peretti”, “genre”: “christian fiction” }   ],  “musicians”: [   
  { “firstName”: “Eric”, “lastName”: “Clapton”, “instrument”: “guitar” },  
  { “firstName”: “Sergei”, “lastName”: “Rachmaninoff”, “instrument”: “piano” }   ]  }
 
  如果要以名称/值对将其发送到服务器端,应该如下所示:


  var url = “organizePeople.php?people=” + people.toJSONString();
  xmlHttp.open(“GET”, url, true);
  xmlHttp.onreadystatechange = updatePage;
  xmlHttp.send(null);
 
  这看起来不错,但却存在一个问题:在JSON数据中会有空格和各种字符,Web浏览器往往要尝试对其继续编译。要确保这些字符不会在服务器上(或者在将数据发送给服务器的过程中)引起混乱,需要在JavaScript escape()函数中做如下添加:


  var url = “organizePeople.php?people=” + escape(people.toJSONString());
  request.open(“GET”, url, true);
  request.onreadystatechange = updatePage;
  request.send(null);
 
  该函数可以处理空格、斜线和其他任何可能影响浏览器的内容,并将它们转换成Web可用字符(比如,空格会被转换成%20,浏览器并不会将其视为空格处理,而是不做更改,将其直接传递到服务器)。之后,服务器会(通常自动)再把它们转换回它们传输后的本来 “面目”。


  这种做法的缺点有两个:


  ·在使用GET请求发送大块数据时,对URL字符串有长度限制。虽然这个限制很宽泛,但对象的JSON字符串表示的长度可能超出您的想象,尤其是在使用极其复杂的对象时更是如此。
  ·在跨网络以纯文本发送所有数据的时候,发送数据面临的不安全性超出了您的处理能力。


  简言之,以上是GET请求的两个限制,而不是简单的两个与JSON数据相关的事情。在想要发送用户名和姓之外的更多内容,比如表单中的选择时,二者可能会需要多加注意。若要处理任何机密或极长的内容,可以使用POST请求。


  利用POST请求发送JSON数据


  当决定使用POST请求将JSON数据发送给服务器时,并不需要对代码进行大量更改,如下所示:


  var url = “organizePeople.php?timeStamp=” + new Date().getTime();
  request.open(“POST”, url, true);
  request.onreadystatechange = updatePage;
  request.setRequestHeader(“Content-Type”, “application/x-www-form-urlencoded”);
  request.send(people.toJSONString());
 
  这些代码中的大部分,您都在“掌握Ajax,第3部分:Ajax中的高级请求和响应” 中见过,应该比较熟悉,第3部分重点介绍了如何发送POST请求。请求使用POST而非GET打开,而且Content-Type头被设置为让服务器预知它能得到何种数据。在这种情况下,即为application/x-www-form-urlencoded,它让服务器知道现在发送的是文本,正如它从常规的HTML表单中得到的一样。


  另一个简单提示是URL的末尾追加了时间。这就确保了请求不会在它第一次被发送后即缓存,而是会在此方法每次被调用后重新创建和重发;此URL会由于时间戳的不同而稍微有些不同。这种技巧常被用于确保到脚本的POST每次都会实际生成新请求且Web服务器不会尝试缓存来自服务器的响应。


  JSON就只是文本


  不管使用GET还是POST,关键之处在于JSON就只是文本。由于不需要特殊编码而且每个服务器端脚本都能处理文本数据,所以可以轻松利用JSON并将其应用到服务器。假如JSON是二进制格式的或是一些怪异的文本编码,情况就不这么简单了;幸好JSON只是常规的文本数据(正如脚本能从表单提交中所接收到的数据,在POST段和Content-Type头中亦可以看出),所以在将数据发送到服务器时无需太费心。


  在服务器上解释JSON


  一旦您编写完客户端JavaScript代码、允许用户与Web表单和Web页的交互、收集发送给服务器端程序以做处理所需的信息,此时,服务器就成为了应用程序(如果调用了异步使用的服务器端程序,则可能是我们认为的所谓的“Ajax应用程序”)中的主角。在此时,您在客户端所做的选择(比如使用JavaScript对象,然后将其转换成JSON字符串)必须要与服务器端的选择相匹配,比如使用哪个API解码JSON数据。


  处理JSON的两步骤


  不管在服务器端使用何种语言,在服务器端处理JSON基本上就需要两个步骤。


  ·针对编写服务器端程序所用的语言,找到相应的JSON解析器/工具箱/帮助器API。
  ·使用JSON解析器/工具箱/帮助器API取得来自客户机的请求数据并将数据转变成脚本能理解的东西。


  以上差不多就是目前所应了解的大致内容了。接下来,我们对每个步骤进行较为详细的介绍。


  寻找JSON解析器


  寻找JSON解析器或工具箱最好的资源是JSON站点(有关链接,请参阅参考资料)。在这里,除了可以了解此格式本身的方方面面之外,还可以通过各种链接找到JSON的各种工具和解析器,从ASP到Erlang,到Pike,再到Ruby,应有尽有。您只需针对自己编写脚本所用的语言下载相应的工具箱即可。为了让服务器端脚本和程序能够使用此工具箱,可以根据情况对其进行选择、扩展或安装(如果在服务器端使用的是C#、PHP或Lisp,则可变性更大)。


  例如,如果使用的是PHP,可以简单将其升级至PHP 5.2并用它完成操作;在PHP这个最新版本默认包含了JSON扩展。实际上,那也是在使用PHP时处理JSON的最好方法。如果使用的是Java servlet,json.org上的org.json包显然就是个不错的选择。在这种情况下,可以从JSON Web站点下载json.zip并将其中包含的源文件添加到项目构建目录。编译完这些文件后,一切就就绪了。对于所支持的其他语言,同样可以使用相同的步骤;使用何种语言取决于您对该语言的精通程度,最好使用您所熟悉的语言。


  使用JSON解析器


  一旦获得了程序可用的资源,剩下的事就是找到合适的方法进行调用。比如,假设为PHP使用的是JSON-PHP模板:


  // This is just a code fragment from a larger PHP server-side script
require_once(’JSON.php’);


  $json = new Services_JSON();


  // accept POST data and decode it
  $value = $json->decode($GLOBALS[’HTTP_RAW_POST_DATA’]);


  // Now work with value as raw PHP
 
  通过该模板,可将获得的所有数据(数组格式的、多行的、单值的或JSON数据结构中的任何内容)转换成原生PHP格式,放在$value变量中。


  如果在servlet中使用的是org.json包,则会使用如下代码:


  public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {


    StringBuffer jb = new StringBuffer();
    String line = null;
    try {
      BufferedReader reader = request.getReader();
      while ((line = reader.readLine()) != null)
        jb.append(line);
    } catch (Exception e) { //report an error }


    try {
      JSONObject jsonObject = new JSONObject(jb.toString());
    } catch (ParseException e) {
      // crash and burn
      throw new IOException(“Error parsing JSON request string”);
    }


    // Work with the data using methods like…
    // int someInt = jsonObject.getInt(“intParamName”);
    // String someString = jsonObject.getString(“stringParamName”);
    // JSONObject nestedObj = jsonObject.getJSONObject(“nestedObjName”);
    // JSONArray arr = jsonObject.getJSONArray(“arrayParamName”);
    // etc…
  }
 
  可以参考org.json包文档(有关链接,请参阅参考资料部分)以了解详细信息。(注意:如果想要获得有关org.json或其他JSON工具箱的详细信息,可以给我发电子邮件。您的来信会有助于我决定将来大概写的内容!)


  结束语


  至此,您应该从技术角度对如何在服务器端处理JSON有了基本的把握。本篇文章和本系列的第10部分 不仅提供了技术层面的帮助,而且还向您展示了JSON是一种多么灵活、强大的数据格式。即使您不会在每个应用程序中都使用JSON,但优秀的Ajax和JavaScript程序员的工具箱中总少不了JSON以备不时之需。


  我当然很希望能够分享您的JSON使用经验以及您对何种语言更善于在服务器端处理JSON数据的高见。您可以访问Java和XML新闻组(有关链接,请参阅参考资料部分)跟我联系。享受JSON和文本数据格式的乐趣吧。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • JSON如何开发API?

    随着开发者遭遇像企业之间业务对业务连接这类的应用对应用问题,他们的第一反应往往是,“这里为什么我们不能用一个API就行了呢?”

  • 云计算究竟是否威胁到了硬件业?

    虚拟化和云计算是目前存储、服务器和网络行业的关键的方面。许多企业正在提供虚拟化的环境或者鼓励人们采用云计算以便 […]

  • API设计如龙生九子 各不相同

    IT咨询管理公司CA Technologies对API产业做了个问卷调查,问卷内容涉及API设计风格以及管理部署的新动向。调查结果表明,JSON与XML可谓两分天下。

  • 如何结合REST和JSON构建API

    构建web可访问应用编程接口很简单,但使之良好工作,而且不间断却不简单,那么难点在哪里?