泽西岛客户端:如何将列表添加为查询参数

2022-08-31 11:03:14

我正在为具有 List as query 参数的 GET 服务创建一个 Jersey 客户端。根据文档,可以将List作为查询参数(此信息也位于@QueryParam javadoc),请查看它:

通常,方法参数的 Java 类型可以:

  1. 是基元类型;
  2. 有一个接受单个字符串参数的构造函数;
  3. 有一个名为 valueOf 或 fromString 的静态方法,它接受单个 String 参数(例如,请参阅 Integer.valueOf(String) 和 java.util.UUID.fromString(String));或
  4. 是列表,设置或排序集,其中T满足上面的2或3。生成的集合是只读的。

有时,参数可能包含同一名称的多个值。如果是这种情况,则可以使用 4) 中的类型来获取所有值。

但是,我无法弄清楚如何使用 Jersey 客户端添加 List 查询参数。

我了解替代解决方案是:

  1. 使用 POST 而不是 GET;
  2. 将列表转换为 JSON 字符串并将其传递给服务。

第一个不好,因为服务的正确HTTP动词是GET。它是一种数据检索操作。

第二个将是我的选择,如果你不能帮助我。:)

我也在开发该服务,因此我可以根据需要进行更改。

谢谢!

更新

客户端代码(使用 json)

Client client = Client.create();

WebResource webResource = client.resource(uri.toString());

SearchWrapper sw = new SearchWrapper(termo, pagina, ordenacao, hits, SEARCH_VIEW, navegadores);

MultivaluedMap<String, String> params = new MultivaluedMapImpl();
params.add("user", user.toUpperCase()); 
params.add("searchWrapperAsJSON", (new Gson()).toJson(sw));

ClientResponse clientResponse = webResource .path("/listar")
                                            .queryParams(params)
                                            .header(HttpHeaders.AUTHORIZATION, AuthenticationHelper.getBasicAuthHeader())
                                            .get(ClientResponse.class);

SearchResultWrapper busca = clientResponse.getEntity(new GenericType<SearchResultWrapper>() {});

答案 1

@GET支持字符串列表

设置
Java : 1.7
泽西岛版本 : 1.9

资源

@Path("/v1/test")

子资源

// receive List of Strings
@GET
@Path("/receiveListOfStrings")
public Response receiveListOfStrings(@QueryParam("list") final List<String> list){
    log.info("receieved list of size="+list.size());
    return Response.ok().build();
}

泽西岛测试用例

@Test
public void testReceiveListOfStrings() throws Exception {
    WebResource webResource = resource();
    ClientResponse responseMsg = webResource.path("/v1/test/receiveListOfStrings")
            .queryParam("list", "one")
            .queryParam("list", "two")
            .queryParam("list", "three")
            .get(ClientResponse.class);
    Assert.assertEquals(200, responseMsg.getStatus());
}

答案 2

如果您要发送简单字符串以外的任何内容,我建议您使用具有适当请求正文的POST,或者将整个列表作为适当编码的JSON字符串传递。但是,使用简单的字符串,您只需要将每个值适当地附加到请求URL,Jersey将为您反序列化它。因此,给定以下示例终结点:

@Path("/service/echo") public class MyServiceImpl {
    public MyServiceImpl() {
        super();
    }

    @GET
    @Path("/withlist")
    @Produces(MediaType.TEXT_PLAIN)
    public Response echoInputList(@QueryParam("list") final List<String> inputList) {
        return Response.ok(inputList).build();
    }
}

您的客户将发送对应于以下内容的请求:

获取 http://example.com/services/echo?list=Hello&list=Stay&list=Goodbye

这将导致反序列化为包含值“Hello”,“Stay”和“Goodbye”inputList