JAX-RS (Jersey) でパラメータとして独自のクラスをインジェクトする (1)
@QueryParamアノテーションで、パラメータをインジェクトすることができますが(パラメータに含まれない場合はnullになる)、パラメータがあまりに多いとメソッドシグネチャが見にくくなり、値をBeanにコピーしたりするのも面倒です。このような場合には、、
@GET @Produces({MediaType.APPLICATION_JSON}) public List<Contact> getContacts(@QueryParam("offset") Integer offset, @QueryParam("limit") Integer limit) { // 省略 }
UriInfoをインジェクトする
JavaによるRESTfulシステム構築では、以下のように、UriInfoをインジェクトして、そこからMultivaluedMap
@GET @Produces({MediaType.APPLICATION_JSON}) public List<Contact> getContacts(@Context UriInfo uiInfo) { int offset= uriInfo.getQueryParameters().getFirst("offset") int limit = uriInfo.getQueryParameters().getFirst("limit"); // .... }
MultivaluedMapからBean(DTOなど)にイテレータ経由でまとめてパラメータをコピーするような使い方もできそうです。
ResourceContextをインジェクトする
これ以外には、クエリパラメータがインジェクトされたBeanを取得する方法があります。例えばリストのページング検索条件用にこんなクラスを作ります。値をインジェクトしたいフィールドにアノテーションを付けておきます。
public class PagingParams { @QueryParam("limit") private String limit; @QueryParam("offset") private String offset; @QueryParam("sort") private String sort; @QueryParam("direction") private Direction direction; public String getLimit() { return limit; } public void setLimit(String limit) { this.limit = limit; } public String getOffset() { return offset; } public void setOffset(String offset) { this.offset = offset; } public String getSort() { return sort; } public void setSort(String sort) { this.sort = sort; } public Direction getDirection() { return direction; } public void setDirection(Direction direction) { this.direction = direction; } /** * ソートの方向 */ public enum Direction{ ASC, DESC; } }
enumのDirectionも自動で変換してくれます(コンストラクタがString1個のみのか、staticなvalueOf(String)を持つ型は自動変換してくれます)。
リソースクラスでは、ResourceContextをインジェクトして、PagingParamsのオブジェクトを取り出します。
@GET @Produces({MediaType.APPLICATION_JSON}) public List<Contact> getContacts(@Context ResourceContext rc) { PagingParams params = rc.getResource(PagingParams.class); // .... }
さらに、以下のJerseyのMLにある方法を使えば直接、PagingParamsをインジェクトすることもできるようです。
Jersey - Custom Parameter Binding