Làm thế nào để bạn tạo một máy khách REST cho Java? [đóng cửa]


247

Với JSR 311 và các triển khai của nó, chúng tôi có một tiêu chuẩn mạnh mẽ để phơi bày các đối tượng Java thông qua REST. Tuy nhiên, về phía máy khách dường như thiếu thứ gì đó có thể so sánh với Trục Apache cho SOAP - thứ gì đó che giấu dịch vụ web và sắp xếp lại dữ liệu trong suốt cho các đối tượng Java.

Làm thế nào để bạn tạo các máy khách Java RESTful? Sử dụng HTTPConnection và phân tích cú pháp thủ công của kết quả? Hoặc khách hàng chuyên biệt cho ví dụ Jersey hoặc Apache CXR?


Chỉ tìm thấy Apache Wink trong Vườn ươm Apache. Có thể là một dự án thú vị để tạo máy chủ REST và máy khách.
Yaba


Hãy xem [Nghỉ ngơi] ( code.google.com/p/resting ). Nó hứa sẽ gọi các dịch vụ REST và tạo danh sách các đối tượng từ phản hồi XML / JSON / YAML trong một bước.
neel

Nghỉ ngơi có vấn đề với các yêu cầu POST.
RyanBrady

2
Bạn có thể làm điều đó một cách rất đơn giản với resteasy (bởi Jboss). Tôi đã viết một bài đăng trên blog về cách phát triển ứng dụng khách Java REST nếu bạn muốn có một hướng dẫn bắt đầu. Dù sao, có hàng trăm lựa chọn thay thế trong Java.
Guido

Câu trả lời:


204

Đây là một câu hỏi cũ (2008) vì vậy có nhiều lựa chọn hơn bây giờ so với lúc đó:

CẬP NHẬT (dự án vẫn hoạt động vào năm 2020):

  • Bộ điều hợp thành phần HTTP Apache (4.2) - Bộ thay thế cơ bản cho JDK, được sử dụng bởi một số ứng cử viên khác trong danh sách này. Tốt hơn so với Commons HTTP Client 3 cũ và dễ sử dụng hơn để xây dựng ứng dụng khách REST của riêng bạn. Bạn sẽ phải sử dụng một cái gì đó như Jackson để hỗ trợ phân tích cú pháp JSON và bạn có thể sử dụng các thành phần HTTP URIBuilder để xây dựng các URI tài nguyên tương tự như máy khách Rest / Jersey / JAX-RS. Các thành phần HTTP cũng hỗ trợ NIO nhưng tôi nghi ngờ bạn sẽ có hiệu suất tốt hơn BIO do yêu cầu ngắn của REST. Apache HTTPComponents 5 có hỗ trợ HTTP / 2.
  • OkHttp - Thay thế cơ bản cho JDK, tương tự như các thành phần http, được sử dụng bởi một số ứng cử viên khác trong danh sách này. Hỗ trợ các giao thức HTTP mới hơn (SPDY và ​​HTTP2). Hoạt động trên Android. Thật không may, nó không cung cấp tùy chọn async dựa trên vòng lặp lò phản ứng thực sự (xem các thành phần Ning và HTTP ở trên). Tuy nhiên, nếu bạn sử dụng giao thức HTTP2 mới hơn thì đây không phải là vấn đề (giả sử số lượng kết nối là có vấn đề).
  • Ning Async-http-client - cung cấp hỗ trợ NIO. Trước đây được gọi là Async-http-client của Sonatype .
  • Trình bao bọc giả cho các máy khách http cấp thấp hơn (okhttp, apache httpcomponents). Tự động tạo ứng dụng khách dựa trên sơ khai giao diện tương tự như một số tiện ích mở rộng Jersey và CXF. Hội nhập mùa xuân mạnh mẽ.
  • Trang bị thêm - trình bao bọc cho các máy khách http cấp thấp hơn (okhttp). Tự động tạo ứng dụng khách dựa trên sơ khai giao diện tương tự như một số tiện ích mở rộng Jersey và CXF.
  • Volley Wrapper cho jdk http client, bởi google
  • trình bao bọc google-http cho jdk http client hoặc apache httpcomponents, bởi google
  • Trình bao bọc đơn nhất cho jdk http client, bởi kong
  • Resteasy Trình bao bọc JakartaEE cho jdk http client, bởi jboss, một phần của khung jboss
  • jcabi-http bao bọc cho httpcomponents apache, một phần của bộ sưu tập jcabi
  • Restlet Wrapper cho apache httpcomponents, một phần của khung restlet
  • bọc yên tâm với các xác nhận để kiểm tra dễ dàng

