【问题标题】:Sending array variables using HTTParty使用 HTTParty 发送数组变量
【发布时间】:2014-02-18 14:12:18
【问题描述】:

我正在使用 HTTParty 发送 POST 请求。所需的变量之一是数组。这是我用来发送的代码:

response = HTTParty.post url, :body => 
    {"key"=>'XYZ123',
    "content"=>
        [{"placename"=>"placeholder",
        "placecontent"=>"sample content"}],
    etc. }

API需要看:

"content": [
    {
        "placename": "placeholder",
        "placecontent": "sample content"
    }
],

但是,当我在 API 上检查收到的请求日志时,我看到我的代码正在生成:

"content": [
    {
        "placename": "placeholder"
    },
    {
        "placecontent": "sample content"
    }
],

如何阻止数组记录被一分为二?

谢谢。

编辑: 代码的期望输出相当于:

...&content[0][placename]=placeholder&content[0][placecontent]=sample%20content...

【问题讨论】:

    标签: ruby arrays post httparty


    【解决方案1】:

    默认情况下,HTTParty 使用HashConversionsHash 正文转换为参数:

    示例:

    { :name => "Bob",
      :address => {
        :street => '111 Ruby Ave.',
        :city => 'Ruby Central',
        :phones => ['111-111-1111', '222-222-2222']
      }
    }.to_params
      #=> "name=Bob&address[city]=Ruby Central&address[phones][]=111-111-1111&address[phones][]=222-222-2222&address[street]=111
    

    红宝石大道。”

    您可以使用HTTParty.query_string_normalizer 使用您自己的转换器覆盖它:

    覆盖查询字符串的标准化方式。有助于覆盖 Array 查询的默认 rails 规范化。

    查询:

    get '/', :query => {:selected_ids => [1,2,3]}
    

    默认查询字符串规范化器返回:

    /?selected_ids[]=1&selected_ids[]=2&selected_ids[]=3
    

    让我们把它改成这样:

    /?selected_ids=1&selected_ids=2&selected_ids=3
    

    将 Proc 传递给接受产生的查询的查询规范化器。

    @example 修改数组查询字符串

    class ServiceWrapper
      include HTTParty
    
      query_string_normalizer proc { |query|
        query.map do |key, value|
          value.map {|v| "#{key}=#{v}"}
        end.join('&')
      }
    end
    

    @param [Proc] 规范化器自定义查询字符串规范化器。 @yield [哈希, String] 查询字符串 @yieldreturn [Array] 一个数组,稍后将 加入'&'

    或简单地将其传递给您的选项:

    response = HTTParty.post url, :body => 
        {"key"=>'XYZ123',
        "content"=>
            [{"placename"=>"placeholder",
            "placecontent"=>"sample content"}]},
        :query_string_normalizer => -> (h) { ... your own implementation here ...}
    

    要获得a[1]=val1&a[2]=val2 而不是a[]=val1&a[]=val2 的序列化,您可以基于current one 创建自己的HashConversions

      class MyHashConversions
    
        def to_params(hash)
          params = hash.map { |k,v| normalize_param(k,v) }.join
          params.chop! # trailing &
          params
        end
    
        def normalize_param(key, value)
          param = ''
          stack = []
    
          if value.is_a?(Array)
    
            #### THE CHANGE IS HERE
    
            param << value.each_with_index.map { |element, i| normalize_param("#{key}[#{i}]", element) }.join
    
            ####
          elsif value.is_a?(Hash)
            stack << [key,value]
          else
            param << "#{key}=#{URI.encode(value.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}&"
          end
    
          stack.each do |parent, hash|
            hash.each do |k, v|
              if v.is_a?(Hash)
                stack << ["#{parent}[#{k}]", v]
              else
                param << normalize_param("#{parent}[#{k}]", v)
              end
            end
          end
    
          param
        end
      end
    

    上面的代码没有经过测试,但如果它可以工作,并且足够通用,你可以考虑分叉项目和 github,在那里进行修复,所以它可以开箱即用:)

    【讨论】:

    • 感谢您的帮助。我不确定如何将其应用于我的代码。我将不胜感激在我的代码中应在何处/如何使用它的具体示例。
    • 我不确定您的编码消息应该是什么样子 - 默认数组编码看起来像 my_arr[]=val1&amp;my_arr[]=val2...,默认哈希编码看起来像 my_hash[k1]=v1&amp;my_hash[k2]=v2。数组中的哈希看起来就像有多个带有单个键的哈希 - content[][placecontent]=placeholder&amp;content[][placename]=sample content。您希望它看起来如何?
    • 经过反复试验以获得正确的结构显示在 API 请求日志中,看起来我需要第三个选项 - 数组内的哈希。我已经编辑了问题,添加了所需的编码格式。
    猜你喜欢
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多