Java 용 REST 클라이언트를 어떻게 작성합니까? [닫은]


248

JSR 311 및 해당 구현을 통해 REST를 통해 Java 객체를 노출하는 강력한 표준이 있습니다. 그러나 클라이언트 측에는 웹 서비스를 숨기고 데이터를 투명하게 Java 객체에 마샬링하는 SOAP for Apache Axis와 비교할 수없는 것이없는 것 같습니다.

Java RESTful 클라이언트를 어떻게 작성합니까? HTTPConnection을 사용하고 결과를 수동으로 구문 분석합니까? 또는 Jersey 또는 Apache CXR과 같은 전문 클라이언트입니까?


Apache Incubator에서 Apache Wink 를 찾았습니다 . REST 서버 및 클라이언트를 작성하는 데 흥미로운 프로젝트가 될 수 있습니다.
Yaba

2
이것을 확인하십시오 : igorpolevoy.blogspot.com/2011/01/java-rest-with-ease.html thanks igor
ipolevoy

[Resting] ( code.google.com/p/resting )을 확인하십시오 . REST 서비스를 호출하고 한 단계로 XML / JSON / YAML 응답에서 오브젝트 목록을 작성할 것을 약속합니다.
neel

휴식에는 POST 요청에 문제가 있습니다.
RyanBrady

2
당신은 resteasy (Jboss에 의한)로 아주 간단한 방법으로 그것을 할 수 있습니다. 시작 안내서를 원할 경우 Java REST 클라이언트를 개발하는 방법에 대한 블로그 게시물을 작성했습니다 . 어쨌든 Java에는 수백 가지 대안이 있습니다.
귀도

답변:


205

이것은 오래된 질문 (2008)이므로 지금보다 많은 옵션이 있습니다.

업데이트 (2020 년에도 여전히 활성화 된 프로젝트) :

  • Apache HTTP 구성 요소 (4.2) Fluent 어댑터 -이 목록의 다른 여러 후보가 사용하는 JDK의 기본 대체입니다. 이전 Commons HTTP 클라이언트 3보다 우수하며 자체 REST 클라이언트를 빌드하는 데 사용하기가 더 쉽습니다. JSON 구문 분석 지원을 위해 Jackson 과 같은 것을사용해야하고 HTTP 컴포넌트 URIBuilder를 사용하여 Jersey / JAX-RS Rest 클라이언트와 유사한 자원 URI를 구성 할 수 있습니다. HTTP 구성 요소도 NIO를 지원하지만 REST의 짧은 요청 특성을 감안할 때 BIO보다 더 나은 성능을 얻지 못할 것입니다.Apache HttpComponents 5 는 HTTP / 2를 지원합니다.
  • OkHttp -http 구성 요소와 유사 목록의 다른 여러 후보가 사용하는 JDK의 기본 대체입니다. 최신 HTTP 프로토콜 (SPDY 및 HTTP2)을 지원합니다. 안드로이드에서 작동합니다. 불행히도 실제 리액터 루프 기반 비동기 옵션을 제공하지 않습니다 (위의 Ning 및 HTTP 구성 요소 참조). 그러나 최신 HTTP2 프로토콜을 사용하는 경우 이는 문제가되지 않습니다 (연결 수에 문제가 있다고 가정).
  • Ning Async-http-client -NIO 지원을 제공합니다. 이전에는 Sonatype에 의해 Async-http-client라고 했습니다 .
  • 하위 http 클라이언트 (okhttp, apache httpcomponents)를위한 Feign wrapper 일부 Jersey 및 CXF 확장과 유사한 인터페이스 스텁을 기반으로 클라이언트를 자동 작성합니다. 강력한 스프링 통합.
  • 개조 -하위 http 클라이언트 (okhttp) 용 래퍼. 일부 Jersey 및 CXF 확장과 유사한 인터페이스 스텁을 기반으로 클라이언트를 자동 작성합니다.
  • 발리 jdk http 클라이언트 용 래퍼 (Google 제공)
  • google-httpjdk http 클라이언트 용 래퍼 또는 Google의 Apache httpcomponents
  • 유니 레스트 JDK http 클라이언트 용 래퍼
  • 편한 jboss 프레임 워크의 일부인 jboss에 의해 jdk http 클라이언트를위한 JakartaEE 래퍼
  • jcabi-http아파치 httpcomponents를위한 래퍼, jcabi 컬렉션의 일부
  • 식당아파치 httpcomponents를위한 wrapper, restlet framework의 일부
  • 안심 래퍼를 쉽게 테스트 주장에