Một cảnh báo về việc chọn khách hàng HTTP / REST. Đảm bảo kiểm tra ngăn xếp khung công tác của bạn đang sử dụng cho máy khách HTTP, cách phân luồng và lý tưởng sử dụng cùng một máy khách nếu nó cung cấp một máy khách. Đó là nếu bạn sử dụng một cái gì đó như Vert.x hoặc Play, bạn có thể muốn thử sử dụng ứng dụng khách hỗ trợ của nó để tham gia vào bất kỳ vòng lặp xe buýt hoặc lò phản ứng nào mà khung cung cấp ... nếu không thì hãy chuẩn bị cho các vấn đề luồng thú vị.


1
Thật không may, máy khách Jersey không hỗ trợ phương thức PATCH nếu được sử dụng với JDK <8
botchniaque

3
Unirest rất dễ sử dụng nhưng thiết kế tĩnh của nó làm cho nó không sử dụng được trong môi trường máy chủ và chia sẻ.
bekce

9
Về unirest bình luận, tôi muốn nói thêm rằng nó hiện (cuối năm 2016) trông như nếu dự án này không còn được duy trì. Thậm chí có một vấn đề mở yêu cầu một người bảo trì mới.
wegenmic

4
Đối với những người thích Unirest , tôi đã có một nhánh của nó hiện đang được duy trì / cập nhật tích cực.
Josh

3
sẽ rất tuyệt nếu biến câu trả lời thành wiki cộng đồng
tkruse

71

Như tôi đã đề cập trong chủ đề này, tôi có xu hướng sử dụng Jersey thực hiện JAX-RS và đi kèm với một ứng dụng REST đẹp. Điều tuyệt vời là nếu bạn triển khai các tài nguyên RESTful của mình bằng JAX-RS thì máy khách Jersey có thể sử dụng lại các nhà cung cấp thực thể như cho JAXB / XML / JSON / Atom, v.v. - để bạn có thể sử dụng lại các đối tượng tương tự ở phía máy chủ như bạn sử dụng trong bài kiểm tra đơn vị phía khách hàng.

Ví dụ ở đây là một trường hợp thử nghiệm đơn vị từ dự án Lạc đà Apache tìm kiếm các tải trọng XML từ tài nguyên RESTful (sử dụng Điểm cuối đối tượng JAXB). Phương thức tài nguyên (uri) được định nghĩa trong lớp cơ sở này chỉ sử dụng API máy khách Jersey.

ví dụ

    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 Tôi hy vọng rằng phiên bản tương lai của JAX-RS sẽ thêm API phía máy khách đẹp mắt dọc theo dòng của Jersey ở Jersey


Có một phương pháp mà chúng ta có thể đề cập đến danh sách máy chủ dịch vụ REST trong ClientResource, trong trường hợp máy chủ không hoạt động, hãy thử máy chủ tiếp theo?
Njax3SmmM2x2a0Zf7Hpd

1
Chỉ là một bản cập nhật, nhưng để giải quyết bình luận của James '' BTW ', phiên bản mới của JAX-RS 2.0 sẽ có API phía máy khách: infoq.com/presentations/Java-REST
Nick Klauer

64

Bạn có thể sử dụng API Java SE tiêu chuẩn:

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

Hoặc bạn có thể sử dụng API máy khách REST được cung cấp bởi các triển khai JAX-RS như Jersey. Các API này dễ sử dụng hơn, nhưng yêu cầu các lọ bổ sung trên đường dẫn lớp của bạn.

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

Để biết thêm thông tin xem:


15
13 dòng cho một cuộc gọi nghỉ ngơi đơn giản, vào năm 2018 , nghe có vẻ quá nhiều ...
Clint Eastwood

1
Khi bạn thêm xử lý lỗi và các tùy chọn, nó không thực sự khác biệt đáng kể. Nếu cách tiếp cận SE có vẻ dài, bạn luôn có thể gói nó trong một lớp ...:> Sau hai ngày gỡ lỗi thư viện JAX-RS, tôi thực sự ổn với 5 dòng mã bổ sung để tránh cơn ác mộng SPI.
tekHedd

2
@ClintEastwood bài đăng này đã được viết vào năm 2010
0ddlyoko

12

Nếu bạn chỉ muốn gọi một dịch vụ REST và phân tích phản hồi, bạn có thể dùng thử 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]");

9

Bạn cũng có thể kiểm tra Restlet có đầy đủ các khả năng phía máy khách, nhiều định hướng REST hơn mà các thư viện cấp thấp hơn như HTTPURLConnection hoặc Apache HTTP Client (chúng ta có thể tận dụng làm trình kết nối).

Trân trọng, Jerome Louvel


