JAX-RSを使用して、2つのクエリパラメータを1つのオブジェクトにマージします

オリヴィエ・グレゴワール

大まかにテーマ(ページ付け/順序付け、フィルタリング、認証)にグループ化された、を含む数十の@QueryParamパラメーターを含むいくつかのリソースハンドルメソッドがあります@Defaultこれは本当に面倒なので、簡単にしたいと思います。良い点は、これらのパラメーターがテーマ(ページ付け、順序付け、フィルタリングなど)ごとにグループ化されているため、パラメーターのセット全体を4つのメソッドに減らすことができることです。

どうすればそれを達成できますか?

通常、私はこれから来たいと思います:

@GET
public Response findAll(
    @QueryParam("sort") @DefaultValue("name") List<String> sort,
    @QueryParam("from") UUID fromId
) {
  // Validate sort
  // Validate fromId
}

これに:

@GET
public Response findAll(@Context Pagination pagination) { // Inject pagination
  // Yeah, small code! Yeah, modularity!
}

// Create the pagination somewhere else.

public Pagination createPagination(@Context UriInfo uriInfo) {
  Optional<UUID> fromId = extractFromId(uriInfo); // retrieve "from" from uriInfo
  List<String> sort = extractSort(uriInfo); // retrieve "sort" from uriInfo
  Pagination pagination = new Pagination();
  pagination.setFromId(fromId);
  pagination.setSort(sort);
  // Validate pagination
  return pagination;
}

注:私の例で示しているように、自分でコードを追加してもかまいませんが、メソッドにパラメーターが多すぎることに耐えられず、@QueryParam+の壁を読んでい@DefaultValueます。

ポール・サムソサ

JAX-RS 2.0を使用している場合は@BeanParam、を使用できます。これにより、任意の@XxxParamアノテーション付きプロパティと@Contextオブジェクトを任意のBeanクラスに注入できます例えば

public class Bean {
    @QueryParam("blah")
    String blah;
}

@GET
public Response get(@BeanParam Bean bean) {}

不変性が必要な場合は、コンストラクターに挿入することもできます。例えば

public static class Pagination {

    private final List<String> sort;
    private final Optional<String> from;

    public Pagination(@QueryParam("sort") List<String> sort, 
                      @QueryParam("from") Optional<String> from) {
        this.sort = sort;
        this.from = from;
    }

    public List<String> getSort() { return sort; }
    public Optional<String> getFrom() { return from; }
}

Optionalが注入されていることに気付いた場合通常これは不可能ですが、私ParamConverterはそれために作成しました。あなたはこの答えでそれについてもっと読むことができます基本的に、パラメータの文字列値から作成して、任意のオブジェクトを挿入できます。

@Provider
public static class OptionalParamProvider implements ParamConverterProvider {

    @Override
    public <T> ParamConverter<T> getConverter(Class<T> rawType, 
                                              Type genericType, 
                                              Annotation[] annotations) {
        if (Optional.class != rawType) {
            return null;
        }

        return (ParamConverter<T>)new ParamConverter<Optional>() {

            @Override
            public Optional fromString(String value) {
                return Optional.ofNullable(value);
            }

            @Override
            public String toString(Optional value) {
                return value.toString();
            }  
        };
    }  
}

利点はOptionalParamProvider、それはあなたが使用することを可能にするということですOptionalどこでも注入する必要がある@FormParam@QueryParam@PathParm、および他のすべて@XxxParamのS(multitpartを除く)を。

使用しているJAX-RS実装はわかりませんが、上記はすべての実装で機能するはずです。以下用い、ジャージーテストケースであるジャージーテストフレームワーク他のJUnitテストと同じようにクラスを実行できます。

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Optional;
import javax.ws.rs.BeanParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import org.junit.Test;

public class BeanParamTest extends JerseyTest {

    @Provider
    public static class OptionalParamProvider implements ParamConverterProvider {

