好先生。 如何强制request.body(或任何其他非JSON字符串)以漂亮的多行JSON或yaml样式打印出来?
我已经看到了将这些字符串转换为真正的JSON的奇特方法,但希望避免使用另一种方法。
def request_token_from_google
uri = URI.parse('https://www.googleapis.com/oauth2/v3/token')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(self.to_params)
puts "request body is"
puts request.body.to_yaml # doesn't work
puts request.body.to_json # doesn't work
http.request(request)
end
答案 0 :(得分:2)
这个问题:
ap "request body is #{request.body.to_json}"
...而你的其他尝试是你试图打印出已经是字符串的东西。 awesome_print(和inspect
及其同类)的目的是获取具有某种结构的对象并打印它以便您可以看到它的结构,但是字符串没有结构 - 它只是字符,性格,性格。当您为awesome_print提供类似"request body is {"foo":...
的字符串时,它无法知道"之后的部分有什么特别之处。"
如果你有一个具有结构的对象,解决方案是直接将它提供给awesome_print:
puts "request body is:"
ap my_hash_or_array
不幸的是,在这种情况下,它无法提供帮助,因为request.body
只是一个字符串,它也是形式编码的数据,就像这样(从{{3}中偷来的) }):
Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21
就像"request body is..."
示例一样,awesome_print无法知道这有什么特别之处。您可以做的一件非常简单的事情就是在每个键/值对之间添加换行符:
body = "Name=Jonathan+Doe&Age=23&Formula=a+%2B+b+%3D%3D+13%25%21"
puts "Request body is:"
puts body.gsub("&", "\n &")
# => Request body is:
# Name=Jonathan+Doe
# &Age=23
# &Formula=a+%2B+b+%3D%3D+13%25%21
这有一个缺点,即值仍然是百分比编码的,正如您在Formula
的情况下所看到的那样。如果这是一个问题,您可以使用CGI.parse
或Rack::Utils.parse_query
解析表单数据,这两个都可以在Rails中使用。它们都返回一个你可以提供给awesome_print的Hash,但格式略有不同(CGI将所有值作为数组返回,Rack :: Util只有在它们处于" array"格式时才会这样做,例如{{ 1}})。这里的Rack :: Utils(您只需要想象输出是彩色的):
foo[]=1&foo[]=2
最后,一些未经请求的建议:puts "Request body is:"
ap Rack::Utils.parse_query(body)
# => Request body is:"
# {
# "Name" => "Jonathan Doe",
# "Age" => "23",
# "Formula" => "a + b == 13%!"
# }
和puts
,写入STDOUT,往往在开发中工作正常,因为Rails' logger也写入STDOUT,因此您可以在与Rails服务器日志相同的终端窗口中看到ap
输出。但是,在生产中,写入STDOUT的数据可能无法在任何地方写入文件,即使是,如果您在某个时刻更改puts
配置,Rails.logger
的输出也可能还在去别的地方。你可能想要的是使用Rails'记录器而不是ap
或puts
,因此您可以确保所有输出都转到同一位置。幸运的是,awesome_print为每个对象添加了一个ap
方法,它会返回您在使用awesome_inspect
时看到的相同的字符串,因此您仍然可以将awesome_print与ap
一起使用:
Rails.logger