用Java发送HTTP POST请求

让我们假设这个URL…

http://www.example.com/page.php?id=10

(这里id需要在POST请求中发送)

我想将id = 10发送给服务器的page.php,后者在POST方法中接受它。

我如何从Java中做到这一点?

我试了一下:

URL aaa = new URL("http://www.example.com/page.php");
URLConnection ccc = aaa.openConnection();

但是我仍然不知道如何通过POST发送它

1003971 次浏览

调用HttpURLConnection.setRequestMethod("POST")HttpURLConnection.setDoOutput(true);实际上只需要后者,因为POST将成为默认方法。

String rawData = "id=10";
String type = "application/x-www-form-urlencoded";
String encodedData = URLEncoder.encode( rawData, "UTF-8" );
URL u = new URL("http://www.example.com/page.php");
HttpURLConnection conn = (HttpURLConnection) u.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty( "Content-Type", type );
conn.setRequestProperty( "Content-Length", String.valueOf(encodedData.length()));
OutputStream os = conn.getOutputStream();
os.write(encodedData.getBytes());

更新后的答案

由于原始答案中的一些类在Apache HTTP组件的新版本中已弃用,所以我发布了此更新。

顺便说一下,你可以访问完整的文档,以获得更多的例子在这里

HttpClient httpclient = HttpClients.createDefault();
HttpPost httppost = new HttpPost("http://www.a-domain.example/foo/");


// Request parameters and other properties.
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("param-1", "12345"));
params.add(new BasicNameValuePair("param-2", "Hello!"));
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));


//Execute and get the response.
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();


if (entity != null) {
try (InputStream instream = entity.getContent()) {
// do something useful
}
}

原来的答案

我推荐使用Apache HttpClient。它更快更容易实现。

HttpPost post = new HttpPost("http://jakarata.apache.org/");
NameValuePair[] data = {
new NameValuePair("user", "joe"),
new NameValuePair("password", "bloggs")
};
post.setRequestBody(data);
// execute method and handle any error responses.
...
InputStream in = post.getResponseBodyAsStream();
// handle response.

更多信息请查看这个URL: http://hc.apache.org/

第一个答案很棒,但我不得不添加try/catch以避免Java编译器错误 此外,我在弄清楚如何使用Java库读取HttpResponse时遇到了麻烦。< / p >

以下是更完整的代码:

/*
* Create the POST request
*/
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://example.com/");
// Request parameters and other properties.
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("user", "Bob"));
try {
httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
} catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
}
/*
* Execute the HTTP Request
*/
try {
HttpResponse response = httpClient.execute(httpPost);
HttpEntity respEntity = response.getEntity();


if (respEntity != null) {
// EntityUtils to get the response content
String content =  EntityUtils.toString(respEntity);
}
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}

使用Apache HTTP Components的一种简单方法是

Request.Post("http://www.example.com/page.php")
.bodyForm(Form.form().add("id", "10").build())
.execute()
.returnContent();

看一下流利的API

在普通Java中发送POST请求很容易。从URL开始,我们需要使用url.openConnection();将其转换为URLConnection。之后,我们需要将它强制转换为HttpURLConnection,这样我们就可以访问它的setRequestMethod()方法来设置我们的方法。我们最后说,我们将通过连接发送数据。

URL url = new URL("https://www.example.com/login");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);

然后我们需要声明我们要发送的内容:

发送一个简单的表单

来自http表单的普通POST具有定义良好的格式。我们需要将输入转换为以下格式:

Map<String,String> arguments = new HashMap<>();
arguments.put("username", "root");
arguments.put("password", "sjh76HSn!"); // This is a fake password obviously
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "="
+ URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;

然后,我们可以将表单内容附加到http请求,并发送它。

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
os.write(out);
}
// Do something with http.getInputStream()

发送JSON

我们也可以使用java发送json,这也很简单:

byte[] out = "{\"username\":\"root\",\"password\":\"password\"}" .getBytes(StandardCharsets.UTF_8);
int length = out.length;


http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
os.write(out);
}
// Do something with http.getInputStream()

请记住,不同的服务器接受json的不同内容类型,参见问题。


用java post发送文件

发送文件的难度更大,因为格式更复杂。我们还将添加以字符串形式发送文件的支持,因为我们不想将文件完全缓冲到内存中。

为此,我们定义了一些helper方法:

private void sendFile(OutputStream out, String name, InputStream in, String fileName) {
String o = "Content-Disposition: form-data; name=\"" + URLEncoder.encode(name,"UTF-8")
+ "\"; filename=\"" + URLEncoder.encode(filename,"UTF-8") + "\"\r\n\r\n";
out.write(o.getBytes(StandardCharsets.UTF_8));
byte[] buffer = new byte[2048];
for (int n = 0; n >= 0; n = in.read(buffer))
out.write(buffer, 0, n);
out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}


private void sendField(OutputStream out, String name, String field) {
String o = "Content-Disposition: form-data; name=\""
+ URLEncoder.encode(name,"UTF-8") + "\"\r\n\r\n";
out.write(o.getBytes(StandardCharsets.UTF_8));
out.write(URLEncoder.encode(field,"UTF-8").getBytes(StandardCharsets.UTF_8));
out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

然后我们可以使用这些方法创建一个多部分的post请求,如下所示:

String boundary = UUID.randomUUID().toString();
byte[] boundaryBytes =
("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8);
byte[] finishBoundaryBytes =
("--" + boundary + "--").getBytes(StandardCharsets.UTF_8);
http.setRequestProperty("Content-Type",
"multipart/form-data; charset=UTF-8; boundary=" + boundary);


// Enable streaming mode with default settings
http.setChunkedStreamingMode(0);


// Send our fields:
try(OutputStream out = http.getOutputStream()) {
// Send our header (thx Algoman)
out.write(boundaryBytes);


// Send our first field
sendField(out, "username", "root");


// Send a seperator
out.write(boundaryBytes);


// Send our second field
sendField(out, "password", "toor");


// Send another seperator
out.write(boundaryBytes);


// Send our file
try(InputStream file = new FileInputStream("test.txt")) {
sendFile(out, "identification", file, "text.txt");
}


// Finish the request
out.write(finishBoundaryBytes);
}




// Do something with http.getInputStream()

用post请求发送参数的最简单方法:

String postURL = "http://www.example.com/page.php";


HttpPost post = new HttpPost(postURL);


List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", "10"));


UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, "UTF-8");
post.setEntity(ent);


HttpClient client = new DefaultHttpClient();
HttpResponse responsePOST = client.execute(post);
你做到了。现在你可以使用responsePOST。 获取响应内容为字符串:

BufferedReader reader = new BufferedReader(new  InputStreamReader(responsePOST.getEntity().getContent()), 2048);


if (responsePOST != null) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
System.out.println(" line : " + line);
sb.append(line);
}
String getResponseString = "";
getResponseString = sb.toString();
//use server output getResponseString as string value.
}

我建议使用apache http api上构建的http请求

HttpRequest<String> httpRequest = HttpRequestBuilder.createPost("http://www.example.com/page.php", String.class)
.responseDeserializer(ResponseDeserializer.ignorableDeserializer()).build();


public void send(){
String response = httpRequest.execute("id", "10").get();
}

我建议使用Postman来生成请求代码。简单地使用Postman进行请求,然后点击code选项卡:

code tab

然后你会看到下面的窗口来选择你想要的请求代码的语言: 请求代码生成 < / p >

使用okhttp:

okhttp的源代码可以在这里找到https://github.com/square/okhttp

如果您正在编写一个pom项目,请添加此依赖项

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.2.2</version>
</dependency>

如果不是,可以在网上搜索“下载okhttp”。在下载jar的地方会出现几个结果。

你的代码:

import okhttp3.*;
        

import java.io.IOException;


public class ClassName{
private void sendPost() throws IOException {
        

// form parameters
RequestBody formBody = new FormBody.Builder()
.add("id", 10)
.build();
        

Request request = new Request.Builder()
.url("http://www.example.com/page.php")
.post(formBody)
.build();




OkHttpClient httpClient = new OkHttpClient();
        

try (Response response = httpClient.newCall(request).execute()) {
        

if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
        

// Get response body
System.out.println(response.body().string());
}
}
}

轻松使用java.net:

public void post(String uri, String data) throws Exception {
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(uri))
.POST(BodyPublishers.ofString(data))
.build();


HttpResponse<?> response = client.send(request, BodyHandlers.discarding());
System.out.println(response.statusCode());
以下是更多信息: https://openjdk.java.net/groups/net/httpclient/recipes.html#post < / p >

从java 11开始,HTTP请求可以用更少的代码使用java.net.http.HttpClient来发出。

    var values = new HashMap<String, Integer>() \{\{
put("id", 10);
}};
    

var objectMapper = new ObjectMapper();
String requestBody = objectMapper
.writeValueAsString(values);
    

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("http://www.example.com/abc"))
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
    

HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
    

System.out.println(response.body());