* 이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
(자바 버전 여행 ⑩)
자바 11은 8 다음으로 오래 쓰인 LTS다. 그중 개발자가 가장 반긴 건 표준 HttpClient다. 그전까지 HTTP 요청 한 번 보내려면 낡은 HttpURLConnection과 씨름하거나 외부 라이브러리를 붙여야 했다. 이제 JDK 안에 제대로 든 게 생겼다.
표준 HttpClient
java.net.http 패키지에 HttpClient·HttpRequest·HttpResponse 세 가지가 있다. 동기(send)와 비동기(sendAsync)를 모두 지원하고, HTTP/2도 기본이다.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.GET()
.build();
HttpResponse<String> res = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(res.statusCode());
System.out.println(res.body());
문자열·파일 편의 메서드
잔손이 많이 가던 것들도 표준으로 들어왔다.
| 하고 싶던 일 | Java 11 |
|---|---|
| 공백만 있는지 | str.isBlank() |
| 양끝 공백 제거(유니코드) | str.strip() |
| 문자열 반복 | “ab”.repeat(3) → ababab |
| 줄 단위 스트림 | str.lines() |
| 파일 통째로 읽기/쓰기 | Files.readString(path) / writeString(path, s) |
컴파일 없이 실행 — 단일 파일 실행
자바 11부터는 .java 파일 하나를 javac 없이 바로 실행할 수 있다. 스크립트처럼 자바를 쓸 수 있게 된 것이다.
$ java Hello.java # 컴파일 단계 없이 바로 실행
직접 해보기 — 표준 라이브러리만으로 API 호출하기
외부 의존성 하나 없이, JDK 11만으로 실제 요청을 보내 보자.
Fetch.java파일 하나에 아래 코드를 넣는다.java Fetch.java로 컴파일 없이 실행한다.- 상태 코드와 본문 앞부분이 찍히는지 본다.
import java.net.URI;
import java.net.http.*;
public class Fetch {
public static void main(String[] args) throws Exception {
var client = HttpClient.newHttpClient();
var req = HttpRequest.newBuilder(URI.create("https://httpbin.org/get")).build();
var res = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("status = " + res.statusCode());
System.out.println(res.body().lines().limit(3).toList());
}
}
실행해 보면 이렇게 나온다.
status = 200
[{, "args": {}, ...]
여기서 조금씩 바꿔 보자.
.GET()를.POST(HttpRequest.BodyPublishers.ofString("hi"))로 바꿔 httpbin.org/post에 보내 본다.send를sendAsync(...).thenAccept(...)비동기로 바꿔 본다.
한 걸음 더 — 응답을 Files.writeString(Path.of("out.json"), res.body())로 파일에 저장해 본다.
✅ 확인 — 외부 라이브러리 없이 HTTP 요청을 보내고, 단일 파일 실행이 무엇인지 설명할 수 있으면 통과다.
동기 vs 비동기 — 코드로
send는 결과를 기다리고, sendAsync는 CompletableFuture를 즉시 돌려줘 논블로킹으로 처리한다. 응답 본문은 BodyHandlers로 문자열·파일·스트림 형태로 받는다. HTTP/2도 기본 지원한다.
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create("https://api.example.com")).build();
// 동기
HttpResponse<String> res = client.send(req, HttpResponse.BodyHandlers.ofString());
// 비동기
client.sendAsync(req, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
POST와 JSON 보내기
본문은 BodyPublishers로 만든다. JSON을 보낼 땐 문자열 본문에 Content-Type 헤더를 붙인다. 표준 라이브러리엔 JSON 파서가 없어 직렬화는 별도(Jackson 등)로 하지만, 전송 자체는 HttpClient로 충분하다.
HttpRequest post = HttpRequest.newBuilder(URI.create("https://api.example.com/orders"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{\"item\":\"coffee\"}"))
.build();
한 번 만들어 재사용하라
HttpClient는 내부에 커넥션 풀과 설정을 들고 있으니, 한 번 만들어 재사용한다. 요청마다 새로 만들면 낭비다. 타임아웃·리다이렉트 정책·프록시·HTTP 버전은 빌더에서 한 번 지정해두면 그 클라이언트로 보내는 모든 요청에 적용된다.
단일 파일 실행 — 스크립트처럼
자바 11의 또 다른 선물. javac 없이 java Hello.java로 소스를 바로 실행한다. 작은 스크립트·학습, 그리고 이 시리즈의 실습에 딱이다. 자바 21 이후엔 가벼운 main 등으로 스크립팅이 더 편해지고 있다. ‘컴파일 → 실행’ 두 단계 없이 바로 돌려보는 맛이 학습의 문턱을 확 낮춘다.
자바 11이 더한 것을 봤으니, 다음 편은 반대로 자바 11이 빼버린 것들이다. 8에서 11로 올릴 때 가장 자주 터지는 사라진 API들을 짚는다.
자주 묻는 질문 (FAQ)
자바 11 HttpClient는 외부 라이브러리 없이 되나요?
네, JDK 표준(java.net.http)이라 의존성 없이 HTTP 요청을 보낼 수 있습니다. 동기·비동기, HTTP/2를 지원합니다.
단일 파일 실행이 뭔가요?
java Hello.java처럼 컴파일(javac) 없이 .java 하나를 바로 실행하는 기능입니다. 자바 11부터 됩니다.

답글 남기기