HTTP / REST 클라이언트 선택시주의 사항 프레임 워크 스택이 HTTP 클라이언트에 사용중인 항목, 스레딩 방법을 확인하고 동일한 클라이언트가 제공하는 경우 이상적으로 사용하십시오. Vert.x 또는 Play와 같은 것을 사용하는 경우 프레임 워크가 제공하는 버스 또는 리액터 루프에 참여하기 위해 백킹 클라이언트를 사용하려고 할 수 있습니다. 그렇지 않으면 흥미로운 스레딩 문제에 대비하십시오.


1
JDK <8과 함께 사용할 경우 불행하게도 뉴저지 클라이언트 패치 방법을 지원하지 않습니다
botchniaque

3
Unirest는 사용하기가 쉽지만 정적 디자인으로 공유 및 서버 환경에서 사용할 수 없습니다.
bekce

9
unirest 의견 과 관련하여 현재 (2016 년 말) 이이 프로젝트가 더 이상 유지되지 않는 것처럼 보입니다. 새로운 관리자를 요구 하는 문제가 열려 있습니다.
wegenmic

4
같은 사람들을 위해 Unirest , 내가있어 포크 현재 활발히 / 유지되고, 업데이트의 IT의를.
Josh

3
답변을 커뮤니티 위키로 바꾸는 것이 좋을 것입니다
tkruse

72

이 스레드 에서 언급했듯이 JAX-RS를 구현하고 멋진 REST 클라이언트와 함께 제공되는 Jersey 를 사용하는 경향이 있습니다 . JAX-RS를 사용하여 RESTful 자원을 구현하면 Jersey 클라이언트가 JAXB / XML / JSON / Atom과 같은 엔티티 제공자를 재사용 할 수 있으므로 서버 측에서 동일한 오브젝트를 재사용 할 수 있습니다. 클라이언트 측 장치 테스트에서 사용하십시오.

예를 들어 여기Apache Camel 프로젝트 의 단위 테스트 사례 가 있습니다 (JAXB 객체 엔드 포인트를 사용하여) RESTful 리소스에서 XML 페이로드를 조회합니다. resource (uri) 메소드는 Jersey 클라이언트 API를 사용하는 이 기본 클래스에 정의되어 있습니다.

예 :

    clientConfig = new DefaultClientConfig();
    client = Client.create(clientConfig);

    resource = client.resource("http://localhost:8080");
    // lets get the XML as a String
    String text = resource("foo").accept("application/xml").get(String.class);        

BTW JAX-RS의 미래 버전이 Jersey의 라인을 따라 멋진 클라이언트 측 API를 추가하기를 바랍니다.


서버가 다운 된 경우 다음 서버를 시도하는 경우 ClientResource에 REST 서비스 서버 목록을 언급 할 수있는 방법이 있습니까?
Njax3SmmM2x2a0Zf7Hpd

1
: 그냥 업데이 트하지만, 주소 제임스 'BTW'주석, 2.0 클라이언트 측 API를해야합니다 JAX-RS의 새 버전으로 infoq.com/presentations/Java-REST
닉 Klauer

65

표준 Java SE API를 사용할 수 있습니다.

private void updateCustomer(Customer customer) { 
    try { 
        URL url = new URL("http://www.example.com/customers"); 
        HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 
        connection.setDoOutput(true); 
        connection.setInstanceFollowRedirects(false); 
        connection.setRequestMethod("PUT"); 
        connection.setRequestProperty("Content-Type", "application/xml"); 

        OutputStream os = connection.getOutputStream(); 
        jaxbContext.createMarshaller().marshal(customer, os); 
        os.flush(); 

        connection.getResponseCode(); 
        connection.disconnect(); 
    } catch(Exception e) { 
        throw new RuntimeException(e); 
    } 
} 

또는 Jersey와 같은 JAX-RS 구현에서 제공하는 REST 클라이언트 API를 사용할 수 있습니다. 이 API는 사용하기 쉽지만 클래스 경로에 추가 jar이 필요합니다.

