简体   繁体   English

通过JSON / XML将二进制数据发送到(Rails)RESTful端点?

[英]Sending binary data to (Rails) RESTful endpoint via JSON/XML?

I am currently putting together a rails-based web application which will only serve and receive data via json and xml. 我目前正在组建一个基于rails的Web应用程序,它只能通过json和xml提供和接收数据。 However, some requirements contain the ability to upload binary data (images). 但是,某些要求包含上载二进制数据(图像)的能力。

Now to my understanding JSON is not entirely meant for that... but how do you in general tackle the problem of receiving binary files/data over those two entrypoints to your application? 现在我的理解JSON并不完全是为了那个......但是你如何解决在你的应用程序的两个入口点上接收二进制文件/数据的问题?

I suggest encoding the binary data in something like base64. 我建议将二进制数据编码为base64。 This would make it safe to use in XML or JSON format. 这样可以安全地使用XML或JSON格式。

http://en.wikipedia.org/wiki/Base64 http://en.wikipedia.org/wiki/Base64

maybe you could have a look on Base64 algorithm. 也许你可以看看Base64算法。 This is used to "transform" everything to ascii char. 这用于将所有内容“转换”为ascii char。 You can code and decode it. 您可以对其进行编码和解码。 It's used for webservices, or even on dotnet Serialization. 它用于web服务,甚至用于dotnet序列化。

Hope this helps a little. 希望这有所帮助。

Edit: I saw "new post", while posting, someone was faster. 编辑:我看到“新帖子”,发帖时,有人更快。 Rails base64 Rails base64

If you are using Rails and json and xml than you are using HTTP. 如果您使用Rails和json和xml而不是使用HTTP。 "POST" is a part of HTTP and is the best way to transform binary data. “POST”是HTTP的一部分,是转换二进制数据的最佳方式。 Base64 is a very inefficient way of doing this. Base64是一种非常低效的方法。

If your server is sending data, I would recommend putting a path to the file on the server in the XML or JSON. 如果您的服务器正在发送数据,我建议在XML或JSON中为服务器上的文件添加路径。 That way your server doesn't have to base64 encode the data and your client, which already supports HTTP GET, can pull down the data without decoding it. 这样,您的服务器就不必对数据进行base64编码,而已经支持HTTP GET的客户端可以在不解码数据的情况下下拉数据。 (GET /path/to/file) (GET / path / to / file)

For sending files, have your server and/or client generate a unique file name and use a two step process; 要发送文件,请让您的服务器和/或客户端生成唯一的文件名并使用两步过程; the client will send the xml or json message with fileToBeUploaded: "name of file.ext" and after sending the message will POST the data with the aforementioned filename. 客户端将使用fileToBeUploaded:“file.ext的名称”发送xml或json消息,并在发送消息后将使用上述文件名POST数据。 Again, client and server won't have to encode and decode the data. 同样,客户端和服务器不必对数据进行编码和解码。 This can be done with one request using a multi-part request. 这可以使用多部分请求通过一个请求完成。

Base64 is easy but will quickly chew up CPU and/or memory depending on the size of the data and frequency of requests. Base64很简单,但会根据数据大小和请求频率快速咀嚼CPU和/或内存。 On the server-side, it's also not an operation which is cached whereas the operation of your web server reading the file from disk is. 在服务器端,它也不是缓存的操作,而是从磁盘读取文件的Web服务器的操作。

If your images are not too large, putting them in the database with a RoR :binary type makes a lot of sense. 如果您的图像不是太大,将它们放在具有RoR:二进制类型的数据库中会非常有意义。 If you have database replicas, the images get copied for free to the other sites, there's no concern about orphaned or widowed images, and the atomic transaction issues become far simpler. 如果您有数据库副本,则图像会被免费复制到其他站点,不用担心孤立或丧偶的图像,并且原子事务问题变得更加简单。

On the other hand, Nessence is right that Base64, as with any encoding layer, does add network, memory and CPU load to the transactions. 另一方面,Nessence是正确的,Base64与任何编码层一样,确实为事务添加了网络,内存和CPU负载。 If network bandwidth is your top issue, make sure your web service accepts and offers deflate/gzip compressed connections. 如果网络带宽是您的首要问题,请确保您的Web服务接受并提供deflate / gzip压缩连接。 This will reduce the cost of the Base64 data on the network layer, albeit at the cost of even more memory and CPU load. 这将降低网络层上Base64数据的成本,尽管代价是更多的内存和CPU负载。

These are architectural issues that should be discussed with your team and/or client. 这些是应该与您的团队和/或客户讨论的架构问题。

Finally, let me give you a heads up about RoR's XML REST support. 最后,让我向您介绍一下RoR的XML REST支持。 The Rails :binary database type will become <object type="binary" encoding="base64">...</object> XML objects when you render to XML using code like this from the default scaffolding: Rails :binary数据库类型将成为<object type="binary" encoding="base64">...</object>当您使用默认脚手架中的代码渲染为XML时的XML对象:

def show
  @myobject = MyObject.find(:id)
  respond_to do |format|
    format.xml { render => @myobject }
  end
end

This works great for GET operations, and the PUT and POST operations are about as easy to write. 这对于GET操作非常有用,PUT和POST操作也很容易编写。 The catch is the Rails PUT and POST operations don't accept the same tags. 问题是Rails PUT和POST操作不接受相同的标签。 This is because the from_xml code does not interpret the type="binary" tag, but instead looks for type="binaryBase64" . 这是因为from_xml代码不解释type="binary"标记,而是查找type="binaryBase64" There is a bug with a patch at the Rails lighthouse site to correct this. 在Rails灯塔站点有一个补丁错误来纠正这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM