Java에서 간단한 HTTP 요청 수행

1. 개요

이 빠른 자습서에서는 기본 제공 Java 클래스 HttpUrlConnection 을 사용하여 Java에서 HTTP 요청을 수행 하는 방법을 제시합니다 .

JDK (11)을 시작으로 자바가에 대한 대체 의미 HTTP 요청을 수행하기위한 새로운 API 제공하는 참고 HttpURLConnection의, HttpClient를 API를.

2. HttpUrlConnection

HttpURLConnection의의 클래스는 우리가 할 수 있는 추가 라이브러리를 사용하지 않고 기본 HTTP 요청을 수행합니다. 필요한 모든 클래스는 java.net 패키지의 일부입니다 .

이 방법을 사용할 때의 단점은 코드가 다른 HTTP 라이브러리보다 번거롭고 헤더 또는 인증을 추가하는 전용 방법과 같은 고급 기능을 제공하지 않는다는 것입니다.

3. 요청 생성

URL 클래스 의 openConnection () 메서드를 사용하여 HttpUrlConnection 인스턴스를 만들 수 있습니다 . 이 메서드는 연결 개체 만 만들지 만 아직 연결을 설정하지는 않습니다.

HttpURLConnection의의 클래스는 설정하여 모든 유형의 요청에 사용되는 requestMethod의 GET, POST가, 머리, 옵션, PUT, DELETE, TRACE : 값 중 하나로 속성을.

GET 메서드를 사용하여 주어진 URL에 대한 연결을 생성 해 보겠습니다.

URL url = new URL("//example.com"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET");

4. 요청 매개 변수 추가

요청에 매개 변수를 추가 하려면 doOutput 속성을 true 로 설정 한 다음 HttpUrlConnection 인스턴스 OutputStreamparam1 = value¶m2 = value 형식 문자열 을 작성해야 합니다.

Map parameters = new HashMap(); parameters.put("param1", "val"); con.setDoOutput(true); DataOutputStream out = new DataOutputStream(con.getOutputStream()); out.writeBytes(ParameterStringBuilder.getParamsString(parameters)); out.flush(); out.close();

Map 매개 변수 의 변환을 용이하게하기 위해 우리는 필요한 형식 의 문자열Map 을 변환하는 정적 메소드 getParamsString ()을 포함하는 ParameterStringBuilder 라는 유틸리티 클래스를 작성했습니다 .

public class ParameterStringBuilder { public static String getParamsString(Map params) throws UnsupportedEncodingException{ StringBuilder result = new StringBuilder(); for (Map.Entry entry : params.entrySet()) { result.append(URLEncoder.encode(entry.getKey(), "UTF-8")); result.append("="); result.append(URLEncoder.encode(entry.getValue(), "UTF-8")); result.append("&"); } String resultString = result.toString(); return resultString.length() > 0 ? resultString.substring(0, resultString.length() - 1) : resultString; } }

5. 요청 헤더 설정

요청에 헤더를 추가하려면 setRequestProperty () 메서드를 사용합니다 .

con.setRequestProperty("Content-Type", "application/json");

연결에서 헤더 값을 읽으려면 getHeaderField () 메서드를 사용할 수 있습니다 .

String contentType = con.getHeaderField("Content-Type");

6. 시간 초과 구성

HttpUrlConnection 클래스를 사용 하면 연결 및 읽기 제한 시간을 설정할 수 있습니다 . 이러한 값은 서버에 대한 연결이 설정되거나 데이터를 읽을 수있을 때까지 기다리는 시간 간격을 정의합니다.

시간 제한 값을 설정하려면 setConnectTimeout ()setReadTimeout () 메서드를 사용할 수 있습니다 .

con.setConnectTimeout(5000); con.setReadTimeout(5000);

이 예에서는 두 시간 초과 값을 모두 5 초로 설정했습니다.

7. 쿠키 처리

java.net의 패키지는 쉽게 같은 쿠키와 협력하는 것이 클래스가 포함 CookieManager에끊어진 HttpCookie .

먼저 응답에서 쿠키읽기 위해 Set-Cookie 헤더 의 값을 검색하여 HttpCookie 개체 목록으로 구문 분석 할 수 있습니다.

String cookiesHeader = con.getHeaderField("Set-Cookie"); List cookies = HttpCookie.parse(cookiesHeader);

다음으로 쿠키를 쿠키 저장소에 추가합니다 .

cookies.forEach(cookie -> cookieManager.getCookieStore().add(null, cookie));

username 이라는 쿠키가 있는지 확인 하고 그렇지 않은 경우 "john"값으로 쿠키 저장소에 추가합니다.

Optional usernameCookie = cookies.stream() .findAny().filter(cookie -> cookie.getName().equals("username")); if (usernameCookie == null) { cookieManager.getCookieStore().add(null, new HttpCookie("username", "john")); }

마지막으로 요청에 쿠키추가 하려면 연결을 닫았다가 다시 연 후 Cookie 헤더 를 설정해야 합니다.

con.disconnect(); con = (HttpURLConnection) url.openConnection(); con.setRequestProperty("Cookie", StringUtils.join(cookieManager.getCookieStore().getCookies(), ";"));

8. 리디렉션 처리

true 또는 false 매개 변수 와 함께 setInstanceFollowRedirects () 메서드를 사용하여 특정 연결대해 자동으로 따르는 리디렉션을 활성화하거나 비활성화 할 수 있습니다 .

con.setInstanceFollowRedirects(false);

모든 연결에 대해 자동 리디렉션활성화 또는 비활성화 할 수도 있습니다 .

HttpUrlConnection.setFollowRedirects(false);

기본적으로이 동작은 활성화되어 있습니다.

요청이 리디렉션을 나타내는 상태 코드 301 또는 302를 반환하면 Location 헤더를 검색 하고 새 URL에 대한 새 요청을 만들 수 있습니다 .

if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM) { String location = con.getHeaderField("Location"); URL newUrl = new URL(location); con = (HttpURLConnection) newUrl.openConnection(); }