WebResource resource = client.resource("http://www.example.com/customers"); 
ClientResponse response = resource.type("application/xml");).put(ClientResponse.class, "<customer>...</customer."); 
System.out.println(response); 

자세한 내용은 다음을 참조하십시오.


15
간단한 휴식 호출을위한 13 개 라인, 2018 년 , 너무 많은 방법 같은 소리 ...
클린트 이스트 우드

1
오류 처리 및 옵션을 추가하면 크게 다르지 않습니다. SE 접근 방식이 길어 보인다면 항상 클래스로 랩핑 할 수 있습니다 ... :> JAX-RS 라이브러리 충돌을 이틀 디버깅 한 후 전체 SPI 악몽을 피하기 위해 5 줄의 코드를 추가하면 정말 좋습니다.
tekHedd

2
@ClintEastwood이 포스트는 2010 년에 작성되었습니다
0ddlyoko

13

REST 서비스 만 호출하고 응답을 구문 분석하려면 Rest Assured를 사용해보십시오.

// Make a GET request to "/lotto"
String json = get("/lotto").asString()
// Parse the JSON response
List<String> winnderIds = with(json).get("lotto.winners.winnerId");

// Make a POST request to "/shopping"
String xml = post("/shopping").andReturn().body().asString()
// Parse the XML
Node category = with(xml).get("shopping.category[0]");

나는 이것이 제안 된 다른 많은 솔루션보다 더 우아하다는 것을 알았습니다.
Herve Mutombo

9

Restlet 도 확인할 수 있습니다 전체 클라이언트 측 기능이있는 을 , HttpURLConnection 또는 Apache HTTP Client (커넥터로 활용할 수있는)와 같은 하위 레벨 라이브러리보다 REST에 중점을 둔 REST를 지향합니다.

안부, 제롬 루벨


2
2019-10-24 현재 제공된 링크는 'Restlet Platform의 수명이 다했습니다.'
Hans Deragon

6

Rapa 시도해 볼 수 있습니다. 이에 대한 귀하의 의견을 알려주십시오. 문제 나 예상 기능을 자유롭게 기록하십시오.


1
Rapa는 정말 멋진 인터페이스와 종속성이 거의 없습니다. .NET 세계에서 RestSharp에 대한 좋은 대안입니다.
오후

이 프로젝트는 죽은 보인다
tkruse



5

최근에 Retrofit Library를 정사각형으로 시도했지만 훌륭하고 나머지 API를 매우 쉽게 호출 할 수 있습니다. 주석 기반 구성을 통해 많은 보일러 플레이트 코딩을 제거 할 수 있습니다.


4

Apache HTTPClient를 사용하여 모든 HTTP 측면을 처리합니다.

XML을 개체 모델로 구문 분석하는 XML 내용에 대한 XML SAX 파서를 작성합니다. Axis2도 XML-> Model 메소드를 노출한다고 생각합니다 (Axis 1 은이 부분을 성가 시게 숨겼습니다). XML 생성기는 간단합니다.

제 생각에는 코딩하는 데 시간이 오래 걸리지 않으며 매우 효율적입니다.


4
제 생각에는 이것이 REST를 수행하는 최악의 방법입니다. JAXB 및 Jackson과 같은 많은 옵션이있는 경우 Java에서 직렬화를 수동으로 처리하는 것은 시간 낭비입니다. 전체 문서를로드하고 XPath를 사용하더라도 SAX보다 속도가 느리고 XML (네트워크 속도)을 얻는 것과 비교할 수 없습니다.
Adam Gent

1
나도 동의하고 원래 의견을 썼습니다. 당시에는 역 직렬화를 제어하고 싶었지만 요즘에는 Jackson과 적절한 주석이 달린 모델 클래스를 사용합니다.
JeeBee

4

OkHttp는 Retrofit과 결합하여 가볍고 강력합니다. 이것은 일반적인 Java 사용뿐만 아니라 Android에서도 잘 작동합니다.

OkHttp : http://square.github.io/okhttp/

public static final MediaType JSON
    = MediaType.parse("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
  RequestBody body = RequestBody.create(JSON, json);
  Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
  Response response = client.newCall(request).execute();
  return response.body().string();
}

개조 : http://square.github.io/retrofit/

