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

如何在RESTful POST方法中访问参数

黄彬
2023-03-14
问题内容

我的POST方法看起来像这样:

@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String param1, String param2){
    System.out.println("param1 = " + param1);
    System.out.println("param2 = " + param2);
}

当我在Netbeans中创建Jersey客户时,调用post方法的方法如下所示:

public void create(Object requestEntity){
    webResource.path("create").type(MediaType.APPLICATION_JSON).post(requestEntity);
}

运行此测试时:

@Test
public void hello(){
    String json = "{param1=\"hello\",param2=\"hello2\"}";
    this.client.create(json);
}

它在服务器中提供以下输出:

INFO: param1 = {param1="hello",param2="hello2"}
INFO: param2 = 

我需要更改什么才能使参数给出正确的值?


问题答案:

你的@POST方法应该接受JSON对象而不是字符串。Jersey使用JAXB支持封送和拆封JSON对象(有关详细信息,请参阅jersey文档)。创建一个类似的类:

@XmlRootElement
public class MyJaxBean {
    @XmlElement public String param1;
    @XmlElement public String param2;
}

然后,你的@POST方法将如下所示:

@POST @Consumes("application/json")
@Path("/create")
public void create(final MyJaxBean input) {
    System.out.println("param1 = " + input.param1);
    System.out.println("param2 = " + input.param2);
}

此方法希望接收JSON对象作为HTTP POST的主体。JAX-RS input在此情况下将HTTP消息的内容主体作为未注释的参数传递。实际消息如下所示:

POST /create HTTP/1.1
Content-Type: application/json
Content-Length: 35
Host: www.example.com

{"param1":"hello","param2":"world"}

由于明显的原因,以这种方式使用JSON很普遍。但是,如果要使用JavaScript以外的其他方式生成或使用它,则必须注意正确地转义数据。在JAX-RS中,你将使用MessageBodyReader和MessageBodyWriter来实现此目的。我相信Jersey已经具有所需类型(例如Java原语和JAXB包装类)以及JSON的实现。JAX-RS支持许多其他方法来传递数据。这些不需要创建新的类,因为使用简单的参数传递来传递数据。

HTML

参数将使用@FormParam进行注释:

@POST
@Path("/create")
public void create(@FormParam("param1") String param1,
                   @FormParam("param2") String param2) {
    ...
}

浏览器将使用“ application / x-www-form-urlencoded”对表单进行编码。JAX-RS运行时将负责解码主体并将其传递给方法。这是你在网上看到的内容:

POST /create HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 25

param1=hello&param2=world

在这种情况下,内容是URL编码的。

如果你不知道FormParam的名称,则可以执行以下操作:

@POST @Consumes("application/x-www-form-urlencoded")
@Path("/create")
public void create(final MultivaluedMap<String, String> formParams) {
    ...
}

HTTP Headers

如果要通过HTTP标头传递参数,可以使用@HeaderParam批注:

@POST
@Path("/create")
public void create(@HeaderParam("param1") String param1,
                   @HeaderParam("param2") String param2) {
    ...
}

这是HTTP消息的样子。请注意,此POST没有正文。

POST /create HTTP/1.1
Content-Length: 0
Host: www.example.com
param1: hello
param2: world

我不会将此方法用于广义参数传递。不过,如果你需要访问特定HTTP标头的值,这确实非常方便。

HTTP查询参数

此方法主要用于HTTP GET,但同样适用于POST。它使用@QueryParam批注。

@POST
@Path("/create")
public void create(@QueryParam("param1") String param1,
                   @QueryParam("param2") String param2) {
    ...
}

与先前的技术一样,通过查询字符串传递参数不需要消息正文。这是HTTP消息:

POST /create?param1=hello&param2=world HTTP/1.1
Content-Length: 0
Host: www.example.com

你必须特别小心,才能在客户端正确编码查询参数。由于某些代理实施的URL长度限制以及与编码相关的问题,使用查询参数可能会出现问题。

