当前位置: 首页 > 面试题库 >

Sinatra控制器params方法在JSON发布请求中变为空

程举
2023-03-14
问题内容

我有一个Sinatra应用程序,并且在我的大多数控制器中,json都会传入并在params对象中自动获取。但是,除非我用before方法来拉取request.body参数,否则我将获得一个根本不获取参数的后期操作.body参数将它们解析为JSON并将它们合并到params哈希中。

这是控制器以及filter方法:

before do
  if request.request_method == "POST"
    body_parameters = request.body.read
    params.merge!(JSON.parse(body_parameters))
  end
end


post '/locations/new' do
  content_type :json
  puts "params after post params method = #{params.inspect}"
  ... other code ...
end

我看到的输出基本上是,控制器操作中的参数实际上正确地位于其中。但是,如果我注释掉before调用,则参数为空。

之前本身感觉就像是黑客。我希望这些参数无论如何都会出现…我必须在那里做错什么,但我不知道那是什么。

任何帮助将不胜感激…


问题答案:

为了回答这个问题,我们首先必须查看一些HTTP请求(仅是简单的telnet“消息”;可以很容易地手动创建)。首先,提交普通的HTML会发生什么<form>?该POST请求看起来将与此非常相似(可能带有一些额外的参数,但是我们现在不必担心这一点):

POST /submit-form HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 12

name=JohnDoe

逐个字符地键入该字符(用/sample-form任何形式操作的URL
替换URL,并Host用您的IP或主机名替换该字符)将与您的浏览器发送的内容相同。要学习的重要内容是参数语法:formname=formvalue
Sinatra 使用此语法将POST请求的内容解释为params哈希!因此,与此基本不兼容的JSON请求将因此 不会
显示在params哈希中。


但是,您在before街区中所做的事情显示了正确的解决方案。虽然params从上面将是{'name' => 'JohnDoe'}request.body.read将返回原始主体,name=JohnDoe

知道了这一点,就可以理解为什么您的“
hacky”解决方案起作用了:POST请求的原始主体由解释JSON.parse,然后插入到空params哈希中。看起来很笨拙的原因是因为params在此示例中是不必要的中间人。以下应完成此工作:

post '/locations/new' do
    @json = JSON.parse(request.body.read)
    # @json now contains a hash of the submitted JSON content
end

但是,采用更好做法的解决方案要么仅在提供JSON内容时响应,要么在提交标准表单时做出不同响应。如上述示例HTTP
POST请求所示,HTML表单使用application/x-www-form- urlencodedMIME类型标识,而JSON使用标识application/json



 类似资料:
  • 在我的控制器中,我有一个用以下映射映射的方法:@PostMapping(“/”)。 此方法需要一个我试图捕获的请求主体,如下所述: 使用这两种方法对我来说都很好,我只是进退两难,如果直接在实体类中接受请求体是一个好主意和最佳实践的话。 我不想在controller类中公开我的实体类,因为我不确定这是否是一个好主意。 java 这两种方法都给出了相同的结果,更多的是关注要遵循的最佳实践。

  • 问题内容: 我试图实现对包含复杂对象作为参数的控制器操作方法的JQueryAJAX调用。我读了很多博客,并尝试了从中学习到的几种技巧。 我想触发一个异步发布,当用户在某个字段上制表符时调用该异步发布(不是表单保存发布–如我发现的其他示例所示)。 我的意图是: 在客户端上实例化一个对象(不是为View提供类型的ViewModel); 使用视图中多个字段中的数据填充对象; 将此对象转换为JSON; 使

  • 我正在开发我的第一个基于spring的项目样本。下面是我的dispatcher-servlet.xml的摘录。 我尝试向以下url发布帖子,但它似乎从未到达相应的控制器类: 网址: post<code>{“testID”:“1”} 就是回应。 为什么我得到400错误,尽管一切似乎都在地方?

  • 我可以在POST请求时发送对象列表作为响应,并在VueJs客户端中接收它 但是当我尝试用自定义类响应时(我甚至在请求映射注释中添加了) 在axios的帮助下发送VueJs端请求。邮递 Vue用户界面客户端接收 为什么我可以用对象列表响应而不能用POJO响应,以及如何解决这个问题?非常感谢。 PS.项目依赖于jackson-数据库v2.8.2和Spring v4.3.1

  • 问题内容: 因此,我得到了以下内容,这些内容似乎难以置信,我一直在想自己Go的库设计得比此更好,但是我找不到Go处理JSON数据POST请求的示例。它们都是POST形式。 这是一个示例请求: 这是代码,其中嵌入了日志: 必须有更好的方法,对吗?我只是为寻找最佳实践而感到困惑。 (Go在搜索引擎中也被称为Golang,在这里提到它,以便其他人可以找到它。) 问题答案: 请使用代替。

  • 我有一个Java动态web项目(部署在本地应用服务器Tomcat 7上),它使用Jersey创建REST API。 我不使用任何构建自动化工具(所以我的库被添加到构建路径中,servlet被插入到web.xml文件中)。 我正在使用的库包括: 我的web.xml如下: 应用程序正在与MySQL数据库交互。场景如下:数据库包含一个名为user的用户帐户表。列是id、name、username和密码。