如何使用HttpPost参数

时间:2011-11-14 10:28:05

标签: java android json web-services http-post

我正在使用这个方法的RESTfull webservice:

@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String str1, String str2){
System.out.println("value 1 = " + str1);
System.out.println("value 2 = " + str2);
}

在我的Android应用中,我想调用此方法。如何使用org.apache.http.client.methods.HttpPost为参数赋予正确的值;

我注意到我可以使用注释@HeaderParam并简单地将标题添加到HttpPost对象。这是正确的方法吗?这样做:

httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("str1", "a value");
httpPost.setHeader("str2", "another value");

在httpPost上使用setEntity方法不起作用。它仅使用json字符串设置参数str1。使用时如:

JSONObject json = new JSONObject();
json.put("str1", "a value");
json.put("str2", "another value");
HttpEntity e = new StringEntity(json.toString());
httpPost.setEntity(e);
//server output: value 1 = {"str1":"a value","str2":"another value"} 

3 个答案:

答案 0 :(得分:98)

要为HttpPostRequest设置参数,您可以使用BasicNameValuePair,如下所示:

    HttpClient httpclient;
    HttpPost httppost;
    ArrayList<NameValuePair> postParameters;
    httpclient = new DefaultHttpClient();
    httppost = new HttpPost("your login link");


    postParameters = new ArrayList<NameValuePair>();
    postParameters.add(new BasicNameValuePair("param1", "param1_value"));
    postParameters.add(new BasicNameValuePair("param2", "param2_value"));

    httpPost.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));

    HttpResponse response = httpclient.execute(httpPost);

答案 1 :(得分:4)

如果您想传递一些http参数并发送json请求,也可以使用此方法:

(注意:我添加了一些额外的代码,只是为了帮助其他未来的读者)

public void postJsonWithHttpParams() throws URISyntaxException, UnsupportedEncodingException, IOException {

    //add the http parameters you wish to pass
    List<NameValuePair> postParameters = new ArrayList<>();
    postParameters.add(new BasicNameValuePair("param1", "param1_value"));
    postParameters.add(new BasicNameValuePair("param2", "param2_value"));

    //Build the server URI together with the parameters you wish to pass
    URIBuilder uriBuilder = new URIBuilder("http://google.ug");
    uriBuilder.addParameters(postParameters);

    HttpPost postRequest = new HttpPost(uriBuilder.build());
    postRequest.setHeader("Content-Type", "application/json");

    //this is your JSON string you are sending as a request
    String yourJsonString = "{\"str1\":\"a value\",\"str2\":\"another value\"} ";

    //pass the json string request in the entity
    HttpEntity entity = new ByteArrayEntity(yourJsonString.getBytes("UTF-8"));
    postRequest.setEntity(entity);

    //create a socketfactory in order to use an http connection manager
    PlainConnectionSocketFactory plainSocketFactory = PlainConnectionSocketFactory.getSocketFactory();
    Registry<ConnectionSocketFactory> connSocketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("http", plainSocketFactory)
            .build();

    PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(connSocketFactoryRegistry);

    connManager.setMaxTotal(20);
    connManager.setDefaultMaxPerRoute(20);

    RequestConfig defaultRequestConfig = RequestConfig.custom()
            .setSocketTimeout(HttpClientPool.connTimeout)
            .setConnectTimeout(HttpClientPool.connTimeout)
            .setConnectionRequestTimeout(HttpClientPool.readTimeout)
            .build();

    // Build the http client.
    CloseableHttpClient httpclient = HttpClients.custom()
            .setConnectionManager(connManager)
            .setDefaultRequestConfig(defaultRequestConfig)
            .build();

    CloseableHttpResponse response = httpclient.execute(postRequest);

    //Read the response
    String responseString = "";

    int statusCode = response.getStatusLine().getStatusCode();
    String message = response.getStatusLine().getReasonPhrase();

    HttpEntity responseHttpEntity = response.getEntity();

    InputStream content = responseHttpEntity.getContent();

    BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
    String line;

    while ((line = buffer.readLine()) != null) {
        responseString += line;
    }

    //release all resources held by the responseHttpEntity
    EntityUtils.consume(responseHttpEntity);

    //close the stream
    response.close();

    // Close the connection manager.
    connManager.close();
}

答案 2 :(得分:1)

一般来说,HTTP POST假定正文的内容包含一系列键/值对,这些键/值对是由HTML端的表单创建的(最常见)。您不使用setHeader设置值,因为它不会将它们放在内容正文中。

因此,在第二次测试中,您遇到的问题是您的客户端没有创建多个键/值对,它只创建了一个,并且默认情况下映射到方法中的第一个参数。

您可以使用几种选项。首先,您可以将方法更改为仅接受一个输入参数,然后像在第二个测试中那样传入JSON字符串。进入方法后,然后将JSON字符串解析为允许访问字段的对象。

另一种选择是定义一个表示输入类型字段的类,并使其成为唯一的输入参数。例如

class MyInput
{
    String str1;
    String str2;

    public MyInput() { }
      //  getters, setters
 }

@POST
@Consumes({"application/json"})
@Path("create/")
public void create(MyInput in){
System.out.println("value 1 = " + in.getStr1());
System.out.println("value 2 = " + in.getStr2());
}

根据您使用的REST框架,它应该为您处理JSON的反序列化。

最后一个选项是构造一个看起来像这样的POST主体:

str1=value1&str2=value2

然后在服务器方法中添加一些额外的注释:

public void create(@QueryParam("str1") String str1, 
                  @QueryParam("str2") String str2)

@QueryParam不关心字段是在表单帖子中还是在URL中(如GET查询)。

如果要继续在输入上使用单个参数,则密钥将生成客户端请求,以在URL(对于GET)或POST正文中提供命名查询参数。