getinputstream - 如何使用java.net.URLConnection來觸發和處理HTTP請求




java httpurlconnection (8)

更新

新的HTTP客戶端隨Java 9一起提供,但作為名為jdk.incubator.httpclient的孵化器模塊的jdk.incubator.httpclient 。 孵化器模塊是一種將非最終API提供給開發人員的手段,而API將在未來版本中進行完成或刪除。

在Java 9中,您可以發送GET請求,如下所示:

// GET
HttpResponse response = HttpRequest
    .create(new URI("http://www.stackoverflow.com"))
    .headers("Foo", "foovalue", "Bar", "barvalue")
    .GET()
    .response();

然後你可以檢查返回的HttpResponse

int statusCode = response.statusCode();
String responseBody = response.body(HttpResponse.asString());

由於這個新的HTTP客戶端在 java.httpclient jdk.incubator.httpclient模塊,你應該在你的module-info.java文件中聲明這個依賴:

module com.foo.bar {
    requires jdk.incubator.httpclient;
}

在這裡經常會問到java.net.URLConnection用法, Oracle教程 簡單了。

該教程基本上只展示瞭如何激發GET請求並讀取響應。 它沒有解釋如何使用它來執行POST請求,設置請求標頭,讀取響應標頭,處理cookie,提交HTML表單,上傳文件等。

那麼,如何使用java.net.URLConnection來觸發和處理“高級”HTTP請求呢?


首先提供免責聲明:發布的代碼片段都是基本示例。 您將需要處理普通IOException s和RuntimeException s,如NullPointerExceptionArrayIndexOutOfBoundsException並配合您自己。

準備

我們首先需要知道至少URL和字符集。 這些參數是可選的,取決於功能要求。

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&param2=%s", 
     URLEncoder.encode(param1, charset), 
     URLEncoder.encode(param2, charset));

查詢參數必須採用name=value格式,並通過&連接。 您通常還會使用URLEncoder#encode()以指定的字符集對查詢參數URL-encode

String#format()僅僅是為了方便。 當我需要String連接運算符+超過兩次時,我更喜歡它。

使用(可選)查詢參數激發HTTP GET請求

這是一項微不足道的任務。 這是默認的請求方法。

URLConnection connection = new URL(url + "?" + query).openConnection();
connection.setRequestProperty("Accept-Charset", charset);
InputStream response = connection.getInputStream();
// ...

任何查詢字符串應連接到URL使用?Accept-Charset頭可以提示服務器參數的編碼方式。如果你不發送任何查詢字符串,那麼你可以離開Accept-Charset頭。 如果你不需要設置任何頭文件,那麼你甚至可以使用URL#openStream()快捷方法。

InputStream response = new URL(url).openStream();
// ...

無論哪種方式,如果另一方是HttpServlet ,那麼它的doGet()方法將被調用,參數將由HttpServletRequest#getParameter()

出於測試目的,您可以將響應主體打印到stdout中,如下所示:

try (Scanner scanner = new Scanner(response)) {
    String responseBody = scanner.useDelimiter("\\A").next();
    System.out.println(responseBody);
}

使用查詢參數激發HTTP POST請求

URLConnection#setDoOutput()true隱式地將請求方法設置為POST。 標準的HTTP POST作為Web表單的類型是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();
// ...

注意:無論何時您希望以編程方式提交HTML表單,請不要忘記將任何<input type="hidden">元素的name=value對添加到查詢字符串中,當然還要將name=value對您希望以編程方式“按下”的<input type="submit">元素(因為通常在服務器端用於區分按鈕是否被按下以及是否按下了按鈕)。

您也可以將獲得的java.net.URLConnectionHttpURLConnection並使用其HttpURLConnection#setRequestMethod()代替。 但是,如果您嘗試將連接用於輸出,則仍然需要將URLConnection#setDoOutput()true

HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
httpConnection.setRequestMethod("POST");
// ...

無論哪種方式,如果另一端是一個HttpServlet ,那麼它的doPost()方法將被調用,參數將由HttpServletRequest#getParameter()

