문제

JSR 311과 그 구현을 통해 우리는 REST를 통해 Java 객체를 노출시키는 강력한 표준을 가지고 있습니다. 그러나 클라이언트 측에는 비누의 아파치 축과 비슷한 것이없는 것 같습니다. 웹 서비스를 숨기고 데이터를 자바 객체로 투명하게 다시 마샬링하는 것입니다.

Java Restful Clients를 어떻게 만들 수 있습니까? 결과의 httpconnection 및 수동 구문 분석 사용? 또는 예를 들어 저지 또는 아파치 CXR을위한 전문 고객?

도움이 되었습니까?

해결책

이것은 오래된 질문 (2008)이므로 다음과 같은 것보다 더 많은 옵션이 있습니다.

업데이트 2014 년경 :

NIO 지원을 제공하는 블록의 새로운 어린이 (진실로 저는 이것이 서버와 같은 클라이언트의 성능을 향상시키는 것은 아니라고 생각합니다).

업데이트 2016:

  • OKHTTP - 새로운 HTTP 프로토콜 (SPDY 및 HTTP2)을 지원합니다. 안드로이드에서 작동합니다. 불행히도 실제 반응기 루프 기반 비동기 옵션을 제공하지 않습니다 (위의 Ning 및 HTTP 구성 요소 참조). 그러나 최신 HTTP2 프로토콜을 사용하는 경우 문제가 덜 문제가되지 않습니다 (연결 수에 문제가 있다고 가정).
  • 개조 - 일부 저지 및 CXF 확장과 유사한 인터페이스 스텁을 기반으로 클라이언트를 자동으로 만듭니다. OKHTTP를 사용합니다.
  • Apache HttpComponents 5는 아마도 HTTP2 지원을받을 것입니다

HTTP/REST 클라이언트 선택에 대한 경고. HTTP 클라이언트에 프레임 워크 스택이 사용하는 내용, 스레딩 방법을 확인하고 동일한 클라이언트를 제공하는 경우 이상적으로 사용하는 방법을 확인하십시오. 즉, Vert.x 또는 Play와 같은 것을 사용하는 경우 후원 클라이언트를 사용하여 프레임 워크가 제공하는 버스 또는 원자로 루프에 참여하려고 시도 할 수 있습니다. 그렇지 않으면 흥미로운 스레딩 문제에 대비해야합니다.

다른 팁

내가 언급했듯이 이 스레드 나는 사용하는 경향이있다 저지 Jax-R을 구현하고 멋진 휴식 클라이언트가 제공됩니다. 좋은 점은 JAX -RS를 사용하여 편안한 리소스를 구현하는 경우 Jersey Client가 JAXB/XML/JSON/ATOM 등과 같은 엔티티 제공 업체를 재사용 할 수 있다는 것입니다. 따라서 서버 측에서 동일한 개체를 재사용 할 수 있습니다. 클라이언트 측 유닛 테스트에 사용하십시오.

예를 들어 다음은 단위 테스트 케이스입니다 ~로부터 아파치 낙타 프로젝트 편안한 리소스에서 XML 페이로드를 찾습니다 (JAXB 객체 엔드 포인트 사용). 리소스 (URI) 메소드는 정의됩니다 이 기본 클래스 Jersey Client 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가 저지의 라인을 따라 멋진 클라이언트 측 API를 추가하기를 바랍니다.

표준 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는 사용하기 쉽지만 클래스 경로에 추가 항아리가 필요합니다.

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

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

휴식 서비스를 호출하고 응답을 구문 분석하려면 시도해 볼 수 있습니다. 안심하십시오

// 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]");

당신은 또한 확인할 수 있습니다 restlet 전체 클라이언트 측 기능을 갖추고 있으며 HTTPURLConnection 또는 Apache HTTP 클라이언트 (커넥터로 활용할 수 있음)와 같은 하위 레벨 라이브러리가 더 많이 사용됩니다.

안부, 제롬 라우 벨

당신은 시도 할 수 있습니다 라파. 그에 대한 귀하의 의견을 알려주십시오. 문제 또는 예상 기능을 자유롭게 기록하십시오.

나는 최근에 시도했다 개조 Square의 라이브러리, 훌륭하며 REST API를 매우 쉽게 호출 할 수 있습니다. 주석 기반 구성을 통해 보일러 플레이트 코딩을 많이 제거 할 수 있습니다.

두 가지 옵션을 추가로 지적하고 싶습니다.

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

XML을 객체 모델에 구문 분석하는 XML 컨텐츠에 대해 XML Sax 파서를 작성합니다. Axis2는 또한 XML-> 모델 방법을 노출한다고 생각합니다 (Axis 1 은이 부분을 짜증나게 숨겼습니다). XML 생성기는 사소한 간단합니다.

제 생각에는 코드에 오래 걸리지 않으며 매우 효율적입니다.

OKHTTP는 리트로이트와 결합 할 때 가볍고 강력합니다. 이것은 Android뿐만 아니라 일반적인 Java 사용에 적합합니다.

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);
}

노력하다 JdkRequest ~에서 JCabi-HTTP (저는 개발자입니다). 이것이 작동하는 방식입니다.

String body = new JdkRequest("http://www.google.com")
  .header("User-Agent", "it's me")
  .fetch()
  .body()

자세한 내용은이 블로그 게시물을 확인하십시오. http://www.yegor256.com/2014/04/11/jcabi-http-intro.html

아무도 언급되지 않았기 때문에 여기에 또 다른 것이 있습니다. feign, 이에 의해 사용됩니다 스프링 클라우드.

잠시 동안, 나는 사용하고 있습니다 쉬운:

JSONResource jsonResource = new Resty().json(uri);

몇 가지 예를 찾을 수 있습니다 여기.

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

당신이 사용할 수있는 RestDescribe WSDL을 생성하고 컴파일하려면 PHP, Ruby, Python, Java 및 C#에서 클라이언트를 생성 할 수 있습니다. 그것은 깨끗한 코드를 생성하고 코드 생성 후 약간 조정해야 할 좋은 변화가 있습니다. 도구 뒤에 좋은 문서와 기본 생각을 찾을 수 있습니다. 여기.

흥미롭고 유용한 사람은 거의 없습니다 WADL 도구 Wintermute에 언급되었습니다.

Java 인터페이스를 원격 JSON REST 서비스에 매핑하는 라이브러리를 썼습니다.

https://github.com/ggeorgovassilis/spring-rest-invoker

public interface BookService {
   @RequestMapping("/volumes")
   QueryResult findBooksByTitle(@RequestParam("q") String q);

   @RequestMapping("/volumes/{id}")
   Item findBookById(@PathVariable("id") String id);
}

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

건배!

Jersey Rest Client의 예 :
종속성 추가 :

         <!-- 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>

잊어 버리고 두 매개 변수를 전달합니다.

          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);

하나의 매개 변수를 전달하고 목록의 Respone Get Method Get Method :

       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));    
    }

위에서 목록으로 수락 한 다음 JSON 배열로 변환 한 다음 JSON 배열로 목록으로 변환하는 목록을 반환합니다.

Post 요청이 JSON 객체를 매개 변수로 전달하는 경우 :

   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 "));
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top