2
Kể từ 2019-10-24, liên kết được cung cấp trả về: 'Nền tảng Restlet đã hết tuổi thọ.'
Hans Deragon

6

Bạn có thể thử Rapa . Cho chúng tôi biết phản hồi của bạn về cùng. Và cảm thấy tự do để đăng nhập các vấn đề hoặc các tính năng dự kiến.


1
Rapa có một giao diện thực sự tốt đẹp và một vài phụ thuộc. Một thay thế tốt cho RestSharp trong thế giới .NET.
chiều

dự án có vẻ đã chết
tkruse



5

Gần đây tôi đã thử Thư viện trang bị thêm từ hình vuông, thật tuyệt và bạn có thể gọi API còn lại của mình rất dễ dàng. Cấu hình dựa trên chú thích cho phép chúng ta loại bỏ rất nhiều mã hóa tấm nồi hơi.


4

Tôi sử dụng Apache HTTPClient để xử lý tất cả các khía cạnh HTTP của mọi thứ.

Tôi viết các trình phân tích cú pháp SAX XML cho nội dung XML phân tích cú pháp XML vào mô hình đối tượng của bạn. Tôi tin rằng Axis2 cũng trưng ra các phương thức XML -> Model (Trục 1 ẩn phần này, thật khó chịu). Các trình tạo XML rất đơn giản.

Theo tôi, nó không mất nhiều thời gian để viết mã và khá hiệu quả.


4
Theo tôi đây là cách tồi tệ nhất để làm REST. Xử lý tuần tự hóa thủ công trong Java là một sự lãng phí thời gian khi bạn có quá nhiều tùy chọn như JAXB và Jackson. Ngay cả việc tải toàn bộ tài liệu và sử dụng XPath cũng chậm hơn SAX và không có gì so với việc lấy XML (tốc độ mạng).
Adam Gent

1
Tôi cũng đồng ý, và tôi đã viết bình luận ban đầu. Hồi đó tôi có một mong muốn kiểm soát việc giải trừ, nhưng ngày nay tôi sẽ sử dụng Jackson và các lớp mô hình chú thích.
JeeBee

4

OkHttp rất nhẹ và mạnh mẽ khi kết hợp với Retrofit. Điều này hoạt động tốt cho việc sử dụng Java nói chung cũng như trên Android.

OkHttp : http://sapes.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();
}

Trang bị thêm : http://sapes.github.io/retrofit/

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


2

Mặc dù đơn giản để tạo một máy khách HTTP và thực hiện lại. Nhưng nếu bạn muốn sử dụng một số máy khách được tạo tự động, Bạn có thể sử dụng WADL để mô tả và tạo mã.

Bạn có thể sử dụng RestDescribe để tạo và biên dịch WSDL, bạn có thể tạo các máy khách bằng php, ruby, python, java và C # bằng cách này. Nó tạo mã sạch và có một thay đổi tốt là bạn phải điều chỉnh nó một chút sau khi tạo mã, bạn có thể tìm thấy tài liệu tốt và những suy nghĩ tiềm ẩn đằng sau công cụ ở đây .

Có một vài công cụ WADL thú vị và hữu ích được đề cập trên wintermute.



0

Hãy thử nhìn vào http-rest-client

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

Đây là một ví dụ đơn giản:

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

Thư viện sẽ chăm sóc tuần tự json và ràng buộc cho bạn.

Đây là một ví dụ khác,

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

Và một ví dụ cuối cùng,

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

Chúc mừng!


0

Ví dụ về jersey Phần còn lại của khách hàng:
Thêm phụ thuộc:

         <!-- 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 và truyền hai tham số:

          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 chuyển một tham số và nhận được danh sách:

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

Trong Ở trên, nó trả về một danh sách mà chúng ta đang chấp nhận như một danh sách và sau đó chuyển đổi nó thành Json Array và sau đó là Json Array thành List.

Nếu Post Request vượt qua Json Object làm tham số:

   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

Tôi hiện đang sử dụng https://github.com/kevinsawicki/http-request Tôi thích sự đơn giản của chúng và cách các ví dụ được hiển thị, nhưng chủ yếu tôi đã được bán khi tôi đọc:

Các phụ thuộc là gì?

Không ai. Mục tiêu của thư viện này là trở thành một lớp lớp duy nhất với một số lớp tĩnh bên trong. Dự án thử nghiệm không yêu cầu Jetty để kiểm tra các yêu cầu đối với việc triển khai máy chủ HTTP thực tế.

trong đó sắp xếp một số vấn đề trên một dự án java 1.6. Đối với việc giải mã json thành các đối tượng gson chỉ là bất khả chiến bại :)


1
dự án có vẻ đã chết, không có cam kết kể từ năm 2015.
tkruse
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.