質問
JSR 311とその実装では、RESTを介してJavaオブジェクトを公開するための強力な標準があります。ただし、クライアント側では、Apache Axis for SOAPに匹敵するものが欠けているようです。Webサービスを隠し、データをJavaオブジェクトに透過的にマーシャリングします。
Java RESTfulクライアントをどのように作成しますか? HTTPConnectionと結果の手動解析を使用していますか?または、たとえばJerseyまたはApache CXR?
解決
これは古い質問(2008)であるため、当時よりも多くのオプションがあります:
- Apache CXF には3つの異なる RESTクライアントがありますオプション
- ジャージ (上記)。
- Spring には RestTemplate
- Commons HTTP Client 古いバージョン用に独自のビルドを行うJavaプロジェクト。
UPDATE 2014年頃:
-
Async-http-client ソナタイプ。 Ning Async-http-client 。
NIOサポートを提供するブロック上の新しい子供(正直なところ、これがサーバーのようにクライアントのパフォーマンスを本当に改善するとは思わない)。
- Apache HTTPコンポーネント(4.2)Fluentアダプター -古いCommons HTTP Client 3よりも優れており、独自のRESTクライアントを構築するのに使いやすい。 JSON for JSON解析サポートのようなものを使用する必要があり、 Jersey / JAX-RS Restクライアントと同様に、リソースURIを構築するHTTPコンポーネントURIBuilder 。 HTTPコンポーネントもNIOをサポートしていますが、RESTの短いリクエストの性質を考えると、BIOよりも優れたパフォーマンスが得られるとは思いません。
UPDATE 2016 :
- OkHttp -新しいHTTPプロトコル(SPDYおよびHTTP2)をサポートします。 Androidで動作します。残念ながら、それは本当のリアクターループベースの非同期オプションを提供しません(上記のNingおよびHTTPコンポーネントを参照)。ただし、より新しいHTTP2プロトコルを使用する場合、これは問題ではありません(接続カウントに問題があると仮定します)。
- レトロフィット -に似たインターフェーススタブに基づいてクライアントを自動作成します一部のJerseyおよびCXF拡張。 OkHttpを使用します。
- Apache HttpComponents 5はHTTP2をサポートするはずです
HTTP / RESTクライアントの選択に関する注意。フレームワークスタックがHTTPクライアントに使用しているもの、スレッド化の方法を確認し、理想的には同じクライアントを使用している場合はそれを使用します。つまり、Vert.xやPlayのようなものを使用している場合、そのバッキングクライアントを使用して、フレームワークが提供するバスまたはリアクターループに参加しようとするかもしれません...そうでない場合は、興味深いスレッドの問題に備えてください。
他のヒント
このスレッドで述べたように、 Jersey は、JAX-RSを実装し、RESTクライアントが付属しています。良いことは、JAX-RSを使用してRESTfulリソースを実装すると、JerseyクライアントはJAXB / XML / JSON / Atomなどのエンティティプロバイダーを再利用できるため、サーバー側で同じオブジェクトを再利用できることです。クライアント側の単体テストで使用します。
たとえば、こちらは、 Apache Camelプロジェクト(RESTfulリソースからJAXBオブジェクトエンドポイントを使用して)XMLペイロードを検索します。 resource(uri)メソッドはこの基本クラスは、JerseyクライアントAPIのみを使用します。
e.g。
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);
ところで、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は使いやすいですが、クラスパスに追加の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);
詳細については、次を参照してください:
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]");
完全なクライアント側機能を備えた Restlet も確認できます。 HttpURLConnectionまたはApache HTTPクライアント(コネクタとして活用できます)。
よろしく、 ジェローム・ルーベル
Rapa を試すことができます。同じことについてのフィードバックをお聞かせください。 また、問題や予想される機能を自由に記録してください。
最近 Retrofit スクエアのライブラリを試してみましたが、素晴らしいです。残りのAPIを呼び出すことができますとても簡単に。 注釈ベースの構成により、ボイラープレートのコーディングの多くを取り除くことができます。
さらに2つのオプションを指摘したいと思います:
- Restfulie は、VRaptor Webフレームワークに基づいており、サーバー側とクライアント側の両方の実装が非常に優れています。ハイパーメディアのサポート。
- RESTEasy には JAX-RSプロキシベースのクライアントの実装。
Apache HTTPClientを使用して、すべてのHTTPサイドを処理します。
XMLをオブジェクトモデルに解析するXMLコンテンツ用のXML SAXパーサーを作成します。 Axis2もXMLを公開していると思います-&gt;モデルメソッド(1軸はこの部分を煩わしく隠した)。 XMLジェネレーターは簡単です。
コーディングにそれほど時間はかからず、非常に効率的です。
OkHttpは、Retrofitと組み合わせても軽量で強力です。これは、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);
}
jcabi-http から JdkRequest
を試してください(私は開発者です)。仕組みは次のとおりです。
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
誰も言及していないので、ここにもう1つあります: Feign は Spring Cloud 。
HTTPクライアントの作成と再作成は簡単ですが。ただし、自動生成されたクライアントを使用する場合は、WADLを使用してコードを記述および生成できます。
RestDescribe を使用してWSDLを生成およびコンパイルできます。クライアントを生成できます。これを使用して、php、ruby、python、java、およびC#で。それはきれいなコードを生成し、コード生成後にそれを少し微調整する必要がある良い変更があります。ツールこちら。
wintermuteで言及されている WADLツールは、興味深く有用です。
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());
最後の1つの例
RestClient client = RestClient.builder().build();
String url = ...
Person person = client.get(url, null, Person.class); //no queryParams
乾杯!
ジャージレストクライアントの例:
依存関係の追加:
<!-- 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および2つのパラメーターを渡す:
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);
1つのパラメーターを渡し、リストの応答を取得する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 Above Itは、リストとして受け入れているリストを返し、それをJson配列に変換してから、Json配列をリストに変換します。
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 "));
}