HTTP路径参数

路径参数与查询参数相似,不同之处在于它们嵌入在HTTP资源路径中。今天,这种方法似乎很受欢迎。由于路径是真正定义HTTP资源的路径,因此对HTTPhtml" target="_blank">缓存有影响。该代码看起来与其他代码略有不同,因为已修改@Path批注,并使用@PathParam:

@POST
@Path("/create/{param1}/{param2}")
public void create(@PathParam("param1") String param1,
                   @PathParam("param2") String param2) {
    ...
}

该消息与查询参数版本相似,不同之处在于消息的任何地方均不包含参数名称。

POST /create/hello/world HTTP/1.1
Content-Length: 0
Host: www.example.com

此方法与查询参数版本共享相同的编码问题。 路径段的编码方式不同,因此你也必须在此处格外小心。

如你所见,每种方法各有利弊。选择通常由你的客户决定。如果你正在提供FORM基于HTML的HTML页面,请使用@FormParam。如果你的客户端基于JavaScript + HTML5,则你可能希望使用基于JAXB的序列化和JSON对象。这些MessageBodyReader/Writer实现应为你处理必要的转义操作,以免出错。如果你的客户端基于Java,但没有良好的XML处理器(例如Android),则我可能会使用FORM编码,因为内容主体比URL更易于正确生成和编码。希望这个微型Wiki条目可以阐明JAX-RS支持的各种方法。

注意:为了全面披露,我实际上尚未使用Jersey的此功能。因为我们已经部署了许多JAXB + JAX-RS应用程序,并且正在向移动客户端空间迁移,所以我们对此进行了修补。JSON比XML更好地适合HTML5或基于jQuery的解决方案。



 类似资料:
  • 问题内容: C和派生函数的入口点函数具有和(和)参数,但是Swift没有合适的参数:顶级代码只是代码,并且没有参数。 在Swift程序中,如何访问等价的? 问题答案: 进程 刚刚重命名为 CommandLine (自Swift 3.0 8月4日快照以来) (由于某些原因,变更日志中未提及)

  • 问题内容: 我有一个接受几个参数的静态方法。在方法内部,我正在创建一个新对象并将新的侦听器附加到该对象。问题是侦听器块需要访问外部静态方法变量,但我不知道如何引用它们。我知道如何使用非静态方法来实现此目的,而不是使用静态方法。 这是代码: 星号包围的上下文和意图变量是传递给静态方法的对象。由于OnTouchListener是一个内部块,因此它不知道那些对象。我该如何引用它们? 问题答案: 在创建侦

  • 问题内容: 这是我的一部分: This is the item reader: 这是Spring Batch在运行时所说的: 怎么了 在Spring 3.0中,我在哪里可以了解有关这些机制的更多信息? 问题答案: 如前所述,你的阅读器需要进行“逐步”调整。你可以通过注释完成此操作。如果你将该注释添加到阅读器,则它应该对你有用,如下所示: 该范围默认情况下不可用,但是如果你正在使用XML名称空间,则

  • 我知道如何获取如下查询的参数: 在这种情况下,我可以使用获取参数(例如中的)。 但是,对于类似的url,如何访问变量? 我尝试了,但没有成功。

  • Rust教程没有解释如何从命令行获取参数。在所有示例中,< code>fn main()只显示了一个空参数列表。 从 访问命令行参数的正确方法是什么?

  • 问题内容: 我有一个应用程序,它基本上是服务的代理。该应用程序本身是在Jersey上构建的,由Jetty提供。我有这个资源方法: 用户提交POST表单。所有POST请求都通过此方法。除了一个细节外,UriInfo和HttpServletRequest被适当地注入:似乎没有参数。这是我从终端发送的请求: 此处的POST正文显然包含两个参数:foo和biz。但是,当我尝试在代码()中获取它们时,结果是