        @Override
        public <T> ParamConverter<T> getConverter(Class<T> rawType, 
                                                  Type genericType, 
                                                  Annotation[] annotations) {
            if (Optional.class != rawType) {
                return null;
            }

            return (ParamConverter<T>)new ParamConverter<Optional>() {

                @Override
                public Optional fromString(String value) {
                    return Optional.ofNullable(value);
                }

                @Override
                public String toString(Optional value) {
                    return value.toString();
                }  
            };
        }  
    }

    public static class Pagination {

        private final List<String> sort;
        private final Optional<String> from;

        public Pagination(@QueryParam("sort") List<String> sort, 
                          @QueryParam("from") Optional<String> from) {
            this.sort = sort;
            this.from = from;
        }

        public List<String> getSort() { return sort; }
        public Optional<String> getFrom() { return from; }
    }

    @Path("bean")
    public static class PaginationResource {

        @GET
        public String get(@BeanParam Pagination pagination) {
            StringBuilder sb = new StringBuilder();
            sb.append(pagination.getSort().toString());
            if (pagination.getFrom().isPresent()) {
                sb.append(pagination.getFrom().get());
            }
            return sb.toString();
        }
    }

    @Override
    public ResourceConfig configure() {
        return new ResourceConfig(PaginationResource.class)
                .register(OptionalParamProvider.class);
    }

    @Test
    public void should_return_all_sort_and_from() {
        Response response = target("bean")
                .queryParam("sort", "foo")
                .queryParam("sort", "bar")
                .queryParam("from", "baz")
                .request().get();
        assertEquals(200, response.getStatus());
        String message = response.readEntity(String.class);
        assertThat(message, containsString("foo"));
        assertThat(message, containsString("bar"));
        assertThat(message, containsString("baz"));
        System.out.println(message);
        response.close();
    }
}

これは、テストを実行するために必要な唯一のMaven依存関係です

<dependency>
    <groupId>org.glassfish.jersey.test-framework.providers</groupId>
    <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
    <version>2.19</version>
    <scope>test</scope>
</dependency>

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

JSONクエリパラメータをJAX-RSを使用してオブジェクトに変換する

分類Dev

パラメータとしてJAX-Bオブジェクトを使用したJAX-RSリクエストの検証

分類Dev

JAX-RSインターフェースを使用してオブジェクトの一部(サブオブジェクト)をシリアル化できないようにするにはどうすればよいですか?

分類Dev

ジャージー(JAX-RS)複数のオプションパラメーターを使用してパスをマップする方法

分類Dev

ジャージー(JAX-RS)複数のオプションパラメーターを使用してパスをマップする方法

分類Dev

jax-rs:jersey @pathparamは、1つのメソッドで前のパラメーターを取得します

分類Dev

JAX-RS Jersey RestfulWebサービスでさまざまなタイプのJSONオブジェクトを1回の呼び出しで取得する方法

分類Dev

JAX-Bを使用して2つのXMLを1つにマージする方法は?

分類Dev

JAX-RS複数のオブジェクトを投稿する

分類Dev

JAX-WSのみを使用して、リクエストの文字列パラメーターにCDATAを追加します

分類Dev

PUTリクエストにパラメータを渡すJAX-RS

分類Dev

JAX-RSを使用するときにオブジェクトのリストを返す

分類Dev

ZipInputStreamをJax-RS Responseオブジェクトとして返す

分類Dev

JacksonオブジェクトのマッピングにJAX-RS GenericTypeを使用する

分類Dev

JacksonオブジェクトのマッピングにJAX-RS GenericTypeを使用する

分類Dev

JAX-RSのGETパラメーターで別のルートをマップします

分類Dev

JAX-Bを使用してXMLから選択したクラスのオブジェクト(ポリモーフィック)を読み取る方法

分類Dev

JAX-RSリクエストのインターセプト:ContainerRequestFilterをTomcatに登録します

分類Dev

JAX-RSのPOSTリクエストからパラメータを受信する

分類Dev

オブジェクトフィールドをNULL値として表示するJAX-RS応答オブジェクト

分類Dev

オブジェクトフィールドをNULL値として表示するJAX-RS応答オブジェクト

分類Dev

