我希望我在Ruby on Rails中的JSON输出“漂亮”或格式化得很好。
现在,我调用to_json,我的JSON都在一行上。有时,很难看出JSON输出流中是否有问题。
有办法配置,使我的JSON“漂亮”或很好的格式在Rails?
我希望我在Ruby on Rails中的JSON输出“漂亮”或格式化得很好。
现在,我调用to_json,我的JSON都在一行上。有时,很难看出JSON输出流中是否有问题。
有办法配置,使我的JSON“漂亮”或很好的格式在Rails?
当前回答
下面是根据@gertas的回答修改的中间件解决方案。这个解决方案不是Rails特有的——它应该适用于任何Rack应用程序。
这里使用的中间件技术,使用#each,由Eifion Bedford在ASCIIcasts 151: Rack middleware中进行了解释。
这段代码放在app/middleware/pretty_json_response.rb中:
class PrettyJsonResponse
def initialize(app)
@app = app
end
def call(env)
@status, @headers, @response = @app.call(env)
[@status, @headers, self]
end
def each(&block)
@response.each do |body|
if @headers["Content-Type"] =~ /^application\/json/
body = pretty_print(body)
end
block.call(body)
end
end
private
def pretty_print(json)
obj = JSON.parse(json)
JSON.pretty_unparse(obj)
end
end
要打开它,将其添加到config/environments/test中。config/environments/development.rb:
config.middleware.use "PrettyJsonResponse"
正如@gertas在他的解决方案版本中警告的那样,避免在生产中使用它。有点慢。
使用Rails 4.1.6测试。
其他回答
以下是我在搜索过程中从其他帖子中得到的解决方案。
这允许您根据需要将pp和jj输出发送到文件中。
require "pp"
require "json"
class File
def pp(*objs)
objs.each {|obj|
PP.pp(obj, self)
}
objs.size <= 1 ? objs.first : objs
end
def jj(*objs)
objs.each {|obj|
obj = JSON.parse(obj.to_json)
self.puts JSON.pretty_generate(obj)
}
objs.size <= 1 ? objs.first : objs
end
end
test_object = { :name => { first: "Christopher", last: "Mullins" }, :grades => [ "English" => "B+", "Algebra" => "A+" ] }
test_json_object = JSON.parse(test_object.to_json)
File.open("log/object_dump.txt", "w") do |file|
file.pp(test_object)
end
File.open("log/json_dump.txt", "w") do |file|
file.jj(test_json_object)
end
使用<pre> HTML代码和pretty_generate是一个好技巧:
<%
require 'json'
hash = JSON[{hey: "test", num: [{one: 1, two: 2, threes: [{three: 3, tthree: 33}]}]}.to_json]
%>
<pre>
<%= JSON.pretty_generate(hash) %>
</pre>
漂亮的打印变体(Rails):
my_obj = {
'array' => [1, 2, 3, { "sample" => "hash"}, 44455, 677778, nil ],
foo: "bar", rrr: {"pid": 63, "state with nil and \"nil\"": false},
wwww: 'w' * 74
}
require 'pp'
puts my_obj.as_json.pretty_inspect.
gsub('=>', ': ').
gsub(/"(?:[^"\\]|\\.)*"|\bnil\b/) {|m| m == 'nil' ? 'null' : m }.
gsub(/\s+$/, "")
结果:
{"array": [1, 2, 3, {"sample": "hash"}, 44455, 677778, null],
"foo": "bar",
"rrr": {"pid": 63, "state with nil and \"nil\"": false},
"wwww":
"wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww"}
多亏了机架中间件和Rails 3,你可以为每个请求输出漂亮的JSON,而无需更改应用程序的任何控制器。我已经编写了这样的中间件片段,我在浏览器和curl输出中得到了漂亮的打印JSON。
class PrettyJsonResponse
def initialize(app)
@app = app
end
def call(env)
status, headers, response = @app.call(env)
if headers["Content-Type"] =~ /^application\/json/
obj = JSON.parse(response.body)
pretty_str = JSON.pretty_unparse(obj)
response = [pretty_str]
headers["Content-Length"] = pretty_str.bytesize.to_s
end
[status, headers, response]
end
end
上面的代码应该放在app/middleware/pretty_json_response中。您的Rails项目的rb。 最后一步是在config/environments/development.rb中注册中间件:
config.middleware.use PrettyJsonResponse
我不建议在生产中使用它。JSON的重新解析可能会降低你的产品应用的响应时间和吞吐量。最终,额外的逻辑,如'X-Pretty-Json: true'头可能会被引入,以触发手动curl请求按需格式化。
(在Rails 3.2.8-5.0.0, Ruby 1.9.3-2.2.0, Linux下测试)
使用pretty_generate()函数,该函数内置于JSON的后期版本中。例如:
require 'json'
my_object = { :array => [1, 2, 3, { :sample => "hash"} ], :foo => "bar" }
puts JSON.pretty_generate(my_object)
这就得到了:
{
"array": [
1,
2,
3,
{
"sample": "hash"
}
],
"foo": "bar"
}