【问题标题】:Rails: How to process incoming POST Request in non-json/custom format?Rails:如何以非 json/自定义格式处理传入的 POST 请求?
【发布时间】:2012-08-08 08:37:31
【问题描述】:

我有一个网络服务,它接收来自另一台服务器的传入 POST 请求。请求的字段映射到我的 rails 应用程序中名为“消息”的模型。

当我发送 JSON POST 时

curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d 
'{"message":{"content":"GUESTTEST","time":"2012-08-01     10:30:99","businessNumber":"5555","sessionId":"5555CHS1343808543654"}}'
http://localhost:3000/messages.json

请求被块处理:

respond_to do |format|
  if @message.save
    format.html { redirect_to @message, notice: 'Message was successfully created.' }
    format.json { render json: @message, status: :created, location: @message }
end

并且对象保存成功。

很遗憾,我从其他 Web 服务收到的 POST 请求不是 json 格式,格式如下:

content=GUESTTEST&time=2012-08-01+10%3A09%3A03&businessNumber=5555&sessionId=5555CHS1343808543654

如何编写自己的路由和方法来处理这些请求并将它们映射到我的消息模型?

任何提示将不胜感激!

===== 更新:

我已经通过在控制器中基于顶级参数元素创建对象来解决这个问题,如下所示:

def create
@message = Message.new(content: params[:content], command: params[:command], messageId: params[:messageId], msisdn: params[:msisdn], businessNumber: params[:businessNumber], keyword: params[:keyword], operatorCode: params[:operatorCode], sessionId: params[:sessionId], time: params[:time])

respond_to do |format|
  if @message.save
    format.html { redirect_to @message, notice: 'Message was successfully created.' }
    format.json { render json: @message, status: :created, location: @message }
  else
    format.html { render action: "new" }
    format.json { render json: @message.errors, status: :unprocessable_entity }
  end
end

结束

什么是更优雅的方式来实现这一点?

【问题讨论】:

    标签: ruby-on-rails json http-post


    【解决方案1】:

    您应该在 params 哈希中找到所有参数。您可以通过在适当的视图中插入来输出它们来检查:

    <%= debug(params) if Rails.env.development? %>
    

    虽然可以将它们直接传递给 update_attributes,(或 Message.new,您的代码 sn-p 中缺少该行)我会编写一个自定义方法来清理它们并从参数哈希中初始化新消息.

    【讨论】:

      【解决方案2】:

      respond_to 方法只关心创建请求完成时用于响应客户端的格式。因此,在这里,当您发布到 URI .json 时,它将以 JSON 格式响应。仅发布到 /messages 的相同数据将创建相同的对象,但将以 HTML(或设置的默认值)响应。

      在您的情况下,您收到的 POST 请求采用参数格式,并且与 HTML form 元素发出的数据相同。参数将在 params 变量中,我确信已经存在。

      由于路由与格式无关,所以也不应该改变。

      您可以使用curl 模拟这个 POST 请求,如下所示:

      $ curl -d "content=GUESTTEST&time=2012-08-01+10%3A09%3A03&businessNumber=5555&sessionId=5555CHS1343808543654" http://localhost:3000/messages
      

      【讨论】:

      • 感谢您的快速回复!但是,这对我不起作用(它会创建一个空对象)。我读过 Rails 需要以 curl -d "message[content]=GUESTTEST&message[time]=2012-08-01+10%3A09%3A03&message[businessNumber]=5555&message[sessionId]=5555CHS1343808543654 的形式发送参数" localhost:3000/messages 如何更改它以使其接受上述表单中的请求?
      • 我已经通过使用明确选择的顶级参数元素创建对象来解决它。 (添加到问题中)什么是更优雅的方式来实现这一点?
      • @user191 我想你可以在MessagesController#create 中只用params 替换params[:message],因为它们是直接发送的,但我担心如果某些属性名称可能会产生副作用在 Message 对象上与嵌入在请求中的通常包含的参数发生冲突。它有什么作用?
      • 我已经尝试过了,但它给了我一个错误:无法批量分配受保护的属性:动作,控制器
      • 好吧,如果真的无法修改传入的请求,那完全是另一个问题:如何根据直接作为参数给出的属性创建实体。
      猜你喜欢
      • 2016-11-15
      • 2014-04-17
      • 2011-09-09
      • 2013-02-16
      • 2012-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多