13

我正在使用 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 没有结果......总是为空......

谢谢你的帮助!

4

4 回答 4

25

路径参数是与特定模式匹配的请求 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 文档。它有一些特定于供应商的实现细节,但总而言之,它是 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);

这些只是高级示例,请通读我链接的文档以更好地了解每种参数类型如何工作以及何时使用哪一种。

于 2012-04-28T05:58:43.120 回答
6

我刚开始在 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 类型

于 2013-03-08T09:57:31.110 回答
1

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

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

例如POST http://localhost/app?name=Joe,您将 POST http://localhost/app 使用正文发送而不是 :

name=Joe
于 2016-09-09T21:46:11.613 回答
-3

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

JSON 中的正文示例:

{"id":"001","name":"myname"}

XML 中的正文示例:

<tenant><id>001</id><name>myname</name></tenant>
于 2012-05-09T22:30:31.137 回答