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


81

我正在为具有List作为查询参数的GET服务创建Jersey客户。根据文档,可以将List作为查询参数(此信息也位于@QueryParam javadoc中),将其检出:

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

  1. 是原始类型;
  2. 有一个接受单个String参数的构造函数;
  3. 有一个名为valueOf或fromString的静态方法,该方法接受单个String参数(例如,请参见Integer.valueOf(String)和java.util.UUID.fromString(String));要么
  4. 是List,Set或SortedSet,其中T满足上面的2或3。结果集合为只读。

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

但是,我不知道如何使用Jersey客户端添加List查询参数。

我了解替代解决方案是:

  1. 使用POST而不是GET;
  2. 将List转换为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
您可以在此处提供球衣客户代码吗?
Yogesh Prajapati 2012年

1
yogesh,我添加了客户端代码。
lsborg

2
如果我理解您的问题说明,则可以通过将多个值添加到同一键来将值列表作为Query参数传递。如果“ searchWrapper”是键,并且您希望向其传递多个值:像这样构建URL:// YourURL?searchWrapper = value1&searchWrapper = value2&searchWrapper = value3如果您的MultivaluedMap支持,则可能需要多次向同一个键插入值。 。
Thamme Gowda

1
谢谢,@ ThammeGowda!我尚未对其进行测试,但是它似乎可以通过MultivaluedMap javadoc来实现添加方法状态的技巧:将一个值添加到所提供键的当前值列表中
lsborg

Answers:


116

@GET 确实支持字符串列表

设置
Java:1.7
Jersey版本: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());
}

1
谢谢。它帮助到我。
Sapikelio

60
就像其他人的注释一样,如果您是直接在浏览器中编写URL,则必须重复参数名称:..?list = one&list = two&list = three
endian 2015年

2
这是真正的清单/订单是否得到保证?鉴于它似乎是泽西岛作为列表返回的多值地图,我想知道是否存在订单未保存的问题
hayduke

是的 ?list = one&list = two&list = three不是那么有用。如表=一,二,三-这就是为什么我手动剥从字符串列表..List<String> argList = List.of(argString.split("\\s*,\\s*"))
SES

30

如果您要发送的不是简单字符串,则建议您使用带有适当请求正文的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();
    }
}

您的客户会发送与以下内容相对应的请求:

GET http://example.com/services/echo?list=Hello&list=Stay&list=再见

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


2
感谢您的回答知觉!但是我想找出是否可以使用Jersey客户端使用GET作为查询参数进行GET。
lsborg

1
您能告诉我如何在客户端创建此类列表吗,因为我的客户端是android和ios。显然,我们不想手动创建键=值和键=值
nilesh 2015年

如果发送该list[0]=Hello&list[1]=Stay怎么办?如何处理?
user1735921

6

我同意您在上面提到的替代解决方案

1. Use POST instead of GET;
2. Transform the List into a JSON string and pass it to the service.

其真实的,你不能添加ListMultiValuedMap,因为它的实现类的MultivaluedMapImpl有能力接受的字符串键和字符串值。如下图所示

在此处输入图片说明

您仍然想要做这些事情,而不是尝试下面的代码。

控制器类

package net.yogesh.test;

import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import com.google.gson.Gson;

@Path("test")
public class TestController {
       @Path("testMethod")
       @GET
       @Produces("application/text")
       public String save(
               @QueryParam("list") List<String> list) {

           return  new Gson().toJson(list) ;
       }
}

客户类别

package net.yogesh.test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.ws.rs.core.MultivaluedMap;

import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.core.util.MultivaluedMapImpl;

public class Client {
    public static void main(String[] args) {
        String op = doGet("http://localhost:8080/JerseyTest/rest/test/testMethod");
        System.out.println(op);
    }

    private static String doGet(String url){
        List<String> list = new ArrayList<String>();
        list = Arrays.asList(new String[]{"string1,string2,string3"});

        MultivaluedMap<String, String> params = new MultivaluedMapImpl();
        String lst = (list.toString()).substring(1, list.toString().length()-1);
        params.add("list", lst);

        ClientConfig config = new DefaultClientConfig();
        com.sun.jersey.api.client.Client client = com.sun.jersey.api.client.Client.create(config);
        WebResource resource = client.resource(url);

        ClientResponse response = resource.queryParams(params).type("application/x-www-form-urlencoded").get(ClientResponse.class);
        String en = response.getEntity(String.class);
        return en;
    }
}

希望对您有帮助。


最好的答案在这里!感谢+1
Haramoz '19

3

带有JSON查询参数的GET请求

package com.rest.jersey.jerseyclient;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

public class JerseyClientGET {

    public static void main(String[] args) {
        try {               

            String BASE_URI="http://vaquarkhan.net:8080/khanWeb";               
            Client client = Client.create();    
            WebResource webResource = client.resource(BASE_URI);

            ClientResponse response = webResource.accept("application/json").get(ClientResponse.class);

            /*if (response.getStatus() != 200) {
               throw new RuntimeException("Failed : HTTP error code : "
                + response.getStatus());
            }
*/
            String output = webResource.path("/msg/sms").queryParam("search","{\"name\":\"vaquar\",\"surname\":\"khan\",\"ext\":\"2020\",\"age\":\"34\""}").get(String.class);
            //String output = response.getEntity(String.class);

            System.out.println("Output from Server .... \n");
            System.out.println(output);                         

        } catch (Exception e) {

            e.printStackTrace();    
        }    
    }    
}

张贴要求:

package com.rest.jersey.jerseyclient;

import com.rest.jersey.dto.KhanDTOInput;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;

public class JerseyClientPOST {

    public static void main(String[] args) {
        try {

            KhanDTOInput khanDTOInput = new KhanDTOInput("vaquar", "khan", "20", "E", null, "2222", "8308511500");                      

            ClientConfig clientConfig = new DefaultClientConfig();

            clientConfig.getFeatures().put( JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);

            Client client = Client.create(clientConfig);

               // final HTTPBasicAuthFilter authFilter = new HTTPBasicAuthFilter(username, password);
               // client.addFilter(authFilter);
               // client.addFilter(new LoggingFilter());

            //
            WebResource webResource = client
                    .resource("http://vaquarkhan.net:12221/khanWeb/messages/sms/api/v1/userapi");

              ClientResponse response = webResource.accept("application/json")
                .type("application/json").put(ClientResponse.class, khanDTOInput);


            if (response.getStatus() != 200) {
                throw new RuntimeException("Failed : HTTP error code :" + response.getStatus());
            }

            String output = response.getEntity(String.class);

            System.out.println("Server response .... \n");
            System.out.println(output);

        } catch (Exception e) {

            e.printStackTrace();

        }    
    }    
}

看到客户资源的例子就是我所需要的:)谢谢
Mobigital
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.