Beginning JAX-RS

Preview:

DESCRIPTION

JAX-RSの基礎、JAX-RS 2.0対応版

Citation preview

Beginning JAX-RS

HASUNUMA KenjiVice president, GlassFish Users Group Japan

k.hasunuma@coppermine.jpTwitter: @btnrouge

December 13, 2012

What’s REST?

RESTful Webサービスとは?

RESTの3原則に基づく

•リソース (対象)

•メソッド (リソースへの操作)

•URI (リソースの識別)

Statelessである…Web本来の姿

RESTfulなもの

• Static Web sites• Weblog (Movable Type, WordPress, etc.)

• Google API• Amazon API• Twitter API• Facebook API➡RESTの3原則=メソッドの使い分け

RESTfulでないもの

• Old CGI Applications

• SOAP based Web service

• Apache Struts (※A級戦犯)

• JavaServer Faces

➡何でもかんでもPOSTで処理(StatelessなWeb本来の姿をねじ曲げている)

リソース•ネットワーク上に存在する情報

URIで識別され、状態を持つ

•性質: リクエストを受け付け、その時の状態に応じてレスポンスを返す

•静的リソース: HTMLファイルなど

•動的リソース: Webアプリケーション

メソッド

メソッド 説明GET リソースの状態を取得する

POST リソースの状態を変更するPUT リソースを追加する

DELETE リソースを削除するHEAD リソースのヘッダーを返す

OPTIONS 有効なメソッドを返す

URI (Unified Resource Identifier)

•リソースを一意に識別する• Unixなどのファイルシステムに似たパ

ス構造を持つ

→ツリー構造

•現在はURLと同義

/say/hello/to/you

/

everybodyhello

goodbyesay

you

write

to

URI = ツリー構造

JAX-RS History

JSR 311 : JAX-RS

• JSR Review : 2007-02-26

• Early Draft Review : 2007-11-23

• Public Review : 2008-06-02

• Final Draft : 2008-09-22

• Final Release : 2008-10-10

• Java EE 6 (JSR 316) : 2009-12-10

Interlude (2008-10/2009-12)

• JAX-RS 0.9 - Last big changes

- @ConsumeMime -> @Consumes

- @ProduceMime -> @Produces

• JAX-RS 1.0 - Final releaseGlassFish v3 Prelude

• JAX-RS 1.1 - Maintenance releaseJava EE 6, EJB Integration

JSR 339 : JAX-RS 2.0

• JSR Review : 2011-01-24

• Early Draft Review 3 : 2012-07-07

• Public Review : 2012-11-26

• Final Draft : ?

• Final Release : ?

• Java EE 7 (JSR 342) : 2013 Q2

JAX-RS 2.0

JAX-RSの主な実装

Jersey (RI)GlassFish Server

Jersey (RI) Oracle WebLogic ServerJersey (RI)Fujitsu Interstage AS

RESTEasyJBoss AS

RESTEasyJBoss EAP

Apache WinkIBM WebSphere AS

Apache Wink IBM WAS CEApache WinkApache Geronimo

Apache CXF Apache TomEE+その他 Hitachi uCosminexus AS不明 Tmax JEUS

Core Features

JAX-RSの処理フロー

JAX-RSの処理フロー JAX-RS 2.0

RESTとJAX-RS

•リソース →リソースクラス (POJO)•メソッド →対応するアノテーション@GET, @POST, @PUT, @DELETE

• URI →@Path•リクエスト/レスポンス→リクエスト種類ごとにメソッド

リソースクラス

•リソースの振る舞いを定義するPOJO

• @Pathアノテーション付きのクラス•リクエスト→内容を判断し適切なメソッドに振り分け

• EJB(Stateless or Singleton)で定義可→EJB連携…CDIを使用するには必須

リソースクラス

• CDI連携…EJB連携を行わなくてもCDIが使用可能に

• Bean Validation対応(引数)

•非同期通信をサポート:メソッド内で別スレッドを生成する(Concurrency Utilitiesの利用を推奨)

JAX-RS 2.0

@Path(”/hello”)

public class HelloResource {

@GET

@Consumes(”application/x-www-urlencoded”)

@Produces(”text/plain”)

public String sayHello(@QueryParam(”q”) String name) {

return “Hello, ” + name;

}

}

簡単なリソースクラスの例

@Path(”/hello”)

public class HelloResource {

@GET

@Consumes(”application/x-www-urlencoded”)

@Produces(”text/plain”)

public String sayHello(@QueryParam(”q”) String name) {

return “Hello, ” + name;

}

}

GET /hello?q=everybody

Response Request

リソースクラスのメソッド引数アノテーション 設定される値@QueryParam クエリー・パラメーターの値@FormParam フォーム・パラメーターの値@PathParam URIの一部

@MatrixParam Matrix URIの属性部分@HeaderParam リクエストヘッダーの値@CookieParam クッキーの値

(なし) リクエストボディー

@Path(”/hello/{q}”)

public class HelloResource {

@GET

@Consumes(”application/x-www-urlencoded”)

@Produces(”text/plain”)

public String sayHello(@PathParam(”q”) String name) {

return “Hello, ” + name;

}

}