實際上觸發HTTP請求

您可以使用URLConnection#connect()明確地觸發HTTP請求,但是當您想要獲取有關HTTP響應的任何信息時(例如使用URLConnection#getInputStream()等的響應主體URLConnection#connect() ,請求將自動按需觸發。 上面的例子確實如此,所以connect()調用實際上是多餘的。

收集HTTP響應信息

  1. HTTP響應狀態

    你需要一個HttpURLConnection 。 如有必要,先將它投射。

    int status = httpConnection.getResponseCode();
    
  2. HTTP響應標頭

    for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
        System.out.println(header.getKey() + "=" + header.getValue());
    }
    
  3. HTTP響應編碼

    Content-Type包含一個charset參數時,那麼響應主體可能是基於文本的,我們想用服務器端指定的字符編碼來處理響應主體。

    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.
    }
    

維護會話

服務器端會話通常由一個cookie支持。 一些網絡表單要求您登錄和/或由會話進行跟踪。 您可以使用CookieHandler API來維護Cookie。 您需要在發送所有HTTP請求之前使用CookiePolicyACCEPT_ALL準備CookieManager

// First set the default cookie manager.
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

// All the following subsequent URLConnections will use the same cookie manager.
URLConnection connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

connection = new URL(url).openConnection();
// ...

請注意,這已知在任何情況下都不能正常工作。 如果它失敗了,那麼最好是手動收集並設置cookie標頭。 您基本上需要從登錄響應或第一個GET請求中獲取所有Set-Cookie標頭,然後通過後續請求傳遞它。

// Gather all cookies on the first request.
URLConnection connection = new URL(url).openConnection();
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
// ...

// Then use the same cookies on all subsequent requests.
connection = new URL(url).openConnection();
for (String cookie : cookies) {
    connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]);
}
// ...

split(";", 2)[0]用於擺脫與服務器端無關的cookie屬性,如expirespath等。另外,還可以使用cookie.substring(0, cookie.indexOf(';'))而不是split()

流式傳輸模式

無論您是否使用connection.setRequestProperty("Content-Length", contentLength);設置了固定的內容長度, HttpURLConnection默認會在實際發送前緩衝整個請求體connection.setRequestProperty("Content-Length", contentLength); 。 這可能會導致OutOfMemoryException只要你同時發送大的POST請求(例如上傳文件)。 為了避免這種情況,你想設置HttpURLConnection#setFixedLengthStreamingMode()

httpConnection.setFixedLengthStreamingMode(contentLength);

但是,如果內容長度事先並不知道,那麼可以通過相應地設置HttpURLConnection#setChunkedStreamingMode()來使用分塊流模式。 這會將HTTP Transfer-Encoding標頭設置為chunked ,這將強制請求主體以塊的形式發送。 下面的例子將以1KB的塊形式發送主體。

httpConnection.setChunkedStreamingMode(1024);

用戶代理

可能會發生請求返回意外的響應,但它可以在真正的Web瀏覽器中正常工作。 服務器端可能會阻止基於User-Agent請求標頭的請求。 URLConnection默認將其設置為Java/1.6.0_19 ,其中最後一部分顯然是JRE版本。 你可以覆蓋它如下:

connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36"); // Do as if you're using Chrome 41 on Windows 7.

使用最近瀏覽器中的用戶代理字符串。

錯誤處理

如果HTTP響應代碼是4nn (客戶端錯誤)或5nn (服務器錯誤),那麼您可能需要閱讀HttpURLConnection#getErrorStream()以查看服務器是否發送了任何有用的錯誤信息。

InputStream error = ((HttpURLConnection) connection).getErrorStream();

如果HTTP響應代碼是-1,則連接和響應處理出錯。 HttpURLConnection實現在舊的JRE中有點問題,它使連接保持活躍。 您可能希望通過將http.keepAlive系統屬性設置為false來關閉它。 您可以通過以下方式在應用程序開始時以編程方式執行此操作:

System.setProperty("http.keepAlive", "false");

上傳文件

通常,對於混合POST內容(二進制和字符數據),使用multipart/form-data編碼。 編碼在RFC2388中有更詳細的描述。

String param = "value";
File textFile = new File("/path/to/file.txt");
File binaryFile = new File("/path/to/file.bin");
String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
String CRLF = "\r\n"; // Line separator required by multipart/form-data.
URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);

try (
    OutputStream output = connection.getOutputStream();
    PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true);
) {
    // Send normal param.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"param\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF);
    writer.append(CRLF).append(param).append(CRLF).flush();

    // Send text file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"textFile\"; filename=\"" + textFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: text/plain; charset=" + charset).append(CRLF); // Text file itself must be saved in this charset!
    writer.append(CRLF).flush();
    Files.copy(textFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // Send binary file.
    writer.append("--" + boundary).append(CRLF);
    writer.append("Content-Disposition: form-data; name=\"binaryFile\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF);
    writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF);
    writer.append("Content-Transfer-Encoding: binary").append(CRLF);
    writer.append(CRLF).flush();
    Files.copy(binaryFile.toPath(), output);
    output.flush(); // Important before continuing with writer!
    writer.append(CRLF).flush(); // CRLF is important! It indicates end of boundary.

    // End of multipart/form-data.
    writer.append("--" + boundary + "--").append(CRLF).flush();
}

如果另一端是一個HttpServlet ,那麼它的doPost()方法將被調用,並且這些部分將通過HttpServletRequest#getPart() (注意,因此不是 getParameter()等等!)可用。 然而, getPart()方法相對較新,它在Servlet 3.0中引入(Glassfish 3,Tomcat 7等)。 在Servlet 3.0之前,最好的選擇是使用Apache Commons FileUpload來解析multipart/form-data請求。 另請參閱FileUpload和Servelt 3.0方法的示例。

處理不可信或錯誤配置的HTTPS站點

有時您需要連接HTTPS網址,也許是因為您正在編寫網絡抓取工具。 在這種情況下,您可能會遇到javax.net.ssl.SSLException: Not trusted server certificate某些HTTPS站點上的javax.net.ssl.SSLException: Not trusted server certificate ,它們未保持最新的SSL證書或java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] foundjavax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name某些配置錯誤的HTTPS站點上的javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name

以下一次性運行的static初始化工具可以讓您的網頁抓取工具類使HttpsURLConnection對這些HTTPS網站更為寬鬆,從而不會再拋出這些異常。

static {
    TrustManager[] trustAllCertificates = new TrustManager[] {
        new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null; // Not relevant.
            }
            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                // Do nothing. Just allow them all.
            }
        }
    };

    HostnameVerifier trustAllHostnames = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true; // Just allow them all.
        }
    };

    try {
        System.setProperty("jsse.enableSNIExtension", "false");
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCertificates, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(trustAllHostnames);
    }
    catch (GeneralSecurityException e) {
        throw new ExceptionInInitializerError(e);
    }
}

最後的話

Apache HttpComponents HttpClient在這方面更方便:)

分析和提取HTML

如果你只想從HTML解析和提取數據,那麼最好使用像Jsoup這樣的HTML解析器


受到這個和其他問題的啟發,我創建了一個最小的開源的basic-http-client ,體現了這裡找到的大部分技術。

google-http-java-client也是一個很好的開源資源。


在使用HTTP時,引用HttpURLConnection而不是基類URLConnection幾乎總是更有用(因為當您在HTTP URL上請求URLConnection.openConnection()時, URLConnection是一個抽像類,無論如何您都會收到該URL)。

然後,您可以不依賴於URLConnection#setDoOutput(true)來隱式地將請求方法設置為POST,而是執行httpURLConnection.setRequestMethod("POST") ,有些人可能會發現它更自然(並且還允許您指定其他請求方法,例如PUTDELETE ,...)。

