2.2. 자카르타 RESTful 웹 서비스 클라이언트
2.2.1. 자카르타 RESTful 웹 서비스 클라이언트 API
Jakarta RESTful Web Services 2.0은 HTTP 요청을 원격 RESTful 웹 서비스에 전송하기 위해 새 클라이언트 API를 도입했습니다. 3개의 주요 클래스가 있는 유연한 요청 빌드 API입니다.
-
클라이언트
-
WebTarget
-
응답
클라이언트
인터페이스는 WebTarget 인스턴스의 빌더입니다. WebTarget은 WebTarget
하위 리소스 WebTarget을 구축하거나 요청을 호출할 고유한 URL 또는 URL 템플릿을 나타냅니다.
클라이언트를 생성하는 방법에는 표준 방법 또는 ResteasyClientBuilder
클래스를 사용하는 두 가지 방법이 있습니다. ResteasyClientBuilder
클래스를 사용할 경우의 장점은 클라이언트를 구성하는 몇 가지 도우미 메서드를 제공한다는 것입니다.
ResteasyClientBuilder
클래스는 이러한 도우미 방법을 제공하지만 클래스는 JBoss EAP API에 따라 다릅니다. 애플리케이션을 새 서버로 마이그레이션하려면 애플리케이션을 다시 빌드해야 합니다. ResteasyClientBuilder
클래스는 RESTEasy에 따라 다르며 클래스는 이식할 수 없습니다.
클라이언트를 생성하는 표준 방법은 Jakarta RESTful Web Services 및 Jakarta EE API 사양을 모두 준수하며 Jakarta RESTful Web Services 구현에서 이식할 수 있습니다.
Jakarta RESTful Web Services 애플리케이션이 이식성을 유지하도록 하려면 Jakarta EE API 사양을 준수하고 가능한 경우 Jakarta EE API 애플리케이션을 사용합니다. 사용 사례에서 Jakarta EE API 사용을 지원하지 않는 경우에만 JBoss 고유의 API를 사용합니다.
이러한 지침에 따라 애플리케이션을 다른 서버로 마이그레이션하거나 새로운 Jakarta EE 호환 JBoss 구현으로 마이그레이션할 때 발생할 수 있는 문제 수를 줄일 수 있습니다.
표준 방법을 사용하여 클라이언트 생성
다음 예제에서는 클라이언트를 생성하는 표준 방법 중 하나를 보여줍니다.
Client client = ClientBuilder.newClient();
또는 다른 표준 방법을 사용하여 아래 예와 같이 클라이언트를 생성할 수 있습니다.
Client client = ClientBuilder.newBuilder().build(); WebTarget target = client.target("http://foo.com/resource"); Response response = target.request().get(); String value = response.readEntity(String.class); response.close(); // You should close connections!
ResteasyClientBuilder 클래스를 사용하여 클라이언트 생성
다음 예제에서는 ResteasyClientBuilder
클래스를 사용하여 클라이언트를 생성하는 방법을 보여줍니다.
ResteasyClient client = new ResteasyClientBuilder().build(); ResteasyWebTarget target = client.target("http://foo.com/resource");
Jakarta RESTful Web Services 2.1을 사용하면 ClientBuilder
클래스에 두 개의 시간 제한 메서드를 추가할 수 있습니다. 시간 제한 메서드는 사양 준수 메서드이며 RESTEasy 메서드를 사용하는 대신 사용할 수 있습니다.
다음 ClientBuilder
사양 준수 방법은 더 이상 사용되지 않는 특정 RESTEasy 메서드를 대체합니다.
connectTimeout
메서드는establishConnectionTimeout
메서드를 대체합니다.connectTimeout
메서드는 새 서버 연결을 만들 때 클라이언트가 기다려야 하는 시간을 결정합니다.readTimeout
메서드는socketTimeout
메서드를 대체합니다.readTimeout
메서드는 클라이언트가 서버의 응답을 기다리는 시간을 결정합니다.
다음 예제에서는 connectTimeout 및
메서드에 대해 지정된 값을 보여줍니다.
readTimeout
import javx.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Client; Client client = ClientBuilder.newBuilder() .connectTimeout(100, TimeUnit.SECONDS) .readTimeout(2, TimeUnit.SECONDS) .build();
readTimeout
은 기존 연결에서 실행된 요청에 적용됩니다.
timeout 매개 변수 값을 0으로 설정하면 서버가 무기한 대기합니다.
RESTEasy는 META-INF/services/javax.ws.rs.ext.Providers
파일에 나열된 모든 클래스를 포함하는 기본 프로바이더 세트를 자동으로 로드합니다. 또한 메서드 호출 Client.configuration()
에서 제공하는 구성 개체를 통해 다른 공급자, 필터 및 인터셉터를 수동으로 등록할 수 있습니다. 또한 구성을 사용하면 필요할 수 있는 구성 속성을 설정할 수 있습니다.
각 WebTarget
에는 상위 인스턴스에 등록된 구성 요소 및 속성을 상속하는 구성 인스턴스가 있습니다. 이를 통해 각 대상 리소스(예: 사용자 이름 및 암호)에 대한 특정 구성 옵션을 설정할 수 있습니다.
추가 리소스
-
ResteasyClientBuilder
클래스 및 해당 메서드에 대한 자세한 내용은 Class ResteasyClientBuilder 를 참조하십시오.
RESTEasy 클라이언트 클래스 사용
RESTEasy 클라이언트에 대한 다음 종속성을 Maven pom.xml 파일에 추가해야 합니다.
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>VERSION_IN_EAP</version>
</dependency>
RESTEasy 클라이언트 클래스를 사용하는 작업 예제를 위해 JBoss EAP와 함께 제공되는 ja
빠른 시작을 참조하십시오.
xrs-client
및 resteasy-jaxrs-client
클라이언트측 필터
클라이언트 쪽에는 두 가지 유형의 필터가 있습니다.
ClientRequestFilter
-
ClientRequestFilter
는 HTTP 요청을 서버로 전송하기 전에 실행됩니다.ClientRequestFilter
는 요청 실행을 중단하고 서버에 대한 유선을 사용하지 않고 준비된 응답을 제공할 수도 있습니다. ClientResponseFilter
-
ClientResponseFilter
는 서버에서 응답을 수신한 후에 실행되지만 응답 본문이 마샬링되지 않습니다.ClientResponseFilter
는 애플리케이션 코드에 전달되기 전에 response 오브젝트를 수정할 수 있습니다. 다음 예제에서는 이러한 개념을 보여줍니다.
// execute request filters for (ClientRequestFilter filter : requestFilters) { filter.filter(requestContext); if (isAborted(requestContext)) { return requestContext.getAbortedResponseObject(); } } // send request over the wire response = sendRequest(request); // execute response filters for (ClientResponseFilter filter : responseFilters) { filter.filter(requestContext, responseContext); }
클라이언트측 필터를 클라이언트 요청에 등록
다음 예제에서는 클라이언트 측 필터를 클라이언트 요청에 등록하는 방법을 보여줍니다.
client = ClientBuilder.newClient(); WebTarget base = client.target(generateURL("/") + "get"); base.register(ClientExceptionsCustomClientResponseFilter.class).request("text/plain").get();
클라이언트 측 캐시
RESTEasy에는 클라이언트 측 캐시를 설정할 수 있는 기능이 있습니다. 이 캐시는 서버 응답으로 다시 전송된 cache-control 헤더를 찾습니다. cache-control 헤더가 클라이언트가 응답을 캐시할 수 있도록 지정하는 경우 RESTEasy는 로컬 메모리 내에 캐시합니다.
ResteasyWebTarget target = client.target(generateBaseUrl()); target.register(BrowserCacheFeature.class);
청크 인코딩 지원
RESTEasy는 클라이언트 API에 요청을 청크 전송 모드로 보내도록 지정하는 기능을 제공합니다. 아래와 같이 청크된 전송 모드를 지정하는 방법은 두 가지가 있습니다.
청크된 모드로 모든 요청을 보내도록
org.jboss.resteasy.client.jaxrs.ResteasyWebTarget
을 구성할 수 있습니다.ResteasyClient client = new ResteasyClientBuilder().build(); ResteasyWebTarget target = client.target("http://localhost:8081/test"); target.setChunked(b.booleanValue()); Invocation.Builder request = target.request();
또는 청크된 모드로 보낼 특정 요청을 구성할 수도 있습니다.
ResteasyClient client = new ResteasyClientBuilder().build(); ResteasyWebTarget target = client.target("http://localhost:8081/test"); ClientInvocationBuilder request = (ClientInvocationBuilder) target.request(); request.setChunked(b);
javax.ws.rs.client.Invocation.Builder
클래스와 달리org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder
는 RESTEasy 클래스입니다.
청크된 모드에서 요청을 보내는 기능은 기본 전송 계층에 따라 다릅니다. 특히, 사용 중인 org.jboss.resteasy.client.jaxrs.ClientHttpEngine
클래스의 구현에 따라 달라집니다. 현재는 기본 구현 ApacheHttpClient43Engine
과 이전 구현 ApacheHttpClient4Engine
만 청크된 모드를 지원합니다. 이 두 가지는 모두 org.jboss.resteasy.client.jaxrs.engines
패키지에서 사용할 수 있습니다. 자세한 내용은 HTTP 클라이언트로 RESTEasy 구현 섹션을 참조하십시오.
2.2.2. HTTP 클라이언트로 RESTEasy 구현
클라이언트와 서버 간의 네트워크 통신은 기본적으로 RESTEasy에서 처리됩니다. Apache HttpComponents
프로젝트의 HttpClient
를 사용합니다. RESTEasy 클라이언트 프레임워크와 네트워크 간의 인터페이스는 ClientHttpEngine
인터페이스에서 정의합니다.
RESTEasy는 이 인터페이스의 네 가지 구현과 함께 제공됩니다. 기본 구현은 ApacheHttpClient43Engine
입니다. 이 구현에서는 Apache 4.3을 사용합니다.
ApacheHttpClient4Engine
은 Apache 4.3 이전 버전을 사용하는 구현입니다. 이 클래스는 이전 버전과의 호환성을 제공합니다. RESTEasy는 Apache 버전의 탐지를 기반으로 이 두 개의 ClientHttpEngine
구현 중 하나를 자동으로 선택합니다. InMemoryClientEngine
은 동일한 JVM의 서버로 요청을 디스패치하는 구현이며 URLConnectionEngine
은 java.net.HttpURLConnection
을 사용하는 구현입니다.
클라이언트 실행자는 특정 ClientRequest
로 전달할 수 있습니다.
ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
RESTEasy 및 HttpClient
는 HttpClient를 참조하지 않고 클라이언트 프레임워크를 사용하도록 기본 결정을 내립니다 .
그러나 일부 애플리케이션의 경우 HttpClient
세부 정보를 자세히 살펴보아야 할 수 있습니다. ApacheHttpClient43Engine
및 ApacheHttpClient4Engine
은 org.apache.http.client.HttpClient 및
의 인스턴스를 제공하여 org.
apache.http.protocol.HttpContextHttpClient
계층에 추가 구성 세부 정보를 전달할 수 있습니다. 예를 들어 인증을 다음과 같이 구성할 수 있습니다.
// Configure HttpClient to authenticate preemptively // by prepopulating the authentication data cache. // 1. Create AuthCache instance AuthCache authCache = new BasicAuthCache(); // 2. Generate BASIC scheme object and add it to the local auth cache AuthScheme basicAuth = new BasicScheme(); authCache.put(new HttpHost("sippycups.bluemonkeydiamond.com"), basicAuth); // 3. Add AuthCache to the execution context BasicHttpContext localContext = new BasicHttpContext(); localContext.setAttribute(ClientContext.AUTH_CACHE, authCache); // 4. Create client executor and proxy HttpClient httpClient = HttpClientBuilder.create().build(); ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient, localContext); ResteasyClient client = new ResteasyClientBuilder().httpEngine(engine).build();
HttpContextProvider
는 RESTEasy에서 제공하는 인터페이스로, ApacheHttpClient43Engine 및
구현에 사용자 지정 ApacheHttpClient4Engine
HttpContext
를 제공할 수 있습니다.
연결 해제 와 연결 종료 의 차이점을 이해하는 것이 중요합니다. 연결을 해제하면 재사용할 수 있습니다. 연결을 종료하면 리소스를 확보하고 사용할 수 없게 됩니다.
RESTEasy는 알림 없이 연결을 해제합니다. 유일한 카운터 예제는 응답이 InputStream
의 인스턴스인 경우이며 명시적으로 닫혀야 합니다.
반면 호출 결과가 Response의 인스턴스인 경우 Response
.close()
메서드를 사용하여 연결을 해제해야 합니다.
WebTarget target = client.target("http://localhost:8081/customer/123"); Response response = target.request().get(); System.out.println(response.getStatus()); response.close();
이 작업은 최종 블록에서 실행할 수 있습니다 .
연결을 해제하면 다른 용도로 사용할 수 있습니다. 일반적으로 소켓을 닫지 않습니다.
ApacheHttpClient4Engine.finalize()
는 열려 있는
모든 소켓을 닫습니다. JDK를 사용하여 finalize()
를 호출하는 것은 안전하지 않습니다. HttpClient
가 ApacheHttpClient4Executor
에 전달되면 아래와 같이 사용자가 연결을 종료해야 합니다.
HttpClient httpClient = new HttpClientBuilder.create().build(); ApacheHttpClient4Engine executor = new ApacheHttpClient4Engine(httpClient); ... httpClient.getConnectionManager().shutdown();
ApacheHttpClient4Engine
이 HttpClient
의 자체 인스턴스를 생성한 경우, 오픈 소켓을 닫기 위해 finalize()
를 기다릴 필요가 없습니다. ClientHttpEngine 인터페이스에는
이러한 목적을 위한 close()
메서드가 있습니다.
마지막으로 javax.ws.rs.client.Client
클래스에서 자동으로 엔진을 생성한 경우 Client.close()
를 호출합니다. 이 호출은 모든 소켓 연결을 정리합니다.
2.2.2.1. HTTP 리디렉션
Apache HttpClient를 기반으로 하는 ClientHttpEngine
구현은 HTTP 리디렉션을 지원합니다. 이 fCenterre는 기본적으로 비활성화되어 있습니다. 다음과 같이 setFollowRedirects
메서드를 true
로 설정하여 활성화할 수 있습니다.
ApacheHttpClient43Engine engine = new ApacheHttpClient43Engine(); engine.setFollowRedirects(true); Client client = new ResteasyClientBuilder().httpEngine(engine).build();