我成功地使用这段代码通过GET方法发送带有一些参数的HTTP请求
void sendRequest(String request)
{
// i.e.: request = "http://example.com/index.php?param1=a¶m2=b¶m3=c";
URL url = new URL(request);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("GET");
connection.setRequestProperty("Content-Type", "text/plain");
connection.setRequestProperty("charset", "utf-8");
connection.connect();
}
现在我可能需要通过POST方法发送参数(即param1, param2, param3),因为它们非常长。
我想添加一个额外的参数,该方法(即字符串httpMethod)。
我怎样才能尽可能少地更改上面的代码,以便能够通过GET或POST发送参数?
我希望情况会有所改变
connection.setRequestMethod("GET");
to
connection.setRequestMethod("POST");
可以完成这个任务,但是参数仍然通过GET方法发送。
HttpURLConnection有任何方法可以帮助吗?
有什么有用的Java构造吗?
任何帮助都将不胜感激。
下面是一个简单的示例,它提交了一个表单,然后将结果页面转储到System.out。当然,要适当地更改URL和POST参数:
import java.io.*;
import java.net.*;
import java.util.*;
class Test {
public static void main(String[] args) throws Exception {
URL url = new URL("http://example.net/new-message.php");
Map<String,Object> params = new LinkedHashMap<>();
params.put("name", "Freddie the Fish");
params.put("email", "fishie@seamail.example.com");
params.put("reply_to_thread", 10394);
params.put("message", "Shark attacks in Botany Bay have gotten out of control. We need more defensive dolphins to protect the schools here, but Mayor Porpoise is too busy stuffing his snout with lobsters. He's so shellfish.");
StringBuilder postData = new StringBuilder();
for (Map.Entry<String,Object> param : params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(param.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(param.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
conn.setDoOutput(true);
conn.getOutputStream().write(postDataBytes);
Reader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
for (int c; (c = in.read()) >= 0;)
System.out.print((char)c);
}
}
如果你想将结果作为字符串而不是直接打印出来,请:
StringBuilder sb = new StringBuilder();
for (int c; (c = in.read()) >= 0;)
sb.append((char)c);
String response = sb.toString();
我已经阅读了上面的答案,并创建了一个实用工具类来简化HTTP请求。我希望它能帮助你。
方法调用
// send params with Hash Map
HashMap<String, String> params = new HashMap<String, String>();
params.put("email","me@example.com");
params.put("password","12345");
//server url
String url = "http://www.example.com";
// static class "HttpUtility" with static method "newRequest(url,method,callback)"
HttpUtility.newRequest(url,HttpUtility.METHOD_POST,params, new HttpUtility.Callback() {
@Override
public void OnSuccess(String response) {
// on success
System.out.println("Server OnSuccess response="+response);
}
@Override
public void OnError(int status_code, String message) {
// on error
System.out.println("Server OnError status_code="+status_code+" message="+message);
}
});
实用程序类
import java.io.*;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import static java.net.HttpURLConnection.HTTP_OK;
public class HttpUtility {
public static final int METHOD_GET = 0; // METHOD GET
public static final int METHOD_POST = 1; // METHOD POST
// Callback interface
public interface Callback {
// abstract methods
public void OnSuccess(String response);
public void OnError(int status_code, String message);
}
// static method
public static void newRequest(String web_url, int method, HashMap < String, String > params, Callback callback) {
// thread for handling async task
new Thread(new Runnable() {
@Override
public void run() {
try {
String url = web_url;
// write GET params,append with url
if (method == METHOD_GET && params != null) {
for (Map.Entry < String, String > item: params.entrySet()) {
String key = URLEncoder.encode(item.getKey(), "UTF-8");
String value = URLEncoder.encode(item.getValue(), "UTF-8");
if (!url.contains("?")) {
url += "?" + key + "=" + value;
} else {
url += "&" + key + "=" + value;
}
}
}
HttpURLConnection urlConnection = (HttpURLConnection) new URL(url).openConnection();
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // handle url encoded form data
urlConnection.setRequestProperty("charset", "utf-8");
if (method == METHOD_GET) {
urlConnection.setRequestMethod("GET");
} else if (method == METHOD_POST) {
urlConnection.setDoOutput(true); // write POST params
urlConnection.setRequestMethod("POST");
}
//write POST data
if (method == METHOD_POST && params != null) {
StringBuilder postData = new StringBuilder();
for (Map.Entry < String, String > item: params.entrySet()) {
if (postData.length() != 0) postData.append('&');
postData.append(URLEncoder.encode(item.getKey(), "UTF-8"));
postData.append('=');
postData.append(URLEncoder.encode(String.valueOf(item.getValue()), "UTF-8"));
}
byte[] postDataBytes = postData.toString().getBytes("UTF-8");
urlConnection.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length));
urlConnection.getOutputStream().write(postDataBytes);
}
// server response code
int responseCode = urlConnection.getResponseCode();
if (responseCode == HTTP_OK && callback != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
// callback success
callback.OnSuccess(response.toString());
reader.close(); // close BufferReader
} else if (callback != null) {
// callback error
callback.OnError(responseCode, urlConnection.getResponseMessage());
}
urlConnection.disconnect(); // disconnect connection
} catch (IOException e) {
e.printStackTrace();
if (callback != null) {
// callback error
callback.OnError(500, e.getLocalizedMessage());
}
}
}
}).start(); // start thread
}
}
对于那些使用$_POST在php页面上接收请求的问题,因为你期望键值对:
虽然所有的答案都很有帮助,但我对实际发布哪个字符串缺乏一些基本的了解,因为在我使用的旧apache HttpClient中
new UrlEncodedFormEntity(nameValuePairs); (Java)
然后可以在php中使用$_POST获取键值对。
据我的理解,现在已经在发布之前手动构建该字符串。所以字符串应该是这样的
val data = "key1=val1&key2=val2"
而是只是把它添加到它被张贴的url(在头)。
另一种方法是使用json-string:
val data = "{\"key1\":\"val1\",\"key2\":\"val2\"}" // {"key1":"val1","key2":"val2"}
然后把它拉到php中,不需要$_POST:
$json_params = file_get_contents('php://input');
// echo_p("Data: $json_params");
$data = json_decode($json_params, true);
下面是Kotlin中的示例代码:
class TaskDownloadTest : AsyncTask<Void, Void, Void>() {
override fun doInBackground(vararg params: Void): Void? {
var urlConnection: HttpURLConnection? = null
try {
val postData = JsonObject()
postData.addProperty("key1", "val1")
postData.addProperty("key2", "val2")
// reformat json to key1=value1&key2=value2
// keeping json because I may change the php part to interpret json requests, could be a HashMap instead
val keys = postData.keySet()
var request = ""
keys.forEach { key ->
// Log.i("data", key)
request += "$key=${postData.get(key)}&"
}
request = request.replace("\"", "").removeSuffix("&")
val requestLength = request.toByteArray().size
// Warning in Android 9 you need to add a line in the application part of the manifest: android:usesCleartextTraffic="true"
// https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted
val url = URL("http://10.0.2.2/getdata.php")
urlConnection = url.openConnection() as HttpURLConnection
// urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") // apparently default
// Not sure what these are for, I do not use them
// urlConnection.setRequestProperty("Content-Type", "application/json")
// urlConnection.setRequestProperty("Key","Value")
urlConnection.readTimeout = 5000
urlConnection.connectTimeout = 5000
urlConnection.requestMethod = "POST"
urlConnection.doOutput = true
// urlConnection.doInput = true
urlConnection.useCaches = false
urlConnection.setFixedLengthStreamingMode(requestLength)
// urlConnection.setChunkedStreamingMode(0) // if you do not want to handle request length which is fine for small requests
val out = urlConnection.outputStream
val writer = BufferedWriter(
OutputStreamWriter(
out, "UTF-8"
)
)
writer.write(request)
// writer.write("{\"key1\":\"val1\",\"key2\":\"val2\"}") // {"key1":"val1","key2":"val2"} JsonFormat or just postData.toString() for $json_params=file_get_contents('php://input'); json_decode($json_params, true); in php
// writer.write("key1=val1&key2=val2") // key=value format for $_POST in php
writer.flush()
writer.close()
out.close()
val code = urlConnection.responseCode
if (code != 200) {
throw IOException("Invalid response from server: $code")
}
val rd = BufferedReader(
InputStreamReader(
urlConnection.inputStream
)
)
var line = rd.readLine()
while (line != null) {
Log.i("data", line)
line = rd.readLine()
}
} catch (e: Exception) {
e.printStackTrace()
} finally {
urlConnection?.disconnect()
}
return null
}
}