它還提供了有用的HTTP常量,因此您可以執行以下操作:

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {


我對這個回應也很有啟發。

我經常在需要做一些HTTP的項目上工作,而且我可能不想引入很多第三方依賴項(引入其他內容等等)

我開始根據一些對話編寫我自己的實用程序(不是在哪裡完成的):

package org.boon.utils;


import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;

import static org.boon.utils.IO.read;

public class HTTP {

然後就是一堆或靜態方法。

public static String get(
        final String url) {

    Exceptions.tryIt(() -> {
        URLConnection connection;
        connection = doGet(url, null, null, null);
        return extractResponseString(connection);
    });
    return null;
}

public static String getWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, null, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String getWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, null);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}
public static String getWithCharSet(
        final String url,
        final Map<String, ? extends Object> headers,
        String contentType,
        String charSet) {
    URLConnection connection;
    try {
        connection = doGet(url, headers, contentType, charSet);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

然後發布...

public static String postBody(
        final String url,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, null, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}

public static String postBodyWithHeaders(
        final String url,
        final Map<String, ? extends Object> headers,
        final String body) {
    URLConnection connection;
    try {
        connection = doPost(url, headers, "text/plain", null, body);
        return extractResponseString(connection);
    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }
}



public static String postBodyWithContentType(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, null, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}


public static String postBodyWithCharset(
        final String url,
        final Map<String, ? extends Object> headers,
        final String contentType,
        final String charSet,
        final String body) {

    URLConnection connection;
    try {
        connection = doPost(url, headers, contentType, charSet, body);


        return extractResponseString(connection);


    } catch (Exception ex) {
        Exceptions.handle(ex);
        return null;
    }


}

private static URLConnection doPost(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset, String body
                                    ) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    connection.setDoOutput(true);
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);


    IO.write(connection.getOutputStream(), body, IO.CHARSET);
    return connection;
}

private static void manageHeaders(Map<String, ? extends Object> headers, URLConnection connection) {
    if (headers != null) {
        for (Map.Entry<String, ? extends Object> entry : headers.entrySet()) {
            connection.setRequestProperty(entry.getKey(), entry.getValue().toString());
        }
    }
}

private static void manageContentTypeHeaders(String contentType, String charset, URLConnection connection) {
    connection.setRequestProperty("Accept-Charset", charset == null ? IO.CHARSET : charset);
    if (contentType!=null && !contentType.isEmpty()) {
        connection.setRequestProperty("Content-Type", contentType);
    }
}

private static URLConnection doGet(String url, Map<String, ? extends Object> headers,
                                    String contentType, String charset) throws IOException {
    URLConnection connection;/* Handle output. */
    connection = new URL(url).openConnection();
    manageContentTypeHeaders(contentType, charset, connection);

    manageHeaders(headers, connection);

    return connection;
}

private static String extractResponseString(URLConnection connection) throws IOException {
/* Handle input. */
    HttpURLConnection http = (HttpURLConnection)connection;
    int status = http.getResponseCode();
    String charset = getCharset(connection.getHeaderField("Content-Type"));

    if (status==200) {
        return readResponseBody(http, charset);
    } else {
        return readErrorResponseBody(http, status, charset);
    }
}

private static String readErrorResponseBody(HttpURLConnection http, int status, String charset) {
    InputStream errorStream = http.getErrorStream();
    if ( errorStream!=null ) {
        String error = charset== null ? read( errorStream ) :
            read( errorStream, charset );
        throw new RuntimeException("STATUS CODE =" + status + "\n\n" + error);
    } else {
        throw new RuntimeException("STATUS CODE =" + status);
    }
}

private static String readResponseBody(HttpURLConnection http, String charset) throws IOException {
    if (charset != null) {
        return read(http.getInputStream(), charset);
    } else {
        return read(http.getInputStream());
    }
}

private static String getCharset(String contentType) {
    if (contentType==null)  {
        return null;
    }
    String charset = null;
    for (String param : contentType.replace(" ", "").split(";")) {
        if (param.startsWith("charset=")) {
            charset = param.split("=", 2)[1];
            break;
        }
    }
    charset = charset == null ?  IO.CHARSET : charset;

    return charset;
}

