好吧,这将有点难以解释,所以请耐心等待…
我有一个Rails应用程序,其中包含一个为ESRI ArcGIS javascript API编写的大型javascript代码库,用于与存储在ESRI ArcGISServer上的空间数据交互。ESRI ArcGIS javascript API使用通常称为"ArcGIS服务器代理"的东西将请求转发到ArcGIS服务器服务,这些请求需要基于令牌的身份验证,或者太长而无法直接在URL中处理。AGS代理只需向传递给它的URL发出HTTP请求,并将与原始请求一起传递的任何附加参数转发给ArcGIS服务器服务,ArcGIS服务器服务器服务会完成实际的繁重工作并使用JSON进行响应。有关AGS代理的更多信息,请参阅ArcGIS资源中心的下一页。
鉴于AGS代理仅由ESRI在ASP.Net、Java和PHP版本中提供,我可以自由地编写一个AGS代理作为Rails控制器。我之所以选择这种方法,是因为JSAPI不支持跨域请求,而且出于托管原因,我不想在Rails应用程序中提供PHP,也不想在JRuby上运行我的应用程序。到目前为止,我的Rails AGS代理可以在我遇到的所有情况下工作,除了多部分请求,这些请求与附件编辑器功能一起出现,如图所示。
在我尝试让多部分请求工作时,我选择使用Faraday向ArcGIS服务器服务发出HTTP请求,因为Faraday的简单性和对多部分请求的支持。我尝试执行多部分请求的代码如下:
# Configure the request
uri = URI.parse(url)
conn = Faraday.new(:url => ("http://" + uri.host.downcase)) do |faraday|
faraday.request :multipart
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
# Make request
response = conn.post uri.path do |req|
req.body = agsparams
end
"agsparams"变量是传递给ArcGIS服务器的参数的散列。
当试图执行这段代码时,Ruby在发出实际请求的那一行出错,并出现以下错误,这就是我目前所处的位置:
NoMethodError (undefined method `local_path' for #ActionDispatch::Http::UploadedFile:0x007ffbe198fe60
当我在控制器中转储params散列时,它看起来类似于以下内容:
{
"attachment"=>#ActionDispatch::Http::UploadedFile:0x007ffbe198fe60
@original_filename="test_image.jpg",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name="attachment"; filename="test_image.jpg"rnContent-Type: image/jpegrn",
@tempfile=#File:/var/folders/mh/2mfy5nr54gngrzg06gzp1jcw0000gn/T/RackMultipart20120718-2772-xwbgjy,
"f"=>"json",
"http://arcgisserver.com/arcgis/rest/services/multitenant/test_organization/FeatureServer/0/4808/addAttachment"=>nil
}
(我去掉了一些括号,这样它就会显示在StackOverflow上。)
我不知道"local_path"方法在哪里被调用,因为我没有调用它,但我猜测这是某种与ActionDispatch相关的内置功能,我不理解。ActionDispatch中是否有我需要重写的方法,如果有,我该怎么做?我有一种预感,ActionDispatch正在尝试上传我指定的文件,而我真的只想将文件输入参数转发到ArcGIS Server,以便ArcGIS Server进行上传。我不想使用Faraday::UploadIO,因为我认为我只需要将参数转发到ArcGIS服务器,但我可能错了。我该何去何从??
作为额外的尽职调查,我已经确认我的映射javascript可以与其他风格的AGS代理一起使用;我还检查了使用Wireshark处理的多部分代理请求,并将这些请求与使用我的Rails AGS代理进行的请求进行了比较,它们看起来是一致的(头和参数看起来很正确)。事实上,我试图添加附件的数据已正确配置为接受附件。我被卡住了,真的需要一些帮助。
关于我的环境:我的应用程序是用Ruby1.9.2上的Rails 3.2编写的(如果这很重要的话,我目前使用CarrierWave和Fog来处理应用程序其他非映射部分的附件)。我试图通过ArcGIS JSAPI 2.8/Dojo 1.6发布到运行ArcGIS server 10.1的服务器上。
提前感谢。。。
Net::HTTP
,并在需要执行多部分请求时使用多部分postgem。Net::HTTP::Post::Multipart
接受一个UploadIO
对象,所以我只需打开附件临时文件,并将其用作POST请求中的参数。问题解决了。
我知道我参加聚会有点晚了,但我想我应该把这个发布在这里作为参考。
我目前正在做一个项目,该项目使用Rails作为外部API服务器的中间件。我们的Rails服务器从客户端接收到的许多请求都经过了验证、身份验证,并提供了适当的头,以访问外部API。当然,我一直在使用Faraday向API发出请求,并遇到了这个问题(特别是图像上传)。我找不到通过un-manipuled传递请求的方法,但我可以单独使用Faraday传递请求,并使用Faraday::UploadIO
对象将其传递给外部API,以通过Rails代理图像数据。我在这里创建了一个GitHub Gist:
https://gist.github.com/mjquinlan2000/10929611