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

时间:2012-04-27 19:57:19

标签: java json rest post jersey

我正在使用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 个答案:

答案 0 :(得分:23)

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

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

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

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

我上面描述的是 一般 规则。现在关于你的情况的具体情况,我在你的代码中注意到的一件事是你实际上没有定义任何路径参数。请记住,在使用REST方法之前,必须将它们定义为@Path注释的一部分:

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

通过上述更改,假设您已在客户端对URL进行了正确编码,则参数不应再显示为null。


*编辑*

根据您的评论,我发现您需要更熟悉JAX-RS规范和各种参数类型。我建议阅读RESTEasy JAX-RS Documentation。它有一些供应商特定的实现细节,但总的来说是JAX-RS的优秀指南。


@PathParam

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

示例 :根据网址 http://services.example.com/contacts/20578 ,我可以定义:

@Path("/contacts/{id}")

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

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

这适用于任何类型的HTTP请求( GET POST PUT DELETE )。


@QueryParam

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

示例:给定网址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,以获得每个参数类型如何工作的更好示例,以及何时使用哪一个。

答案 1 :(得分: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类型

答案 2 :(得分:1)

我发布这个作为对已接受答案的评论,但我只是羞于能够做到这一点。

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

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

name=Joe

答案 3 :(得分:-2)

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

JSON中的正文示例:

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

XML中的正文示例:

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