反正你懂這個意思....

這裡是測試:

static class MyHandler implements HttpHandler {
    public void handle(HttpExchange t) throws IOException {

        InputStream requestBody = t.getRequestBody();
        String body = IO.read(requestBody);
        Headers requestHeaders = t.getRequestHeaders();
        body = body + "\n" + copy(requestHeaders).toString();
        t.sendResponseHeaders(200, body.length());
        OutputStream os = t.getResponseBody();
        os.write(body.getBytes());
        os.close();
    }
}


@Test
public void testHappy() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9212), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9212/test", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.postBodyWithCharset("http://localhost:9212/test", headers, "text/plain", "UTF-8", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    response = HTTP.postBodyWithHeaders("http://localhost:9212/test", headers, "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));


    response = HTTP.get("http://localhost:9212/test");

    System.out.println(response);


    response = HTTP.getWithHeaders("http://localhost:9212/test", headers);

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithContentType("http://localhost:9212/test", headers, "text/plain");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));



    response = HTTP.getWithCharSet("http://localhost:9212/test", headers, "text/plain", "UTF-8");

    System.out.println(response);

    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

@Test
public void testPostBody() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9220), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBody("http://localhost:9220/test", "hi mom");

    assertTrue(response.contains("hi mom"));


    Thread.sleep(10);

    server.stop(0);


}

@Test(expected = RuntimeException.class)
public void testSad() throws Exception {

    HttpServer server = HttpServer.create(new InetSocketAddress(9213), 0);
    server.createContext("/test", new MyHandler());
    server.setExecutor(null); // creates a default executor
    server.start();

    Thread.sleep(10);


    Map<String,String> headers = map("foo", "bar", "fun", "sun");

    String response = HTTP.postBodyWithContentType("http://localhost:9213/foo", headers, "text/plain", "hi mom");

    System.out.println(response);

    assertTrue(response.contains("hi mom"));
    assertTrue(response.contains("Fun=[sun], Foo=[bar]"));

    Thread.sleep(10);

    server.stop(0);


}

你可以在這裡找到其他的:

https://github.com/RichardHightower/boon

我的目標是提供人們想要以更簡單的方式進行的常見事情....


有2個選項可以使用HTTP URL命中:GET / POST

GET請求: -

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url";
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
System.out.println(String.valueOf(http_conn.getResponseCode()));

POST請求: -

HttpURLConnection.setFollowRedirects(true); // defaults to true

String url = "https://name_of_the_url"
URL request_url = new URL(url);
HttpURLConnection http_conn = (HttpURLConnection)request_url.openConnection();
http_conn.setConnectTimeout(100000);
http_conn.setReadTimeout(100000);
http_conn.setInstanceFollowRedirects(true);
http_conn.setDoOutput(true);
PrintWriter out = new PrintWriter(http_conn.getOutputStream());
if (urlparameter != null) {
   out.println(urlparameter);
}
out.close();
out = null;
System.out.println(String.valueOf(http_conn.getResponseCode()));

起初我被article贊成HttpClient article誤導了。

後來我意識到HttpURLConnection將會停留在這篇article

根據Google博客

Apache HTTP客戶端在Eclair和Froyo上的bug較少。 這是這些版本的最佳選擇。 對於薑餅,HttpURLConnection是最好的選擇。 其簡單的API和小尺寸使其非常適合Android。

透明壓縮和響應緩存減少網絡使用,提高速度並節省電池。 新的應用程序應該使用HttpURLConnection; 這正是我們將會耗費我們能源的地方。

在閱讀rapidvaluesolutions.com/tech_blog/…和其他一些關於流程問題的堆棧之後,我確信HttpURLConnection將持續更長的時間。

一些有利於HttpURLConnections的SE問題:

在Android上,使用URL編碼表單數據進行POST請求,而不使用UrlEncodedFormEntity

HttpPost在Java項目中工作,而不是在Android中工作





urlconnection