JAX-RS と Jersey

最終更新: 2024-07-01 19:46:18 +0800 +0800
tags: Java | Jax-Rs | Jersey | Web
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

JAX-RS は、jakarta.ws.rs パッケージにおける HTTP リソースの Jakarta 標準 API および仕様です。 アノテーション、リクエストとレスポンスの型、クライアント API、プロバイダー、 サーバー送信イベントを定義します。Jersey は準拠する JAX-RS 実装です。

JAX-RS は XML Web サービスを扱う JAX-WS とは異なります。

リソースを定義する #

Jakarta REST API をコンパイル時に、JAX-RS 実装を実行時に追加します。リソースクラス は @Path を使い、メソッドは HTTP メソッドアノテーションを使い、相対パスを追加 できます。

java
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public class UserResource {
    @GET
    @Path("/{id}")
    public User get(@PathParam("id") long id) {
        return service.find(id);
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response create(User input) {
        User created = service.create(input);
        return Response.created(
                URI.create("/users/" + created.id())).entity(created).build();
    }
}

Application サブクラスには @ApplicationPath("/api") を付けられます。周囲の コンテナーまたは実装が、リクエストを JAX-RS ランタイムへ届ける方法を決定します。

リクエストをバインドする #

ボディ以外のメソッドパラメーターには、値の取得元をアノテーションで指定します。

  • @PathParam、@QueryParam、@MatrixParam は URI コンポーネントを読み取ります。
  • @HeaderParam、@CookieParam、@FormParam はヘッダー、Cookie、フォームデータを読み取ります。
  • @Context はコンテキストの JAX-RS オブジェクトを注入します。
java
@GET
public Response search(
        @QueryParam("q") String query,
        @QueryParam("limit") @DefaultValue("20") int limit) {
    return Response.ok(service.search(query, limit)).build();
}

アノテーションのないリソースメソッドパラメーターは通常、リクエストエンティティです。 Java 型は MessageBodyReader によってサポートされる必要があります。たとえば JSON からオブジェクトへのバインディングには、インストール済みの JSON プロバイダーが 必要です。契約を明確にするため @Consumes を宣言します。InputStream は生の エンティティを受け取れますが、JAX-RS のコアだけでは multipart/form-data を解析 しません。Jersey の multipart モジュールなど、対応する multipart プロバイダーを 使用します。

@BeanParam を使って複数のパラメーターバインディングを Bean にまとめます。

java
public class PageRequest {
    @QueryParam("offset") @DefaultValue("0") int offset;
    @QueryParam("limit") @DefaultValue("20") int limit;
}

@BeanParam PageRequest page として使用します。入力は明示的に、またはランタイムが 提供する Jakarta Validation 統合を通じて検証します。

レスポンスとエラーを生成する #

メソッドはエンティティを直接返すか、ステータス、ヘッダー、エンティティを明示的に 制御するため Response を返せます。@Produces はコンテンツネゴシエーションに 参加します。適切なステータスと安定したエラー表現を返し、スタックトレースを クライアントに公開しないでください。

NotFoundException や BadRequestException などの WebApplicationException を スローすると HTTP レスポンスが提供されます。アプリケーション例外には ExceptionMapper<T> を記述し、@Provider を付けます。

java
@Provider
public class IllegalArgumentMapper
        implements ExceptionMapper<IllegalArgumentException> {
    public Response toResponse(IllegalArgumentException error) {
        return Response.status(Response.Status.BAD_REQUEST)
                .entity(Map.of("error", error.getMessage())).build();
    }
}

ランタイムは、スローされた例外に最も近いスーパータイプの例外型を持つ適用可能な マッパーを選びます。該当するものがなければ、コンテナー統合に従ってサーバーエラー レスポンスを生成します。

Jersey でデプロイする #

Jersey は JAX-RS の契約を実装しますが、それ自体では TCP 接続を受け付けません。 サーブレットコンテナーでは org.glassfish.jersey.containers:jersey-container-servlet を追加し、 org.glassfish.jersey.servlet.ServletContainer を登録し、リソースパッケージスキャン または ResourceConfig を構成します。

組み込みサーバーでは ResourceConfig を作成し、対応する Jersey コンテナーに渡します。 可能な限りアプリケーションコードは jakarta.ws.rs に依存させ、Jersey 固有の設定は デプロイメント境界に隔離します。

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)