开发者

HTTP post request via Ruby

I'm very new to ruby and trying some basic stuff. When I send HTTP request to the server using:

curl -v -H "Content-Type: application/json" -X GET -d "{"myrequest":"myTest","reqid":"44","data":{"name":"test"}}" localhost:8099

My server sees JSON data as "{myrequest:myTest,reqid:44,data:{name:test}}"

But when I send the request using the following ruby code:

require 'net/http'

@host = 'localhost'
@port = '8099'

@path = "/posts"

@body = ActiveSupport::JSON.encode({
    :bbrequest => "BBTest", 
    :reqid => "44", 
    :data => 
    {
        :name => "test"
    }
})

request = Net::HTTP::Post.new(@path, initheader =开发者_运维知识库 {'Content-Type' =>'application/json'})
request.body = @body
response = Net::HTTP.new(@host, @port).start {|http| http.request(request) }
puts "Response #{response.code} #{response.message}: #{response.body}"

It sees it as "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}" and server is unable to parse it. Perhaps there are some extra options I need to set to send request from Ruby to exclude those extra characters?

Can you please help. Thanks in advance.


What you are doing on the shell produces invalid JSON. Your server should not accept it.

  $echo "{"myrequest":"myTest","reqid":"44","data":{"name":"test"}}"
      {myrequest:myTest,reqid:44,data:{name:test}}

This is JSON with unescaped keys and values, will NEVER work. http://jsonlint.com/ If your server accept this "sort of kind of JSON" but does not accept the second one in your example your server is broken.

My server sees JSON data as "{myrequest:myTest,reqid:44,data:{name:test}}"

Your server sees a string. When you will try to parse it into JSON it will produce an error or garbage.

It sees it as "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}"

No this is how it's printed via Ruby's Object#inspect. You are printing the return value of inspect somewhere and then trying to judge whether it's valid JSON - it is not, since this string you've pasted in is made to be pasted into the interactive ruby console (irb) or into a ruby script, and it contains builtin escapes. You need to see your JSON string raw, just print the string instead of inspecting it.

I think your server is either broken or not finished yet, your curl example is broken and your ruby script is correct and will work once the server is fixed (or finished). Simply because

  irb(main):002:0> JSON.parse("{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\" test\"}}")
        # => {"bbrequest"=>"BBTest", "reqid"=>"44", "data"=>{"name"=>" test"}}


Your problem is something other than the existence of escape characters in the string. Those are not put in by the code you show, but by irb or .inspect. If you put in a simple puts @body in your code (or in a Rails context, logger.debug @body), you'll see this. Here's an irb session showing the difference:

ruby-1.9.2-p180 :002 > require 'active_support'
 => true 
ruby-1.9.2-p180 :003 > json = ActiveSupport::JSON.encode({
ruby-1.9.2-p180 :004 >           :bbrequest => "BBTest", 
ruby-1.9.2-p180 :005 >           :reqid => "44", 
ruby-1.9.2-p180 :006 >           :data => 
ruby-1.9.2-p180 :007 >           {
ruby-1.9.2-p180 :008 >                 :name => "test"
ruby-1.9.2-p180 :009?>           }
ruby-1.9.2-p180 :010?>     })
 => "{\"bbrequest\":\"BBTest\",\"reqid\":\"44\",\"data\":{\"name\":\"test\"}}" 
ruby-1.9.2-p180 :013 > puts json
{"bbrequest":"BBTest","reqid":"44","data":{"name":"test"}}
 => nil 

In any case, the best way to do json encoding in Rails is not to call ActiveSupport::JSON.encode directly, but rather override as_json in your model or use the serializable_hash feature. This will make your code cleaner as well. See the top answers to this stackoverflow question for details.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