9. 응답 읽기

HttpUrlConnection 인스턴스 InputStream구문 분석하여 요청 응답을 읽을 수 있습니다 .

To execute the request, we can use the getResponseCode(), connect(), getInputStream() or getOutputStream() methods:

int status = con.getResponseCode();

Finally, let's read the response of the request and place it in a content String:

BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer content = new StringBuffer(); while ((inputLine = in.readLine()) != null) { content.append(inputLine); } in.close();

To close the connection, we can use the disconnect() method:

con.disconnect(); 

10. Reading the Response on Failed Requests

If the request fails, trying to read the InputStream of the HttpUrlConnection instance won't work. Instead, we can consume the stream provided by HttpUrlConnection.getErrorStream().

We can decide which InputStream to use by comparing the HTTP status code:

int status = con.getResponseCode(); Reader streamReader = null; if (status > 299) { streamReader = new InputStreamReader(con.getErrorStream()); } else { streamReader = new InputStreamReader(con.getInputStream()); }

And finally, we can read the streamReader in the same way as the previous section.

11. Building the Full Response

It's not possible to get the full response representation using the HttpUrlConnection instance.

However, we can build it using some of the methods that the HttpUrlConnection instance offers:

public class FullResponseBuilder { public static String getFullResponse(HttpURLConnection con) throws IOException { StringBuilder fullResponseBuilder = new StringBuilder(); // read status and message // read headers // read response content return fullResponseBuilder.toString(); } }

Here, we're reading the parts of the responses, including the status code, status message and headers, and adding these to a StringBuilder instance.

First, let's add the response status information:

fullResponseBuilder.append(con.getResponseCode()) .append(" ") .append(con.getResponseMessage()) .append("\n");

다음으로, getHeaderFields ()를 사용하여 헤더를 가져 와서 각각 HeaderName : HeaderValues 형식으로 StringBuilder추가합니다 .

con.getHeaderFields().entrySet().stream() .filter(entry -> entry.getKey() != null) .forEach(entry -> { fullResponseBuilder.append(entry.getKey()).append(": "); List headerValues = entry.getValue(); Iterator it = headerValues.iterator(); if (it.hasNext()) { fullResponseBuilder.append(it.next()); while (it.hasNext()) { fullResponseBuilder.append(", ").append(it.next()); } } fullResponseBuilder.append("\n"); });

마지막으로 이전에했던 것처럼 응답 내용읽고 추가합니다.

있습니다 getFullResponse의 방법은 요청이 성공 여부가 사용할 필요가 있는지 결정하기 위해 여부를 확인합니다 con.getInputStream () 또는 con.getErrorStream ()를 요청의 콘텐츠를 검색 할 수 있습니다.

12. 결론

이 기사에서는 HttpUrlConnection 클래스를 사용하여 HTTP 요청을 수행하는 방법을 보여주었습니다 .

예제의 전체 소스 코드는 GitHub에서 찾을 수 있습니다.