Jersey 2.14でパラメータの受け取りにOptionalが使えるようになった
Jersey 2.14がリリースされたようです!
で、注目はJERSEY-2612
です。
この対応のおかげで@QueryParam
などのパラメータをOptional
で定義する事が可能になります。
ただしParamConverter
を書く必要はありますが。
ParamConverter
ってなんやねん!って方は
の後半を読んでくださいませー。
リクエストパラメータをOptionalで受け取るコード例
適当ですがサクッちょとサンプル書きました。
リソースクラスをこちらにも掲載します。
ちょー簡単な例ですが、こんな感じでリソースメソッドの引数にOptional
を使えるようになります。
package example;
import java.util.Optional;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
@Path("hello")
public class HelloWorld {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String say(@QueryParam("name") Optional<String> name) {
return "Hello, " + name.orElse("world") + "!";
}
}
注意点としては先ほども書きましたがParamConverter
実装クラスとParamConverterProvider
実装クラスも自前で準備しなくてはならない事です。
まあ、一度書いたら使い回せるはずなのでサクッと書いておきましょー。
今までこれが出来なかった理由
@QueryParam
などで注釈された引数へ渡される値はSingleValueExtractor
のextract
メソッドを通るんですが、Jersey 2.13までのextract
メソッドは「値がnull
でなければParamConverter
などで変換、null
なら@DefaultValue
で設定された値を返す」という感じの実装になっていました。
その部分を抜粋します。
@Override public T extract(MultivaluedMap<String, String> parameters) { String v = parameters.getFirst(getName()); if (v != null) { try { return fromString(v); } catch (WebApplicationException ex) { throw ex; } catch (ProcessingException ex) { throw ex; } catch (Exception ex) { throw new ExtractorException(ex); } } else { return defaultValue(); } }
このロジックが原因でOptional
のParamConverter
を書いてもnull
が渡ってくるアレっぷりでした。
しかしこのextract
メソッドはJersey 2.14で次のように修正されました。
@Override public T extract(MultivaluedMap<String, String> parameters) { String v = parameters.getFirst(getName()); try { return fromString((v == null && isDefaultValueRegistered()) ? getDefaultValueString() : v); } catch (WebApplicationException ex) { throw ex; } catch (ProcessingException ex) { throw ex; } catch (IllegalArgumentException ex) { return defaultValue(); } catch (Exception ex) { throw new ExtractorException(ex); } }
ご覧の通り「値がnull
かつデフォルト値が設定されていればデフォルト値を、そうでなければ値をParamConverter
などに渡す」という風になっています。
これで値がnull
の場合でもParamConverter
を通るようになり、Optional
への変換が可能になりました。
まとめ
- Jerseyでリクエストパラメータなどの受け取りに
Optional
使えるようになって嬉しい - ハイテンションでブログ書いたら文章やばい
そんな感じでー
Discussion