GET /hello/everybody

Response Request

参考: @PathParam

@Path("/position")public class PositionResource { @GET public String getPosition( @MatrixParam("latitude") double latitude, @MatrixParam("longitude") double longitude) { return String.format("%3.2f%s %3.2f%s", Math.abs(latitude), latitude == 0.0 ? "" : (latitude > 0.0 ? "N" : "S"), Math.abs(longitude), longitude == 0.0 ? "" : (longitude > 0.0 ? "E" : "W")); }}

GET /position;latitude=35.75;longitude=139.72参考: @MatrixParam

JavaクラスとMIMEタイプの対応Javaクラス MIMEタイプ

byte[ ]任意のMIMEタイプ

(*/*)String 任意のMIMEタイプ

(*/*)InputStream任意のMIMEタイプ

(*/*)Reader

任意のMIMEタイプ(*/*)

JavaBean(JAXB)

text/xmlJavaBean

(JAXB) application/xmlJavaBean(JAXB)

application/jsonMultivaluedMap application/x-www-urlencoded

Boolean text/plain※プリミティブ型はauto-boxing

Charactertext/plain

※プリミティブ型はauto-boxingNumber

text/plain※プリミティブ型はauto-boxing

特殊なMIMEタイプ

•最も汎用的な方法:MessageBodyReaderまたはMessageBodyWriterを拡張する

• JAXBの使用が前提なら、JAXBのカスタムマーシャラー実装の方が容易

• byte[ ]やInputStreamで受けて、独自にデコードする方法もあり(結構大変)

特殊なMIMEタイプ•インターセプター:

MessageBodyReaderの前、またはMessageBodyWriterの後に実行

•リソースクラスと独立してリクエスト/レスポンスボディーを加工する。

•例: リクエスト/レスポンスのgzip圧縮※JSR 339仕様書にサンプルコードあり

JAX-RS 2.0

クライアントAPI

// Step 1 : Clientオブジェクト作成Client client = ClientFactory.newClient();

// Step 2 : ターゲット(URI)設定WebTarget target = client.target(uri);

// Step 3 : リクエストResponse response = target.request().get();

JAX-RS 2.0

クライアントAPI

// Step 3a : リクエスト(型指定)String response = target.request().get(String.class);

// Step 3b : 非同期リクエストFuture<String> response = target.request().async().get(String.class);

JAX-RS 2.0

How to deploy

JAX-RSのデプロイ方法

•Webアプリケーションとしてデプロイ

•設定方法:1.Applicationのサブクラスを作成

2.実装固有のサーブレットを登録(web.xml)

※ uCosminexusのみ非対応(独自手順に従う)

@ApplicationPath(“/app”)public MyApplication extends Application { // 通常は空の実装でよい}

下記のURLでアクセス可能:http://hostname/context-root/app/hello

Applicationのサブクラスを作成

実装固有のサーブレットを登録(Jerseyの場合)

<servlet> <servlet-name>Jersey</servlet-name> <servlet-class>com.sun.jersey.spi.container .servlet.ServletContainer</servlet-class></servlet><servlet-mapping> <servlet-name>Jersey</servlet-name> <url-pattern>/app/*</url-pattern></servlet-mapping>

実装固有のサーブレットを登録(Jerseyの場合(裏技))

@WebServlet(“/app/*”)public class MyServletContainer extends ServletContainer { // 必ず空の実装}

Extensions

コンテキストの注入

@Context で以下コンテキストを注入可能

• ServletConfig

• ServletContext

• HttpServletRequest

• HttpServletResponse→サーブレットの機能を直接利用可能(例) HttpSession、リダイレクト

プロバイダーによる拡張@Provider で機能拡張

• @Provider を付加されたクラスが自動的に読み込まれる

(具体例)

•カスタムMessageBodyReader/Writer

•フィルター/インターセプター(JAX-RS 2.0)• EJB連携(JAX-RS 1.0以前)

Non-standard Features

Jersey

•クライアントAPI

•MIME Multipartメッセージ

•フィルター

•OAuth認証

•gzip圧縮/展開

•MVCサポート

RESTEasy

•クライアントAPI

•MIME Multipartメッセージ•インターセプター•CDI連携•非同期通信•OAuth認証•gzip圧縮/展開

Apache CXF

•クライアントAPI

•MIME Multipartメッセージ

•インターセプター (CXFの定義による)•Kerberos認証

•JAX-WS連携

Apache Wink

•クライアントAPI

•MIME Multipartメッセージ

※WebSphere AS - 独自拡張あり

Conclusions

• JAX-RSはFinal release当初から完成されたAPI (JEE6以前にも実績あり)

• JAX-RS 2.0…実装依存の機能を標準化

•標準化されていない実装固有の機能も今後標準化される可能性はある

•サーブレットで可能なことはJAX-RSでもほぼ可能である

•JAX-RS = 高水準API

• JAX-RSのメリットは、RESTの概念が理解できていればWebサービスの実装が容易であること

• JAX-RSはサーブレットベースに構築されているが、通常サーブレットを意識する必要はない。