大まかにテーマ(ページ付け/順序付け、フィルタリング、認証)にグループ化された、を含む数十の@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]
コメントを追加