Jersey POST 方法正在接收空值作为参数

Posted

技术标签:

【中文标题】Jersey POST 方法正在接收空值作为参数【英文标题】:Jersey POST Method is receiving null values as parameters 【发布时间】:2012-05-08 13:55:17 【问题描述】:

我正在使用 Jersey 开发 RESTful 服务,它适用于 GET 方法。但是我不能让它与 POST 方法和 JSON 或文本参数一起工作。这就是我所做的:

@Path("/method/")
@POST
@Consumes(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN)
@Produces(MediaType.APPLICATION_JSON)
public ResponseObject method(@Context Request request, @PathParam("ob1") Object obj1, @PathParam("obj2") String obj2) 
...

我只得到所有参数的空值。我试图只使用一个字符串作为参数,但它也不起作用......我试图从 ios 访问这些方法,也许这就是问题之一。但是我一直在嗅探我的局域网,我可以在数据包正文中看到正确的参数......这是正确的吗?

我从 XCode 发送了不同的正文内容:

obj1="id1": "value1", "id2" : "value2"&obj2=xxxx

和:

"id1": "value1", "id2" : "value2",xxxx

虽然我一直在玩 @QueryParam 和 @PathParam 没有结果...总是为空...

感谢您的帮助!

【问题讨论】:

【参考方案1】:

假设我们有一个具有idname 属性的tenant 对象,并且REST 资源通过@POST@PATH("/xyz/tenants") 公开。

JSON 中的正文示例:

"id":"001","name":"myname"

XML 中的正文示例:

<tenant><id>001</id><name>myname</name></tenant>

【讨论】:

【参考方案2】:

我会将此作为对已接受答案的评论发布,但我只是不敢这样做。

除了上述出色的建议之外,我还要补充一点,至少在 2.0.x 版本中,Jersey 不会从查询字符串中提取 @FormParam。相反,它希望将其作为名称-值对包含在请求正文中。

例如,您可以发送 POST http://localhost/app?name=Joe,而不是 POST http://localhost/app 与身体:

name=Joe

【讨论】:

【参考方案3】:

我刚开始在 java 中开发 webservice,并且在 POST 数据方面遇到了同样的问题。 我有一个非常简单的解决方案来使用@FormParam 读取 POST 数据,实际上我是使用@QueryParam 来读取 POST 数据,我认为它仅用于使用 GET 方法读取 QueryString 数据

这里给出了一个非常好的文档。读完这篇文章,我的大部分困惑都被清除了。 http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html_single/index.html

提示:请确保在使用 @FormParam 时使用“application/x-www-form-urlencoded”mime 类型

【讨论】:

【参考方案4】:

路径参数是与特定模式匹配的请求 URL 的一部分。因此,对于可以指定为路径参数的内容存在字符限制 - 特别是任何特殊字符都需要进行 URL 编码。这适用于任何类型的请求(GETPOSTPUTDELETE)。

作为一般规则,您应该将路径参数限制为简单的值,例如标识符或资源端点 - 更复杂的数据应该通过请求参数或请求主体本身传递给 REST 服务。这是一种混合方法,将实体标识符作为路径参数传递,并在请求正文中传递实体数据:

@Path("/contacts/id")
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response updateContact(@PathParam final String contactId, Contact contact) 

在上面的例子中,contactId是作为路径参数获取的,联系人是从请求体中自动序列化的。

我上面描述的是一般规则。现在关于您的案例的细节,我在您的代码中注意到的一件事是您实际上没有定义任何路径参数。请记住,它们必须定义为 @Path 注释的一部分,然后才能在您的 REST 方法中使用:

@Path("/method/obj1/obj2")
public ResponseObject method(@Context Request request, @PathParam("obj1") Object obj1, @PathParam("obj2") String obj2) 

通过上述更改,您的参数不应再显示为空,假设您已在客户端正确编码 URL。


* 编辑 *

根据您的评论,我认为您需要更加熟悉 JAX-RS 规范和各种参数类型。我建议通读RESTEasy JAX-RS Documentation。它有一些特定于供应商的实现细节,但总而言之是 JAX-RS 的极好指南。


@PathParam

目的:用于将请求 URL 的一部分注入到变量中。请注意,URL 参数被视为 URL 的一部分。

示例:给定 URL http://services.example.com/contacts/20578,我可以定义:

@Path("/contacts/id")

我可以从中注入@PathParam("id")

public Response getContact(@PathParam("id") final String identifier);

这适用于任何类型的 HTTP 请求(GETPOSTPUTDELETE )。


@QueryParam

目的:用于将查询字符串的一部分或将编码数据形成一个变量。查询字符串是 URL 中? 之后的部分。当请求类型为 application/x-www-form-urlencoded 时,表单编码数据是在 HTTP 请求正文中传递的 URL 编码名称/值对数据。通常,查询参数作为 GET 请求的 URL 字符串的一部分传递,而对于 POST 请求,则在请求正文中传递。

示例:给定 URL http://services.example.com/contacts?group=Business,我可以注入 @QueryParam("group")

public Response getContactsInGroup(@QueryParam("group") final String groupName);

在 POST 请求中使用查询参数是不典型的,但如果请求类型是 application/x-www-form-urlencoded,则可以:

@POST
@Path("/contacts")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createContact(@QueryParam("contact") final Contact contactData, @QueryParam("metadata") final String metaData);

这些只是高级示例,请通读我链接的documentation 以获得关于每种参数类型如何工作以及何时使用哪一种的更好示例。

【讨论】:

您好 Perception,我没有将参数放在 Path 参数中,因为我使用的是 POST 方法,所以我认为没有必要放置它(它不存在于 URL 中)。如果我将参数放在路径参数中,我没有收到任何到服务器的东西......我认为使用 PathParam 和 QueryParam 只会用于知道如何将参数传递给发布请求......那么球衣期待什么在请求正文中?非常感谢 @Kasas - 这是一个非常广泛的后续问题,我在回答中链接了一些文档,这些文档应该有助于获取更多信息。 感谢@Perception,我一直在阅读它,它让我清楚了一些方面......其中最重要的是你只能在请求正文中处理一个请求参数......所以它以我的方式处理两个参数是不可能的。您必须使用 multipart/mixed 来完成或制作另一种复杂类型(这是我的解决方案)。然而空参数的问题并没有完全解决......明天我会找到解决方案,我会在这里发布;)......我希望!我认为是IOS格式化JSON字符串的方式有问题... 将所有参数放入相同的参数后,一切正常。感谢@Perception 的帮助。我的方法现在使用像 "obj1":"id1": "value1", "id2" : "value2","obj2":"xxxx" 这样的参数,一切都很好:)。

以上是关于Jersey POST 方法正在接收空值作为参数的主要内容,如果未能解决你的问题,请参考以下文章

在 Jackson/Jersey JAVA 上发布带有多个参数 JSON 和 String 的请求

Jersey POST 请求并关闭 InputStream

MVC 方法接收空值

ASP.Net Core Web 应用程序 POST 方法始终接收 NULL 作为参数

OAuth:接收带有参数的回调作为 POST 数据

Jersey写Restful接口获取参数的问题