0

JSON で応答するレガシー Rails 1.2.6 アプリで Web サービスを構築しています。URL エンコードされたパラメーターではなく、JSON も受け入れるようにしようとしています。

これをコントローラーに入れました:

param_parsers[Mime::JSON] = lambda { |data| JSON.parse(data) }

正常に動作する残りのクライアントが送信するため、これは機能しません。

Content-Type: application/json; charset=utf-8

ご覧のとおり、文字エンコーディングは Content-Type ヘッダーに追加されますが、Rails 1.2 は "Content-Type" ヘッダー全体で単純な文字列比較を行い、"charset=utf-8" 部分によって破棄されます。

rails-1.2/gems/gems/actionpack-1.13.6/lib/action_controller/request.rb

def content_type
  @content_type ||=
    begin
      content_type = @env['CONTENT_TYPE'].to_s.downcase

      if x_post_format = @env['HTTP_X_POST_DATA_FORMAT']
        case x_post_format.to_s.downcase
        when 'yaml'
          content_type = 'application/x-yaml'
        when 'xml'
          content_type = 'application/xml'
        end
      end

      Mime::Type.lookup(content_type)
    end
end

rails-1.2/gems/gems/actionpack-1.13.6/lib/action_controller/mime_type.rb

  def lookup(string)
    LOOKUP[string]
  end

mime_type.rb ファイルの下部:

LOOKUP["application/json"]         = JSON
LOOKUP["text/x-json"]              = JSON

@env['CONTENT_TYPE'] は "application/json; charset=utf-8" です

Mime::Type.lookup(content_type) は単に LOOKUP[content_type] を返しますが、これは一致しません。これは、その時点でコンテンツ タイプにまだ「; charset=utf-8」が追加されているためです。

content_type から charset=utf-8 を取り除く必要があるのはどこですか? これをどのように修正しますか?Rails3 ではどのように動作するのでしょうか?

4

1 に答える 1

1

答えは、parse_formatted_pa​​rameters() のコードを読むことから得られました。ラムダを使用してブロックを作成しましたが、この Rails コードは特に Proc を探します。

私はちょうど変更しました

param_parsers[Mime::JSON] = lambda { |data| JSON.parse(data) }

param_parsers[Mime::JSON] = Proc.new { |data| JSON.parse(data) }

そして今、すべてが期待どおりに機能します。私はそれをラムダに戻し、paramsが再び空になり、Procに戻って再び機能しました。

奇妙なことに、そのコード フラグメントが機能する解決策を私に与えたとしても、それは問題ではないようです。

>> case Proc.new{}; when Proc; "a"; when :xml_simple; "b" end
"a"
>> case lambda{}; when Proc; "a"; when :xml_simple; "b" end 
"a"

rails-1.2/gems/gems/actionpack-1.13.6/lib/action_controller/cgi_ext/cgi_methods.rb

def parse_formatted_request_parameters(mime_type, raw_post_data)
  case strategy = ActionController::Base.param_parsers[mime_type]
    when Proc
      strategy.call(raw_post_data)
    when :xml_simple
      raw_post_data.blank? ? {} : Hash.from_xml(raw_post_data)
    when :yaml
      YAML.load(raw_post_data)
    when :xml_node
      node = XmlNode.from_xml(raw_post_data)
      { node.node_name => node }
  end
于 2012-04-30T21:24:11.270 に答える