Upload
ikeyat
View
5.542
Download
0
Embed Size (px)
Citation preview
Beginning Java EE 6 勉強会(7)-RESTful Webサービス(JAX-RS)-
担当者:ikeyat
2012/07/04
アンケート
• REST知ってますか?
– 知らない
– 聞いたことがある
– 使ったことがある
– 人に説明することができる
2
INDEX
● REST
● JAX-RS
3
REST
RESTとは
● Webサービスのアーキテクチャスタイルの一つ– 仕様や実装ではない
– もちろんプロトコルでもない(SOAPはプロトコル)
● 二つの意味で使用されている– HTTPを用いた簡易的なRPC
– Roy Fieldingが提唱するWebサービスアーキテクチャスタイル
5
RESTとは
● HTTPを用いた簡易的なRPC– クライアントはサービスを呼び出すために、手続きに対しHTTPリク
エストする(例:検索、追加)
– URIに動詞が含まれることが多い(例:deleteXxx)
– GETやPOSTが用いられることが多い
– 例:Amazon API
6
GEThttp://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&AWSAccessKeyId=[AWS アクセスキー ID]&AssociateTag=[Associate Tag]&Operation=CartClear&CartId=[Cart ID]&HMAC=[URL-encoded HMAC]
RESTとは
● Roy Fieldingが提唱するWebサービスアーキテクチャスタイル– クライアントはサービスを呼び出すために、リソースに対しHTTPリ
クエストする(例:本、カテゴリ)
– URIは名詞である(例:book、books、categories)
– リソースに対する手続きの種類はCRUDで、HTTPのメソッドで指定する(GET/POST/PUT/DELETE)
– 本書ではこちらに従う
7
DELETEhttp://www.apress.com/books/1023
RESTとは
● Roy Fielding式RESTを学ぶ上で必要な知識=Web– リソースとURI
– 表現
– HTTP
● メソッド● コンテンツ・ネゴシエーション● ステータスコード● キャッシュ
8
Web● リソース
– 参照もしくは操作の対象となるサーバ上のオブジェクト。
– 例:
● Apress社のJavaに関する書籍のリスト
● 書籍『The Definitive Guide to Grails』
● Ola Biniの経歴
● URI– Web上のリソースを特定する識別子。内容が分かるような文字列にするとよい。
– 例:
● http://www.apress.com/book/catalog
● http://www.weather.com/weather/2008?location=Paris
● http://www.flickr.com/explore/interesting/2009/01/01
9
Web
● 表現– リソースをクライアントで扱う際の形式。
● 例:テキスト、HTML、XML、JSON、JPG画像、PDF
– 必要に応じて、一つのリソースに対し複数の表現を用意することもある。
● 例:書籍一覧のHTML、書籍一覧CSV
– クライアントが表現を選択する方法
● URIを拡張子などで分ける方法
– http://xxxxxx/xxx/books.html– http://xxxxxx/xxx/books.csv
● コンテンツ・ネゴシエーションを使用する方法(後述)
10
Web
● HTTP
11
GET /book/catalog?category=32 HTTP/1.1User-Agent: xxxxxxHost: www.apress.comAccept: */*
<GETの場合は空>
HTTP/1.1 200 OKDate: Mon, 23 Feb 2009 07:28:09 GMTServer: Apache/2.0.63 (Unix) PHP/5.2.6Set-Cookie: XX=YYYYYYExpires: Thu, 19 Nov 1981 08:52:00 GMTCache-Control: no-store, no-cache, …Pragma: no-cacheTransfer-Encoding: chunkedContent-Type: text/html
<!DOCTYPE HTML><html> <head> <title> <body>...
リクエスト例 レスポンス例
Web
● HTTP
12
GET /book/catalog?category=32 HTTP/1.1User-Agent: xxxxxxHost: www.apress.comAccept: */*
<GETの場合は空>
HTTP/1.1 200 OKDate: Mon, 23 Feb 2009 07:28:09 GMTServer: Apache/2.0.63 (Unix) PHP/5.2.6Set-Cookie: XX=YYYYYYExpires: Thu, 19 Nov 1981 08:52:00 GMTCache-Control: no-store, no-cache, …Pragma: no-cacheTransfer-Encoding: chunkedContent-Type: text/html
<!DOCTYPE HTML><html> <head> <title> <body>...
リクエスト例 レスポンス例メソッドステータスコード
コンテンツネゴシエーション
Web
● メソッド– リソースに対する操作の種類。主にGET/POST/PUT/DELETEを
用いる。
13
メソッド CRUD リソース変化 HTTP本体
GET R なし なし リソースの返却を要求する
POST C あり あり リソースの新規作成を要求する
PUT U あり あり リソースの更新を要求する
DELETE D あり なし リソースの削除を要求する
他にもHEAD/TRACE/OPTIONS/CONNECTがあります
Web
● コンテンツ・ネゴシエーション– 使用可能な「表現」が複数存在する時に、最適な表現を選択する
プロセス。
– クライアントはHTTPリクエストヘッダで要求する表現を指定できる。サーバはこれに応じた表現を返却するのが望ましい。
● Accept:コンテンツ・タイプ● Accept-Charset:文字コード● Accept-Encoding:エンコード● Accept-Language:言語
14
Web
● コンテンツ・タイプ– text/html
– text/plain
– image/gif, image/jpeg, image/png
– text/xml, application/xml
– application/json
15
Web
● ステータスコード– 1xx:情報を示す。リクエストを受信しプロセスを継続。
– 2xx:処理の精巧を示す。リクエストを正しく受信し、理解。
● 200 OK
– 3xx:リダイレクトを示す。リクエストを完了するために更なる操作が必要。
● 301 Moved Permanently
– 4xx:クライアントエラーを示す。リクエストに不適切な構文が含まれる、もしくはリクエストを満たすことができない。
● 404 Not Found
– 5xx:サーバーエラーを示す。サーバーは有効なリクエストに対し実行できない。
● 500 Internal Server Error
16
RESTとは
● (話戻って)RESTアーキテクチャスタイルとは– 統一インタフェース
● HTTP(GET/POST/PUT/DELETEおよびステータスコード)に準拠する(=URIさえ分かれば利用できる)
– アドレス指定
● アプリケーションが扱う情報をアドレス(URI)で指定できるようにする
– 連結性
● 関連するリソース同士をURIでリンクさせる
● 例:CDリソースの中にアーティスト情報がある場合、その名前だけでなくURIも含める
– ステートレス
● リソースの状態はサーバで管理
● アプリケーションの状態はクライアントで管理
17
RESTとは
● 連結性の例
18
<cd> <title>Ella and Louis</title> <year ref=”http://music.com/year/1956”>1956</year> <artist ref=”http://music.com/artists/123”>Ella Fitzgerald</artist> <artist ref=”http://music.com/artists/456”>Louis Armstrong</artist> <link rel=”self” type=”text/json” href=”http://music.com/album/789” /> <link rel=”self” type=”text/xml” href=”http://music.com/album/789” /> <link rel=”http://music.com/album/comments” type=”text/xml” href=”http://music.com/album/789/comments” /></cd>
RESTとは
● メリット– クライアントとサービスの結びつきが弱い
– スケーラビリティ性
● ステートレス● HTTPキャッシュ● コンパクトな電文(JSON)
– 1HTTPリクエストで簡潔(SOAPはWSDL取るので2リクエスト)
● デメリット– 透過的に扱えない
– プロトコルがHTTPに限定
– SOAPにあるようなWS-*(WS-Security,etc...)標準が無い
19
JAX-RS
JAX-RS
● JAX-RS1.1– JavaでRESTfulなWebサービスを開発するためのAPI仕様
– JavaEE6に導入
– アノテーションを利用
● ローカルBeanインタフェースもしくはインタフェースなしBeanに適用可能
– サーバサイドのみ
– 永続性マネージャ、データソース、EJBなどのDI可能
● 実装– Jersey (Sun) : GlassFish3に搭載
– Apache CXF
– RESTeasy (JBoss)
21
JAX-RS
● (参考)JAX-RS2.0(JavaEE7)– クライアントAPI
– FiltersとHandlers
– BeanValidationを用いたパラメータの検証機能
– 非同期処理(クライアント側でFutureオブジェクトを返す)
– 優れた接続ネゴシエーション
22https://blogs.oracle.com/arungupta/entry/jax_rs_2_0_earlyより
Java EE 6の全体像
23
http://www.slideshare.net/takakiyo/jjuc-ccc-2010-spring より拝借
JAX-RS
● JAX-RSモデル– リソースを表すPOJOクラスに@javax.ws.rs.Pathアノテーションを付加。
– リソースクラスのメソッドに@GET/@POST/@PUT/@DELETEアノテーションを付加し、各操作の処理を記述する。
– EJB機能を利用する場合はステートレスセッションBeanに@Pathを付加。
24
@Path(“/book”)public class BookResource { @GET @Produces(“text/plain”) public String getBookTitle() { return “H2G2”; }}
www.apress.com
GET http://www.apress.com/book
200 OKH2G2
JAX-RSモデル
● URI定義– @Pathでコンテキストルートからの相対パスを指定。
– クラスに付加した@PathのURIはルートリソース
● 例:/items
– ルートリソースのメソッドに@Pathを付加し、小リソースの操作を記述することも可能。
● 例:/items/books
– URI構文に変数を埋め込むことも可能。@PathParamで参照。
● 例:/items/{itemid}
25
@Path(“/items”)public class ItemResource { @GET public List<Item> get...() {...}
@GET @Path(“/{itemid}”) public Item get...( @PathParam(“itemid”) String itemid) {...}}
GET /items
GET /items/1234
JAX-RSモデル
● パラメータの抽出
26
アノテーション 取得元 説明 例
@PathParam URI @Pathで指定したURIテンプレートパラメータ
@PathParam(“itemId”)
@QueryParam URI URIクエリパラメータ(?以降のxxx=yyy)
@QueryParam(“zip”)
@MatrixParam URI URIの;で区切られたパラメータ(.../books;author=hoge)
@MatrixParam(“author”)
@CookieParam Cookie Cookieの値 @CookieParam(“sessionid”)
@HeaderParam HTTPヘッダ
リクエストHTTPヘッダの値 @HeaderParam(“Content-Type”)
@FormParam リクエスト本文
HTMLフォームからのパラメータ @FormParam(“password”)
@DefaultValue(“デフォルト値”)でデフォルト値の設定が可能
JAX-RSモデル
● コンテンツタイプの使用と生成– リクエストのコンテンツタイプに応じて呼び出すメソッドを振り分け
る→@Consumes
– リクエストのAcceptに応じて呼び出すメソッドを振り分ける→@Produces
27
@Path(“/items”)@Produces(MediaType.TEXT_PLAIN)public class CustomerResource { @GET public String getAsPlainText() {...}
@GET @Produces(MediaType.TEXT_HTML) public String getAsHtml() {...}
@GET @Produces(MediaType.Application_JSON) public List<Customer> getAsJson() {…}
@PUT @Consumes(MediaType.Application_XML) public Response createCustomer(InputStream is) {...}
}
Accept: text/plain
Content-Type: application/xml
Accept: text/html
Accept: application/json
JAX-RSモデル
● エンティティプロバイダ– HTTP本体(JSONやXML等)をJavaオブジェクトに変換、もしくはその逆を行うマッピングサービス。
– デフォルトでXMLやJSON用(JAXBElement)のプロバイダは用意されているので、通常は自作する必要はない。(JAXB/BadgerFishアダプタ)
28
@Provider@Consumes(MediaType.APPLICATION_XML)public class CustomerReader implements MessageBodyReader<Customer> { @Override public boolean isReadable(...) {…}
@Override public Customer readFrom(..., InputStream inputStream) {…}}
@Provider@Produces(MediaType.TEXT_PLAIN)public class CustomerWriter implements MessageBodyWriter<Customer> { @Override public boolean isWritable(...) {…}
@Override public void writeTo(Customer customer, ..., OutputStream outputStream) {…}}
JAX-RSモデル
● エンティティプロバイダ(続き)
29
@Path(“/customers”)public class CustomerResource { @GET public List<Customer> get...() {...}
@GET @Path(“/{customerid}”) public Customer get...( @PathParam(“customerid”) String customerId, @QueryParam(“zip”) String zip) {…}
@POST public Response create...( @QueryParam(“zip”) String zip, Customer customer) {…}
@PUT public Response update...( JAXBElement<Customer>) {...}
}
CustomerをXMLにwriteToするMessageBodyWriter
GETAccept: XML
CustomerをXMLからreadFromするMessageBodyReader
POSTAccept: XML+XML
(デフォルトの)XML出力MessageBodyWriter
XML
XML
JAX-RSモデル
● HTTPメソッド– publicメソッドに@GET/@POST/@PUT/@DELETEを付加すると
リソースメソッドとなる。
– リソースメソッドはvoid、ResponseもしくはJava型を返却。Java型の場合はエンティティプロバイダによってXMLやJSONに変換される。
30
@Path(“/customers”)Public class CustomerResource { @GET Public List<Customer> getListOfCustomers() {…}
@POST @Consumes(MediaType.APPLICATION_XML) public Response createCustomer(JAXBElement<Customer> element) {…}
@PUT @Path(“/{customerid}”) @Consumes(MediaType.APPLICATION_XML) public Response updateCustomer(@PathParam(“customerid”) String customerId, JAXBElement<Customer> element) {…}
@DELETE @Path(“/{customerid}”) public void deleteCustomer(@PathParam(“customerid”) String customerId) {…}}
JAX-RSモデル
● コンテキスト情報– @Contextにより各種情報(下記)を属性もしくはメソッド引数にイ
ンジェクションできる。
31
コンテキスト情報 属性 引数 説明
HttpHeaders ○ リクエストHTTPヘッダの各種値の取得httpHeaders.getAcceptableLanguages()// Accept-Language値
UriInfo ○ ○ リソースのURI情報uriInfo.getAbsolutePathBuilder()// 自リソースの絶対パスURIビルダー
Request ○ HTTPメソッドの種類、キャッシュ関連情報request.getMethod()// HTTPメソッド
SecurityContext ○ ○ セキュリティ関連情報の取得secureContext.isSecure()// HTTPSか否か
Providers ○ ○ エンティティプロバイダや例外マッピングプロバイダの取得providers.getMessageBodyWriter(...)// マッチするエンティティプロバイダ(Writer)の取得
JAX-RSモデル
● Response– メタ情報をクライアントに返却したい場合にbuildして返却する。
● ステータスコード(デフォルトだと200 OK)
– POST/PUTの正常時に201 Createdを返却するよう変更– エラーコード返却するよう変更(後述)
● Location(URI)
– POST/PUTの正常時に作成・修正リソースのURI● レスポンスHTTP本体
32
@POST public Response createNewBook(JAXBElement<Book> bookJaxb) { ... URI bookUri = uriInfo.getAbsolutePathBuilder().path( Book.getId().toString()).build();
// 返却メタ情報:ステータスコード201 Created、かつLocation=生成リソースのURI return Response.created(bookUri).build();}
JAX-RSモデル
● 例外処理– エラーステータスコードを充てたResponseを引数にしてWebApplicatio
nExceptionをスロー
– 例外マッピングプロバイダを使用れば、任意の非チェック例外をWebApplicationExceptionにチェインできる。
– いずれにも該当しないの非チェック例外はServletまでスローされつづけ、ServletコンテナがInternalServerError500を返却する。
33
// HTTP本体にメッセージを付けてステータスコード400を返却throw new WebApplicationException( Response.status(400).entity(“Id must be a positive integer!”).build());
// 404 NotFoundthrow new WebApplicationException(Response.Status.NOT_FOUND);
@ProviderPublic class EntityNotFoundMapper implements ExceptionMapper<javax.persistence.EntityNotFoundException> { Public Response toResponse(EntityNotFoundException ex) { return Response.status(404).entity(ex.getMessage()).build());}
JAX-RSモデル
● RESTサービスのパスの設定– Jerseyに渡すURLパターンを設定する。
34
// ${コンテキストルート/rs/以下のURIがリクエストされたらRESTとみなし、Jerseyに渡す}@ApplicationPath(“rs”)public class ApplicationConfig extends Application {}
JAX-RSモデル
● ライフサイクル(EJB)– JAX-WS(SOAP)と同じ
35
存在しない状態
準備状態
@PostConstruct @PreDestroy
メソッド呼び出し
演習
● ソースコードを熟読(ex14.BookResource14)
● ビルド+デプロイ
● cURLでGET/POST/DELETE
● リクエストのAcceptやContent-Typeを変えてみる
● PUT(Bookの修正)に対応させる
※リクエスト文はソースコードにコメントで書かれているのでcopy&pasteしてください
36
演習
● 修正– JSONArrayが見つからないエラーが発生する場合は、chapter15配下pom.xmlに以下のリポジトリを追加する。
– NetBeansでdeployした場合のURIは”chapter15/rs/14/books”になります。
– おまけで用意されているManagedBeanは腐っています。
● 動かしたい場合は頑張ってください。
37
<dependency> <groupId>org.codehaus.jettison</groupId> <artifactId>jettison</artifactId> <version>1.3.1</version> </dependency>
SOAP or REST?● REST と SOAP ではどちらが優れていますか
● セキュリティについて、SOAP は REST より優れているのではありませんか
● トランザクションについてはどちらが優れていますか
● 相互運用性について、SOAP は相互運用性が考慮されており、REST よりも優れているのではありませんか
● メタデータについてはどうでしょう。REST の相互運用性が高いとしても、REST には WSDL が存在せず、WSDL が存在しなければサービスを呼び出すクライアント側プロキシを生成できないため、使いにくくありませんか
● HTTP 以外のトランスポートを使用するにはどうすればよいでしょう
● ここまでの答えをまとめると、REST はインターネットに接続しているアプリケーションに適し、SOAP はエンタープライズ アプリケーションに適していることになりますか
38
続きはhttp://msdn.microsoft.com/ja-jp/magazine/dd942839.aspx