准备
首先我们至少要知道URL和charset,这两个参数是可选的,取决于功能需求。
String url = "http://example.com";
String charset = "UTF-8"; // Or in Java 7 and later, use the constant: java.nio.charset.StandardCharsets.UTF_8.name()
String param1 = "value1";
String param2 = "value2";
// ...
String query = String.format("param1=%s¶m2=%s",
URLEncoder.encode(param1, charset),
URLEncoder.encode(param2, charset));
参数query必须是name=vale格式的,并且用&符号来连结。你也可以通过URLEncoder.encode()方法来指定参数的字符集。
String的format()方法是很方便的。当我需要使用字符串连接操作符 ’ + ’ 两次以上的时候,我很喜欢用这个方法。
发起一个带query参数的HTTP GET请求
这是一个繁琐的任务,get请求是默认的请求方法。
URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...
任何query参数都要跟URL的?后面。请求头的Accept-Charset属性用来告诉服务器用什么字符集来编码参数。如果你不想发送任何参数,你可以不加Accept-Charset属性。如果你不需要加任何请求头信息,甚至你可以使用URL.openStream()快捷方法。
InputStream response = new URL(url).openStream();
// ...
如果另一边是HttpServlet的话,那么doGet()方法会被调用,然后可以用HttpServletRequest.getParameter()方法来获取参数。
你可以打印响应体到控制台来测试,就像下面这样:
try (Scanner scanner = new Scanner(response)) {
String responseBody = scanner.useDelimiter("\\A").next();
System.out.println(responseBody);
}
发起一个带query参数的HTTP POST请求
通过URLConnection.setDoOutput(true)方法来表明我们发起的是一个POST请求。标准的web表单HTTP POST请求体的Content-Type是application/x-www-form-urlencoded类型。
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=" + charset);
try (OutputStream output = connection.getOutputStream()) {
output.write(query.getBytes(charset));
}
InputStream response = connection.getInputStream();
// ...
注意:不管你什么时候提交表单,不要忘了把表单中的
<inputtype="hidden">
和<input type="submit">
元素以name=value
的形式加入到query字符串参数中,因为这是在服务器端确定你触发的是哪一个按扭的关键。
你也可以将URLConnection 转换成HttpURLConnection ,并使用HttpURLConnection.setRequestMethod()方法来表明是一个POST请求。但如果你想要获取输出流的话,你仍然需要设置URLConnection.setDoOutput(true)。
HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...
另外,如果另一边是一个HttpServlet,那么doPost()方法将会被调用,就可以通过HttpServletRequest.getParameter()方法来获取参数。
关于发起请求
你可以用URLConnection.connect()方法来发起一个请求,但当你想要获取关于HTTP response的任何信息的时候,请求会自动的发起,诸如:通过URLConnection.getInputStream()方法来获取响应体等等。上面的例子确实如此,所以connect()方法的调用实际上是多余的。
收集HTTP响应信息
① HTTP response status:
在这里你需要一个HttpURLConnection,如果必要转换它。
int status = httpConnection.getResponseCode();
② HTTP response headers:
for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
System.out.println(header.getKey() + "=" + header.getValue());
}
③ HTTP response encoding:
当Content-Type属性设置了字符集参数时,响应体很可能是基于文本的,那么我们将要在服务器端以指定的字符集来编码响应体。
String contentType = connection.getHeaderField("Content-Type");
String charset = null;
for (String param : contentType.replace(" ", "").split(";")) {
if (param.startsWith("charset=")) {
charset = param.split("=", 2)[1];
break;
}
}
if (charset != null) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(response, charset))) {
for (String line; (line = reader.readLine()) != null;) {
// ... System.out.println(line) ?
}
}
} else {
// It's likely binary content, use InputStream/OutputStream.
}
声明:文章是经论坛回答翻译而来。