JEP 110: HTTP Client (Incubator)
Summary
HTTP / 2 및 WebSocket을 구현하는 새 HTTP 클라이언트 API를 정의하고 기존 HttpURLConnectionAPI를 대체 할 수 있습니다 . API는 JEP 11 , JDK 9에 정의 된 바와 같이 인큐베이터 모듈로 제공됩니다. 이는 다음을 의미합니다.
- API와 구현은 Java SE에 포함되지 않습니다.
- API는 jdk.incubtor 네임 스페이스 아래에 있습니다.
- 모듈은 컴파일 또는 실행시 기본적으로 해석되지 않습니다.
Motivation
기존 HttpURLConnectionAPI 및 그 구현에는 많은 문제점이 있습니다.
- 기본 URLConnectionAPI는 지금 소멸 (있는 거의 모두 염두에두고 여러 프로토콜로 설계되었다 ftp, gopher등).
- API는 HTTP / 1.1보다 앞서서 너무 추상적입니다.
- 많은 문서화되지 않은 행동으로 사용하기가 어렵습니다.
- 블로킹 모드에서만 작동합니다 (요청 / 응답 당 하나의 스레드).
- 유지하기가 매우 어렵습니다.
Goals
simple blocking mode를 포함하여 일반적인 경우에 사용하기 쉬워야합니다.
“headers received”, errors, and “response body received”과 같은 이벤트 알림을 제공해야합니다. 이 알림은 반드시 콜백을 기반으로하지는 않지만 CompletableFuture와 같은 비동기 메커니즘을 사용할 수 있습니다.
애플리케이션 요구의 80-90 %를 충족시키는 간단하고 간결한 API입니다. 이것은 아마도 프로토콜의 모든 기능을 노출하지 않는 상대적으로 작은 API 풋 프린트를 의미합니다.
HTTP 프로토콜 요청의 모든 관련 측면을 서버에 노출하고 서버의 응답 (헤더, 본문, 상태 코드 등)을 노출해야합니다.
표준 및 공통 인증 메커니즘을 지원해야합니다. 초기에는 기본 인증으로 만 제한됩니다.
WebSocket 핸드 셰이크를 쉽게 설정할 수 있어야합니다.
HTTP / 2를 지원해야합니다 . (HTTP / 2의 애플리케이션 레벨 의미는 1.1과 거의 동일하지만 와이어 프로토콜은 완전히 다릅니다.)
- 1.1에서 2로 업그레이드를 협상 할 수 있어야하며, 그렇지 않으면 처음부터 2를 선택해야합니다.
- 서버 푸시 (Server Push)를 지원해야합니다. 즉, 서버가 클라이언트의 명시 적 요청없이 클라이언트에 자원을 푸시하는 기능입니다.
기존 네트워킹 API와 일치하는 보안 검사를 수행해야합니다.
람다 식과 같은 새로운 언어 기능에 친숙해야합니다.
임베디드 시스템 요구 사항에 맞춰야하며 특히 타이머 스레드를 영구적으로 실행하지 않아야합니다.
HTTPS / TLS를 지원해야합니다.
HTTP / 1.1의 성능 요구 사항 :
- 성능은 기존 HttpURLConnection 구현 과 동등해야합니다.
- 성능은 클라이언트 API로 사용될 때 Apache HttpClient 라이브러리 및 Netty 및 Jetty와 동등해야합니다.
- 새 API의 메모리 소비 HttpURLConnection는 클라이언트 API로 사용되는 경우 Apache HttpClient 및 Netty 및 Jetty 보다 낮거나 같아야합니다 .
HTTP / 2의 성능 요구 사항 :
- 플랫폼의 제한 사항 (예 : TCP 세그먼트 확인 창)에도 불구하고 성능은 새로운 프로토콜 (예 : 확장 성 및 대기 시간)에서 예상되는 방식으로 HTTP / 1.1보다 우수해야합니다.
- 성능은 HTTP / 2 용 클라이언트 API로 사용될 때 Netty 및 Jetty와 동등해야합니다.
- 새 API의 메모리 소비 HttpURLConnection는 클라이언트 API로 사용할 때 Apache HttpClient 및 Netty 및 Jetty를 사용할 때보 다 낮아야 합니다.
성능 비교는 비교 가능한 운영 모드의 맥락에서만 가능할 것입니다. 새로운 API는 모든 가능한 유스 케이스를 다루는 것보다 단순하고 사용하기 쉬우므로,
이 작업은 JDK 9를 대상으로합니다. 일부 코드는 Java EE가 Servlet 4.0 API에서 HTTP / 2를 구현할 때 다시 사용할 수 있으므로 JDK 8 언어 기능과 가능한 경우 API 만 사용됩니다.
JDK 9에서 API를 사용하여 얻은 경험을 활용하면 Java SE에서 JDK 10의 java.net 네임 스페이스 아래에서 API를 표준화 할 수 있습니다.이 경우 JEP 10의 일부로 API 더 이상 인큐베이터 모듈로 존재하지 않습니다.
Non-Goals
이 API는 결국 HttpURLConnection새 코드 용 API를 대체하기위한 것이지만 새 API를 사용하여 이전 API를 즉시 구현하지는 않습니다. 이것은 미래의 일이 될 수 있습니다.
JDK 8 용 JEP의 이전 버전에서는 몇 가지 요구 사항이 고려되었지만 가능한 한 간단하게 API를 유지하기 위해 제외되었습니다.
- 요청 / 응답 필터링,
- 플러그 가능한 연결 캐시 및
- 일반적인 업그레이드 메커니즘.
이러한 요구 사항 중 일부 (예 : 연결 캐싱)는 점진적으로 HTTP / 2를 채택하면 덜 중요해질 것입니다.
Description
HTTP 클라이언트, 요청 및 응답에 대해 별도의 클래스가 정의 된 JDK 9의 프로토 타이핑 작업이 일부 수행되었습니다. 빌더 패턴은 변경 불가능한 엔티티를 변경 불가능한 제품에서 분리하는 데 사용되었습니다. 동기 블로킹 모드는 송수신을 위해 정의되고 java.util.concurrent.CompletableFuture를 기반으로하는 비동기 모드도 정의됩니다.
이 프로토 타입은 NIO SocketChannels에서 구현되었으며 Selectors 및 외부에서 제공되는 ExecutorServices로 구현 된 비동기 동작을 제공합니다.
프로토 타입 구현은 독립 실행 형이었습니다. 즉, 기존 스택이 변경되지 않아 호환성을 보장하고 처음부터 모든 기능을 지원해야하는 단계적 접근을 허용했습니다.
프로토 타입 API에는 다음이 포함됩니다.
- 서블릿 및 HTTP 서버 API와 같은 별도의 요청 및 응답;
- 다음 이벤트의 비동기 알림 :
- 수신 된 응답 헤더,
- 응답 오류,
- 접수 된 응답 본문
- 서버 푸시 (HTTP / 2 전용);
- HTTPS, via SSLEngine;
- Proxying;
- Cookies; and Authentication
추가 작업이 필요한 API 부분은 HTTP / 2 다중 응답 (서버 푸시) 및 HTTP / 2 구성을 지원하는 것입니다. 프로토 타입 구현은 거의 모든 HTTP / 1.1을 지원하지만 아직 HTTP / 2는 지원하지 않습니다.
HTTP / 2 proxying은 다음 변경에서 구현됩니다.
Alternatives
Jetty 및 Apache HttpClient 와 같은 기존 HTTP 클라이언트 API 및 구현이 많이 존재합니다 . 이 두 가지 모두 패키지와 클래스 수 측면에서 다소 무겁고 람다 식과 같은 새로운 언어 기능을 이용하지 않습니다.
Testing
내부 HTTP 서버는 회귀 및 TCK 테스트에 적합한 기반을 제공합니다. 기능 테스트에서도이 기능을 사용할 수 있지만 실제 HTTP 서버를 테스트해야 할 수 있습니다.