programing

java.net 사용방법URL HTTP 요청을 실행하고 처리하기 위한 연결

javaba 2022. 7. 27. 23:38
반응형

java.net 사용방법URL HTTP 요청을 실행하고 처리하기 위한 연결

의 사용에 대해서는 여기서 자주 묻는데 Oracle 튜토리얼이 너무 간결합니다.

이 튜토리얼에서는 기본적으로 GET 요청을 실행하고 응답을 읽는 방법만 보여 줍니다.POST 요청 실행, 요청 헤더 설정, 응답 헤더 읽기, 쿠키 처리, HTML 폼 제출, 파일 업로드 등에 사용하는 방법은 설명되지 않습니다.

어떻게 요?java.net.URLConnection'HTTP'는 'HTTP'를 사용합니까?

우선, 사전에 면책 사항: 투고된 코드 스니펫은 모두 기본적인 예시입니다.자질구레한 에도 대처할 IOException §RuntimeExceptionNullPointerException,ArrayIndexOutOfBoundsException자신을 돌볼 수 있는 것 같아

Java 대신 Android용으로 개발 중인 경우 API 수준 28이 도입된 이후 기본적으로 클리어텍스트 HTTP 요청이 비활성화되어 있습니다.다음을 사용하는 것이 좋습니다.HttpsURLConnection 꼭 할 수


준비하는

우선 적어도 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하여 맷하 format format format format format format format 로 연결되다.&또한 보통 를 사용하여 지정된 문자 집합으로 쿼리 파라미터를 URL 인코딩합니다.

String#format()그냥 편의상 하는 거예요.String 연산자 String이 할 때 하는 것이 좋습니다.+2월 1일


(옵션) 쿼리 파라미터를 사용한HTTP GET 요청 기동

그것은 사소한 일이다.기본 요청 방식입니다.

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

은 모두 "URL"을에 연결해야 합니다.?헤더는 파라미터가 어떤 부호화 상태인지 서버에 힌트를 줄 수 있습니다.쿼리 스트링을 송신하지 않으면,Accept-Charset헤더가 사라지다헤더를 설정할 필요가 없는 경우는, 쇼트 컷 방법을 사용할 수도 있습니다.

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

어느 쪽이든 상대방이 의 경우 그 메서드가 호출되고 파라미터는 에 의해 사용 가능하게 됩니다.

테스트 목적으로 다음과 같이 응답 본문을 표준 출력으로 인쇄할 수 있습니다.

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

쿼리 파라미터를 사용한HTTP POST 요청 기동

의 설정true는 요구 POST로 합니다. 표준 POST는 「HTTP POST」입니다.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」을 .name=value의 ""의 페어'<input type="hidden"> " " "도 마찬가지입니다. "name=value<input type="submit">이 요소는 프로그래밍 방식으로 "누르는" 요소입니다(버튼이 눌렸는지, 눌렸는지 여부를 구별하기 위해 서버 측에서 일반적으로 사용되기 때문입니다).

취득한 것을 에 캐스트 해, 대신에 사용할 수도 있습니다.단, 출력에 접속을 사용하려고 할 경우 다음과 같이 설정할 필요가 있습니다.true.

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

어느 쪽이든 상대방이 의 경우 그 메서드가 호출되고 파라미터는 에 의해 사용 가능하게 됩니다.


실제로 HTTP 요청을 실행하는 중

HTTP 요구를 명시적으로 기동할 수 있지만, HTTP 응답에 관한 정보(예를 들면, 를 사용하고 있는 응답 본체등)를 취득하는 경우는, 요구가 온 디맨드로 자동적으로 기동됩니다.위의 예에서는 정확하게 그렇게 되어 있습니다.connect()콜은 사실상 불필요한 것입니다.


HTTP 응답 정보 수집

  1. HTTP 응답 상태:

넌 여기 필요해.필요하다면 먼저 던져라.

    int status = httpConnection.getResponseCode();
  1. HTTP 응답 헤더:

     for (Entry<String, List<String>> header : connection.getHeaderFields().entrySet()) {
         System.out.println(header.getKey() + "=" + header.getValue());
     }
    
  2. HTTP 응답 부호화:

?Content-Type에는 를 contains contains a a가 되어 있습니다.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.
    }

세션 유지 관리

서버측 세션은 보통 쿠키에 의해 백업됩니다.일부 웹 양식에서는 사용자가 로그인하거나 세션에 의해 추적되어야 합니다.API를 사용하여 쿠키를 유지할 수 있습니다.모든 HTTP 요구를 송신하기 전에를 사용하여를 준비해야 합니다.

// 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();
// ...

이것은, 모든 상황에서 올바르게 동작하는 것은 아닙니다.실패했을 경우 쿠키 헤더를 수동으로 수집하여 설정하는 것이 가장 좋습니다.으로 다 요.Set-Cookie the 첫 headers " " " " " " " " " " " " " " " " " " " " " " " 。 " " " " " " " " " " " " "GET요청 후 후속 요청으로 전달합니다.

// 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 Attribute」등의 를 삭제하는 입니다.expires,path , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,cookie.substring(0, cookie.indexOf(';'))split().


스트리밍 모드

디폴트로는는 사용자가 를 사용하여 고정 콘텐츠 길이를 설정했는지 여부에 관계없이 실제로 전송하기 전에 요청 본문 전체를 버퍼링합니다.connection.setRequestProperty("Content-Length", contentLength); 때문에, 「」의 원인이 되는 가 있습니다OutOfMemoryException대량의 POST 요구(파일 업로드 등)를 동시에 송신할 수 있습니다.이것을 회피하려면 , 을 설정합니다.

httpConnection.setFixedLengthStreamingMode(contentLength);

단, 콘텐츠 길이를 사전에 알 수 없는 경우에는 를 적절히 설정하여 청크 스트리밍 모드를 사용할 수 있습니다.그러면 HTTP 헤더가 다음과 같이 설정됩니다.chunked그러면 요청 본문이 강제로 청크로 전송됩니다.다음 예제에서는 본문을 1KB의 청크로 전송합니다.

httpConnection.setChunkedStreamingMode(1024);

사용자 에이전트

실제브라우저에서 정상적으로 동작하는 동안 요청에 의해 예기치 않은 응답이 반환될 수 있습니다.서버 측에서 요청 헤더를 기반으로 요청을 차단하고 있을 수 있습니다.URLConnection에서는, 이 은 「이러다」로 되어 있습니다.Java/1.6.0_19JRE를 사용하다을 사용하다

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.

최근 브라우저의 User-Agent 문자열을 사용합니다.


에러 처리

가 HTTP인 4nn 오류) ('클라이언트 오류')5nn Error를 선택하면 (Server Error)를 수 .HttpURLConnection#getErrorStream()서버에서 유용한 오류 정보가 전송되었는지 확인합니다.

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

HTTP 응답 코드가 -1인 경우 연결 및 응답 처리에 문제가 있습니다.HttpURLConnection오래된 JRE에서는 접속이 활성화되어 있기 때문에 다소 버그가 있습니다. , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .http.keepAlive to system systemfalse응용 프로그램 시작 시 다음을 통해 프로그래밍 방식으로 이 작업을 수행할 수 있습니다.

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

파일 업로드 중

통상, POST 컨텐츠(바이너리와 문자 데이터)의 혼재에는 부호화를 사용합니다.부호화의 상세한 것에 대하여는, 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();
}

반대쪽이 의 경우 메서드가 호출되어 에서 부품을 사용할 수 있게 됩니다(주의, 따라서 사용할 수 없습니다). getParameter() getPart()이 방법은 비교적 새로운 것으로, Servlet 3.0(Glassfish 3, Tomcat 7 등)에 도입되었습니다.Servlet 3.0 이전 버전에서는 Apache Commons FileUpload를 사용하여multipart/form-data부탁한다.또한 FileUpload 및 Servelt 3.0 접근법의 예를 보려면 이 답변을 참조하십시오.