JAX-RSのクエリパラメータで `%`シンボルをエスケープする

分類Dev

JAX-RSのフィルターを使用してHTTPリクエストにヘッダーを追加するにはどうすればよいですか?

分類Dev

Jax-rsがサブリソースを初期化しますインジェクションに使用できるオブジェクトがありませんでした

分類Dev

Jax-RS-サブリソースオブジェクトが出力に書き込まれます

分類Dev

JAX-RS + Jerseyを使用したJSONからオブジェクトへのマッピング用のMorphiaを含む

分類Dev

JAX-RS Webサービスを介してJSONオブジェクトを送信しようとすると、「mediaBodyWriter not media type = application / json」を取得する

分類Dev

JAX-RS / JerseyにJavaパッケージのリソースパスセグメントを追加しますか?

分類Dev

Responseオブジェクトに頼らずにJAX-RSを使用してETagを設定することは可能ですか?

Related 関連記事

  1. 1

    JSONクエリパラメータをJAX-RSを使用してオブジェクトに変換する

  2. 2

    パラメータとしてJAX-Bオブジェクトを使用したJAX-RSリクエストの検証

  3. 3

    JAX-RSインターフェースを使用してオブジェクトの一部(サブオブジェクト)をシリアル化できないようにするにはどうすればよいですか?

  4. 4

    ジャージー(JAX-RS)複数のオプションパラメーターを使用してパスをマップする方法

  5. 5

    ジャージー(JAX-RS)複数のオプションパラメーターを使用してパスをマップする方法

  6. 6

    jax-rs:jersey @pathparamは、1つのメソッドで前のパラメーターを取得します

  7. 7

    JAX-RS Jersey RestfulWebサービスでさまざまなタイプのJSONオブジェクトを1回の呼び出しで取得する方法

  8. 8

    JAX-Bを使用して2つのXMLを1つにマージする方法は?

  9. 9

    JAX-RS複数のオブジェクトを投稿する

  10. 10

    JAX-WSのみを使用して、リクエストの文字列パラメーターにCDATAを追加します

  11. 11

    PUTリクエストにパラメータを渡すJAX-RS

  12. 12

    JAX-RSを使用するときにオブジェクトのリストを返す

  13. 13

    ZipInputStreamをJax-RS Responseオブジェクトとして返す

  14. 14

    JacksonオブジェクトのマッピングにJAX-RS GenericTypeを使用する

  15. 15

    JacksonオブジェクトのマッピングにJAX-RS GenericTypeを使用する

  16. 16

    JAX-RSのGETパラメーターで別のルートをマップします

  17. 17

    JAX-Bを使用してXMLから選択したクラスのオブジェクト(ポリモーフィック)を読み取る方法

  18. 18

    JAX-RSリクエストのインターセプト:ContainerRequestFilterをTomcatに登録します

  19. 19

    JAX-RSのPOSTリクエストからパラメータを受信する

  20. 20

    オブジェクトフィールドをNULL値として表示するJAX-RS応答オブジェクト

  21. 21

    オブジェクトフィールドをNULL値として表示するJAX-RS応答オブジェクト

  22. 22

    JAX-RSのクエリパラメータで `%`シンボルをエスケープする

  23. 23

    JAX-RSのフィルターを使用してHTTPリクエストにヘッダーを追加するにはどうすればよいですか?

  24. 24

    Jax-rsがサブリソースを初期化しますインジェクションに使用できるオブジェクトがありませんでした

  25. 25

    Jax-RS-サブリソースオブジェクトが出力に書き込まれます

  26. 26

    JAX-RS + Jerseyを使用したJSONからオブジェクトへのマッピング用のMorphiaを含む

  27. 27

    JAX-RS Webサービスを介してJSONオブジェクトを送信しようとすると、「mediaBodyWriter not media type = application / json」を取得する

  28. 28

    JAX-RS / JerseyにJavaパッケージのリソースパスセグメントを追加しますか?

  29. 29

    Responseオブジェクトに頼らずにJAX-RSを使用してETagを設定することは可能ですか?

ホットタグ

アーカイブ