2011-05-27 45 views
12

我想在json中对简单字符串进行编码/解码,但是出现错误。在rails中解码JSON简单字符串引发错误

在栏杆2.3。红宝石1.8.6,它曾经工作。

>> puts ActiveSupport::JSON.decode("abc".to_json) 
abc 
=> nil 

在rails 3.1beta1 w/ruby​​ 1.9.2中,会产生一个错误。

ruby-1.9.2-p180 :001 > puts ActiveSupport::JSON.decode("abc".to_json) 
MultiJson::DecodeError: 706: unexpected token at '"abc"' 
    from /home/stevenh/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:147:in `parse' 
    from /home/stevenh/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/json/common.rb:147:in `parse' 
    from /home/stevenh/.rvm/gems/ruby-1.9.2-p180/gems/multi_json-1.0.1/lib/multi_json/engines/json_gem.rb:13:in `decode' 
    [...] 

这是相当多的nil.to_json cannot be parsed back to nil?

讨论同样的问题,但无使用2.3/1.8.7的工作为好。

puts ActiveSupport::JSON.decode(nil.to_json) 
nil 

这是新常态吗?

+1

由于字符串 “abc” 是无效的JSON一个DecodeError似乎是适当的我。 – polarblau 2011-05-28 12:54:47

+1

我必须同意@polarblau,尤其是因为: ruby​​-1.9.2-p180:012> ActiveSupport :: JSON.decode({:abc =>“test”}。to_json) => {“abc”= >“test”} – Yardboy 2011-06-06 18:34:58

+0

@polarblau,@Yardboy:我不同意:'ActiveSupport :: JSON.decode(“abc”.to_json)'解码'“\”abc \“”'而不是“abc”。问题在于解码器对于简单的字符串无法正常工作。 – moritz 2011-06-17 18:17:58

回答

8

此更改发生在Rails 3.1.0.rc1中包含的switch from ActiveSupport's JSON backend to MultiJson中。每MultiJson project team,目前的行为是正确的和以前的实现是错误的,由于JSON语法RFC4627的规格:尝试解码时

2. JSON Grammar 

    A JSON text is a sequence of tokens. The set of tokens includes six 
    structural characters, strings, numbers, and three literal names. 

    A JSON text is a serialized object or array. 

     JSON-text = object/array 

既不​​也不"/"abc/""序列化对象或数组,错误他们是适当的。

JSON website的图表强化了这个规范。

话虽这么说,这似乎意味着在to_json执行导致的错误:

ruby-1.9.2-p180 :001 > "abc".to_json 
=> "\"abc\"" 
1

是,什么Rails3中正在发生的事情是新的常态。你所说明的变化看起来像是一个成熟框架的反映。

“decode”方法名为“encode”&预计应完全符合the JSON spec,并且相互颠倒。

另一方面,String#to_json是行为ish类型的方法,用作构建更复杂的JSON对象的便利,假设Array#to_json或Hash#to_json遇到String值时(在ActiveSupport中)作为他们的组成部分之一。

0

如果您需要还原行为遵循these steps,即

# in your Gemfile 
gem 'yajl-ruby' 

# in your application.rb 
require 'yajl/json_gem' 

后这些步骤:

Loading development environment (Rails 3.2.8) 
[1] pry(main)> puts ActiveSupport::JSON.decode("abc".to_json) 
abc 
=> nil 
[2] pry(main)> puts ActiveSupport::JSON.decode(nil.to_json) 

=> nil