Jersey Client / JAX-RS和可选(非默认)@QueryParam(客户端)

问题描述 投票:16回答:2

我有一个RESTful API,他的文档说某个查询参数是可选的,并且不提供默认参数。因此,我可以提供值,也可以不在GET请求中将其作为参数发送。

例:

  • queryA是必需的
  • queryB是可选的(没有它可以发送GET

这应该工作:

http://www.example.com/service/endpoint?queryA=foo&queryB=bar

这应该也有效:

http://www.example.com/service/endpoint?queryA=foo

如何为Jersey-Proxy创建一个可以执行此操作的客户端界面?我没有服务器端代码来连接,所以我通过Jersey-Proxy使用org.glassfish.jersey.client.proxy.WebResourceFactory来生成客户端以与服务器API交互。

样本界面:

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            @QueryParam("queryB") String second);

}

我知道我可以制作另一种方法:

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first);

但是当你有多个可选字段时会发生什么?我不想让它们发生任何可能的变异!

java rest jersey jax-rs
2个回答
28
投票

The interface was right all along

我简直不敢相信这很容易:

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            @QueryParam("queryB") String second);

}

注意什么不同于问题界面?不。那是因为这就是答案!


Don't use @DefaultValue for optional parameters

如果要将参数默认为特定值,请在参数中使用@DefaultValue批注:

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            @QueryParam("queryB") @DefaultValue("default") String second);

}

Pass null to the @QueryParam you don't want

如果要使@QueryParam可选,则不应用@DefaultValue注释。要使用query参数传递值,只需正常传入值即可。如果您希望查询参数根本不显示,只需传递null

import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/service")
@Produces("application/json")
public interface ServiceInterface {

    @Path("/endpoint")
    @GET
    public Response getEndpoint(
            @QueryParam("queryA") String first,
            // Pass null to this parameter to not put it in the GET request
            @QueryParam("queryB") String second);

}

所以调用ServiceInterface.getEndpoint("firstQueryParam", "secondQueryParam");调用:

http://targethost.com/service/endpoint?queryA=firstQueryParam&queryB=secondQueryParam

并调用ServiceInterface.getEndpoint("firstQueryParam", null);调用:

http://targethost.com/service/endpoint?queryA=firstQueryParam

还有沃拉!没有第二个查询参数! :)

关于原始值的注释

如果您的API采用原始值(如intfloatboolean等),则使用对象包装类(Autoboxing)作为该原语(如IntegerFloatBoolean等)。然后,您可以将null传递给方法:

public Response getEndpoint(@QueryParam("queryA") Boolean first);

2
投票

您可以将UriInfo实例(或其他类似HttpServletRequest)注入到您的方法中,并从中获取您想要的任何数据。

例如

@Path("/endpoint")
@GET
public Response getEndpoint(@Context UriInfo info, @QueryParam("queryA") String queryA) {
  String queryB = info.getQueryParameters().getFirst("queryB");
  if (null != queryB) {
    // do something with it
  }
  ...
}
© www.soinside.com 2019 - 2024. All rights reserved.