我正在使用这个方法的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"}
答案 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正文中提供命名查询参数。