public interface GitHubService {
  @GET("/users/{user}/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
}


2

HTTP 클라이언트를 작성하고 reuest를 만드는 것은 간단하지만. 그러나 자동 생성 된 일부 클라이언트를 사용하려는 경우 WADL을 사용하여 코드를 설명하고 생성 할 수 있습니다.

RestDescribe 를 사용 하여 WSDL을 생성하고 컴파일 할 수 있으며이를 사용 하여 php, ruby, python, java 및 C #로 클라이언트를 생성 할 수 있습니다. 깨끗한 코드를 생성하고 코드 생성 후에 약간 수정 해야하는 좋은 변경 사항이 있습니다 . 여기 에서 도구 뒤에 좋은 문서와 기본 생각을 찾을 수 있습니다 .

wintermute에 언급 된 흥미롭고 유용한 WADL 도구 는 거의 없습니다.




0

http-rest-client를보십시오

https://github.com/g00dnatur3/http-rest-client

다음은 간단한 예입니다.

RestClient client = RestClient.builder().build();
String geocoderUrl = "http://maps.googleapis.com/maps/api/geocode/json"
Map<String, String> params = Maps.newHashMap();
params.put("address", "beverly hills 90210");
params.put("sensor", "false");
JsonNode node = client.get(geocoderUrl, params, JsonNode.class);

라이브러리는 json 직렬화 및 바인딩을 처리합니다.

여기 또 다른 예가 있습니다.

RestClient client = RestClient.builder().build();
String url = ...
Person person = ...
Header header = client.create(url, person);
if (header != null) System.out.println("Location header is:" + header.value());

마지막 예는

RestClient client = RestClient.builder().build();
String url = ...
Person person = client.get(url, null, Person.class); //no queryParams

건배!


0

저지 레스트 클라이언트의 예 :
의존성 추가 :

         <!-- jersey -->
    <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-json</artifactId>
        <version>1.8</version>
    </dependency>
   <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-server</artifactId>
        <version>1.8</version>
    </dependency>

<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-client</artifactId>
    <version>1.8</version>
</dependency>

    <dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20090211</version>
</dependency>

ForGetMethod 및 두 개의 매개 변수 전달 :

          Client client = Client.create();
           WebResource webResource1 = client
                        .resource("http://localhost:10102/NewsTickerServices/AddGroup/"
                                + userN + "/" + groupName);

                ClientResponse response1 = webResource1.get(ClientResponse.class);
                System.out.println("responser is" + response1);

GetMethod는 하나의 매개 변수를 전달하고 목록의 응답 받기 :

       Client client = Client.create();

        WebResource webResource1 = client
                    .resource("http://localhost:10102/NewsTickerServices/GetAssignedUser/"+grpName);    
    //value changed
    String response1 = webResource1.type(MediaType.APPLICATION_JSON).get(String.class);

    List <String > Assignedlist =new ArrayList<String>();
     JSONArray jsonArr2 =new JSONArray(response1);
    for (int i =0;i<jsonArr2.length();i++){

        Assignedlist.add(jsonArr2.getString(i));    
    }

In It It List로 받아들이고 Json Array로 변환 한 다음 Json Array를 List로 변환하는 List를 반환합니다.

Post Request가 Json Object를 매개 변수로 전달하는 경우 :

   Client client = Client.create();
    WebResource webResource = client
            .resource("http://localhost:10102/NewsTickerServices/CreateJUser");
    // value added

    ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).post(ClientResponse.class,mapper.writeValueAsString(user));

    if (response.getStatus() == 500) {

        context.addMessage(null, new FacesMessage("User already exist "));
    }

0

나는 현재 https://github.com/kevinsawicki/http-request를 사용하고 있습니다. 나는 그들의 단순성과 예제가 표시되는 방식을 좋아하지만 대부분 읽을 때 팔렸습니다.

종속성은 무엇입니까?

없음 이 라이브러리의 목표는 내부 정적 클래스가있는 단일 클래스 클래스가되는 것입니다. 테스트 프로젝트에는 실제 HTTP 서버 구현에 대한 요청을 테스트하기 위해 Jetty가 필요합니다.

Java 1.6 프로젝트에서 몇 가지 문제를 해결했습니다. JSON을 객체로 디코딩하는 것에 관해서gson 은 무적입니다 :)


1
프로젝트는 2015 년 이후로 커밋되지 않은 것처럼 보입니다.
tkruse
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.