在rails中解码JSON简单的字符串会引起错误

时间:2021-10-16 20:20:26

I'm trying to roundtrip encode/decode plain strings in json, but I'm getting an error.

我正在尝试用json对普通字符串进行编码/解码,但是我得到了一个错误。

In rails 2.3. w/ ruby 1.8.6, it used to work.

在rails 2.3。w/ ruby 1.8.6,它曾经工作过。

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

In rails 3.1beta1 w/ ruby 1.9.2, it raises an error.

在rails 3.1中,它会引发一个错误。

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'
    [...]

This is pretty much the same question discussed at nil.to_json cannot be parsed back to nil?

这和我们在nil时讨论的问题差不多。to_json不能被解析为nil?

But nil used to work in 2.3/1.8.7 as well.

但nil在2。3。1。7中也用过。

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

Is this the new normal?

这是新的常态吗?

3 个解决方案

#1


8  

This change occurred with the switch from ActiveSupport's JSON backend to MultiJson that was included in Rails 3.1.0.rc1. Per the MultiJson project team, the current behavior is correct and the previous implementation was faulty due to RFC4627's specification of the JSON grammar:

这种变化发生在从ActiveSupport的JSON后端到Rails 3.1.0.rc1中包含的多JSON的转换中。对于MultiJson项目团队来说,由于RFC4627对JSON语法的规范,当前的行为是正确的,之前的实现是错误的:

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

As neither "abc" nor "/"abc/"" are serialized objects or arrays, an error when attempting to decode them is appropriate.

由于“abc”和“/ abc/”都不是序列化的对象或数组,因此在试图解码它们时出现错误是适当的。

The diagrams from the JSON website reinforce this specification.

JSON网站的图表加强了这一规范。

That being said, this would seem to imply a bug in the to_json implementation that results in:

也就是说,这似乎暗示了to_json实现中的一个错误,导致:

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

#2


1  

Yes, what is happening in Rails3 is the new normal. The changes you illustrate seem like a reflection of a maturing framework.

是的,在Rails3发生的是新的常态。您所演示的更改似乎是成熟框架的反映。

Methods named "encode" & "decode" should be expected to be perfectly compliant with the JSON spec, and inverses of one another.

命名为“encode”和“decode”的方法应该完全符合JSON规范,并相互进行反向操作。

String#to_json, on the other hand is a behavior-ish type of method that functions as a convenience for building more complex JSON objects presumably used internally (within ActiveSupport) when Array#to_json or Hash#to_json encounter a String value as one of their consituent elements.

另一方面,String#to_json是一种行为类型的方法,它可以方便地构建更复杂的JSON对象(在ActiveSupport中),当数组#to_json或Hash#to_json遇到一个字符串值作为它们的组成元素时。

#3


0  

If you need to restore that behavior follow these steps, i.e.

如果您需要恢复该行为,请遵循以下步骤,即。

# in your Gemfile
gem 'yajl-ruby'

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

After those steps:

在这些步骤:

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

#1


8  

This change occurred with the switch from ActiveSupport's JSON backend to MultiJson that was included in Rails 3.1.0.rc1. Per the MultiJson project team, the current behavior is correct and the previous implementation was faulty due to RFC4627's specification of the JSON grammar:

这种变化发生在从ActiveSupport的JSON后端到Rails 3.1.0.rc1中包含的多JSON的转换中。对于MultiJson项目团队来说,由于RFC4627对JSON语法的规范,当前的行为是正确的,之前的实现是错误的:

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

As neither "abc" nor "/"abc/"" are serialized objects or arrays, an error when attempting to decode them is appropriate.

由于“abc”和“/ abc/”都不是序列化的对象或数组,因此在试图解码它们时出现错误是适当的。

The diagrams from the JSON website reinforce this specification.

JSON网站的图表加强了这一规范。

That being said, this would seem to imply a bug in the to_json implementation that results in:

也就是说,这似乎暗示了to_json实现中的一个错误,导致:

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

#2


1  

Yes, what is happening in Rails3 is the new normal. The changes you illustrate seem like a reflection of a maturing framework.

是的,在Rails3发生的是新的常态。您所演示的更改似乎是成熟框架的反映。

Methods named "encode" & "decode" should be expected to be perfectly compliant with the JSON spec, and inverses of one another.

命名为“encode”和“decode”的方法应该完全符合JSON规范,并相互进行反向操作。

String#to_json, on the other hand is a behavior-ish type of method that functions as a convenience for building more complex JSON objects presumably used internally (within ActiveSupport) when Array#to_json or Hash#to_json encounter a String value as one of their consituent elements.

另一方面,String#to_json是一种行为类型的方法,它可以方便地构建更复杂的JSON对象(在ActiveSupport中),当数组#to_json或Hash#to_json遇到一个字符串值作为它们的组成元素时。

#3


0  

If you need to restore that behavior follow these steps, i.e.

如果您需要恢复该行为,请遵循以下步骤,即。

# in your Gemfile
gem 'yajl-ruby'

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

After those steps:

在这些步骤:

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