신뢰할 수 없거나 잘못 구성된 HTTPS 사이트 처리

Java가 아닌 Android용으로 개발 중인 경우 주의하세요.개발 중에 올바른 증명서를 도입하지 않으면 다음 회피책으로 시간을 절약할 수 있습니다.하지만 당신은 그것을 생산에 사용해서는 안됩니다.현재(2021년 4월) Google은 안전하지 않은 호스트 이름 확인자를 감지한 경우 앱을 Play Store에 배포하지 않습니다. https://support.google.com/faqs/answer/7188426를 참조하십시오.

웹 스크레이퍼를 쓰고 있기 때문에 HTTPS URL을 연결해야 할 수 있습니다. '아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.javax.net.ssl.SSLException: Not trusted server certificate않는 SSL의 HTTPS 사이트java.security.cert.CertificateException: No subject alternative DNS name matching [hostname] found ★★★★★★★★★★★★★★★★★」javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_nameHTTPS를 사용합니다.

실행 1회 실행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 Http Components HttpClient가 이 모든 면에서 훨씬 편리합니다.


HTML 해석 및 추출

HTML에서 데이터를 해석하고 추출하는 것이 전부라면 Jsoup과 같은 HTML 파서를 사용하는 것이 좋습니다.

를 를 .HttpURLConnection URLConnection)URLConnection입니다.URLConnection.openConnection()HTTP URL ) ) 。

'이렇게'에 URLConnection#setDoOutput(true)대신 요청 방법을 암묵적으로 POST로 설정합니다.httpURLConnection.setRequestMethod("POST")이는 보다 자연스러운 것으로 간주될 수 있습니다(또한 PUT, DELETE 등의 다른 요청 메서드를 지정할 수도 있습니다).

또한 유용한 HTTP 상수도 제공되므로 다음을 수행할 수 있습니다.

int responseCode = httpURLConnection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

StackOverflow에 이것과 다른 질문을 보고영감을 받아 나는에 나오는 기술은 발견되는 대부분의 구체화하는 최소한의 오픈 소스 basic-http-client 만들었습니다.

google-module-client는 오픈 소스 리소스이기도 합니다.

kevinsawicki/http-request의 코드를 보시길 권합니다. 기본적으로 그 위에 포장지가 있습니다.HttpUrlConnection지금 바로 요청을 하고 싶은 경우나 소스(너무 크지 않은 경우)를 보고 접속 처리 방법을 확인할 수 있는 경우 훨씬 더 간단한 API를 제공합니다.

": "를 .GET type이 「」인 application/json 몇 파라미터 " " " " " 입니다.

// GET http://google.com?q=baseball%20gloves&size=100
String response = HttpRequest.get("http://google.com", true, "q", "baseball gloves", "size", 100)
        .accept("application/json")
        .body();
System.out.println("Response was: " + response);

갱신하다

출하된 9의 모듈의 Client가 포함되어 .jdk.incubator.httpclient인큐베이터 모듈은 최종적이지 않은 API를 개발자의 손에 맡기 위한 수단이며, API는 향후 출시에서 최종화 또는 삭제로 진행됩니다.

9 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 클라이언트는 에 있습니다. jdk.incubator.httpclient이 .module-info.java 삭제:

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

HTTP URL Hits에는 GET / POST의 2가지 옵션이 있습니다.

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()));

저도 이 답변에 매우 감명받았습니다.

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

그 때 하고 싶은 공통점을 조금 더 쉽게 제공하는 것이 목표입니다.

처음에 나는 이 기사에 현혹되었다HttpClient.

에서야 깨달은 것은 중에 later later later later later later 。HttpURLConnection 기사에 관여하지 않습니다.

Google 블로그에 따르면:

Apache HTTP 클라이언트의 Eclair 및 Froyo 버그가 적습니다.이러한 릴리스에서는 이것이 최선의 선택입니다.Gingerbread의 경우 HttpURL Connection이 최선의 선택입니다.심플한 API와 작은 사이즈로 Android에 매우 적합합니다.

투과적인 압축 및 응답 캐싱으로 네트워크 사용을 줄이고 속도를 향상시키며 배터리를 절약합니다.새 응용 프로그램은 Http를 사용해야 합니다.URL 연결: 이것이 우리가 앞으로 에너지를 소비하는 곳입니다.

기사와 다른 스택 오버 플로우 질문을 읽고, 나는 확신했다.HttpURLConnection더 오래 머무르게 됩니다.

SE를 입니다.HttpURLConnections:

Android에서는 UrlEncodedFormEntity를 사용하지 않고 URL EncodedForm 데이터로 POST 요청

HttpPost는 Java 프로젝트에서 작동하지만 Android에서는 작동하지 않습니다.

기본적으로 효율적인 HTTP 클라이언트인 OkHttp도 있습니다.

  • HTTP/2 를 서포트하면, 같은 호스트에 대한 모든 요구가 소켓을 공유할 수 있습니다.
  • 연결 풀링은 요청 지연 시간을 줄입니다(HTTP/2를 사용할 수 없는 경우).
  • 투과적인 GZIP은 다운로드 크기를 줄입니다.
  • 응답 캐싱은 반복 요청에 대한 네트워크를 완전히 방지합니다.

저저 of of of of of of of of of 의 인스턴스를 .OkHttpClient:

OkHttpClient client = new OkHttpClient();

이렇게 준비하세요.GET★★★★

Request request = new Request.Builder()
      .url(url)
      .build();

""를 사용합니다.OkHttpClient된 것을 Request:

Response response = client.newCall(request).execute();

상세한 것에 대하여는, OkHttp 의 메뉴얼을 참조해 주세요.

jcabi-http(나는 개발자)에서도 사용할 수 있습니다.이 모든 작업을 대신하고 Http를 꾸밀 수 있습니다.URL 연결, HTTP 요청 실행 및 응답 구문 분석. 예를 들어 다음과 같습니다.

String html = new JdkRequest("http://www.google.com").fetch().body();

상세한 것에 대하여는, 다음의 블로그 투고를 참조해 주세요.http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

HTTP GET 를 사용하고 있는 경우는, 다음의 행을 삭제해 주세요.

urlConnection.setDoOutput(true);

기존 HttpUrlConnection 클래스 대신 Java 11(Android 제외)을 사용하는 경우 Java 11의 새로운 HTTP Client API를 사용할 수 있습니다.

GET 요구의 를 다음에 나타냅니다.

var uri = URI.create("https://httpbin.org/get?age=26&isHappy=true");
var client = HttpClient.newHttpClient();
var request = HttpRequest
        .newBuilder()
        .uri(uri)
        .header("accept", "application/json")
        .GET()
        .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());

동일한 요청이 비동기적으로 실행되었습니다.

var responseAsync = client
        .sendAsync(request, HttpResponse.BodyHandlers.ofString())
        .thenApply(HttpResponse::body)
        .thenAccept(System.out::println);
// responseAsync.join(); // Wait for completion

POST 요구의 예:

var request = HttpRequest
        .newBuilder()
        .uri(uri)
        .version(HttpClient.Version.HTTP_2)
        .timeout(Duration.ofMinutes(1))
        .header("Content-Type", "application/json")
        .header("Authorization", "Bearer fake")
        .POST(BodyPublishers.ofString("{ title: 'This is cool' }"))
        .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());

.multipart/form-datasyslog url-displays)application/x-www-form-urlencoded) 포맷, 이 솔루션을 참조하십시오.

HTTP 클라이언트 API 의 예와 상세한 것에 대하여는, 다음의 문서를 참조해 주세요.

언급URL : https://stackoverflow.com/questions/2793150/how-to-use-java-net-urlconnection-to-fire-and-handle-http-requests

반응형