前回の記事 beatdjam.hatenablog.com
前回はJerseyの環境づくりと起動方法、Kotlinへの変換について書きました。
今回は各種リクエストパラメータをどうやって取り扱うかを説明します。
準備
今回の記事の内容を扱うにあたり、新しいResouceクラスを作成しましょう。
下記の形でParametersResource.kt
を作成します。
このクラスには @Path("parameters")
アノテーションがついているので、
http://localhost:8080/myapp/parameters
に対応するクラスとなります。
クラスに@Path
がついている状態でメソッドにも@Path
がついているとき、
クラスのpath/メソッドのpath
に対応します。
package com.example import com.example.form.BeanParamSample import java.nio.charset.Charset import javax.validation.Valid import javax.ws.rs.* import javax.ws.rs.core.MediaType /** * Root resource (exposed at "myresource" path) */ @Path("parameters") class ParametersResource { }
HTTPリクエストのクエリ
HTTPリクエストのクエリに含まれている値を利用するには、@QueryParam
を使います。
例)
@QueryParam("parameter") parameter: String?
http://localhost:8080/myapp/parameters/queryparam?parameter=hoge
@GET @Path("/queryparam") @Produces(MediaType.TEXT_PLAIN) fun queryParam(@QueryParam("parameter") parameter: String?): String { return if (parameter.isNullOrEmpty()) { "Parameter is Empty." } else parameter }
クエリをdata classに対応させる
前述したQueryParam
をdata classのフィールドに定義します。
これを、対応させたいResourceクラスで@BeanParam
アノテーションをつけて記述すると、
リクエスト時に自動でdata classに格納してくれるようになります。
後述する @PathParam
や@FormParam
でも利用できるので覚えておきましょう。
また、JerseyではJavaEEのBean Validationという仕組みが利用できます。
@field:NotNull
や @field:NotEmpty
などのバリデーション用のアノテーションを設定すると、
正しくないリクエストに対して、自動で400 Bad Request
を返却してくれるものです。
- リクエストOK
- NotNull制約に引っかかるクエリ
- NotEmpty制約に引っかかるクエリ
data class BeanParamSample ( @QueryParam("parameter1") val parameter1: String?, @QueryParam("parameter2") @field:NotNull val parameter2: String?, @QueryParam("parameter3") @field:NotEmpty val parameter3: String? )
@GET @Path("/beanparam") @Produces(MediaType.TEXT_PLAIN) fun beanparam(@BeanParam @Valid parameter: BeanParamSample): String { return buildString { appendln( if (parameter.parameter1.isNullOrEmpty()) { "Parameter is Empty." } else parameter.parameter1 ) appendln(parameter.parameter2) appendln(parameter.parameter3) } }
Pathに含まれる値
HTTPリクエストのパスに含まれる値を利用するためには @PathParam
アノテーションを利用します。
また、@Path
の指定時にパラメータとしたい箇所を{}
でくくる必要があります。
例)
@Path("/pathparam/{parameter1}
@PathParam("parameter") parameter: String?
http://localhost:8080/myapp/parameters/pathparam/hogehoge
@GET @Path("/pathparam/{parameter}") @Produces(MediaType.TEXT_PLAIN) fun pathParam(@PathParam("parameter") parameter: String?): String { return if (parameter.isNullOrEmpty()) { "Parameter is Empty." } else parameter }
リクエストパスからパターンに対応した値を取り出す
パターンに対応する文字列から複数を取り出すような事もできます。
{parameter1}.{parameter2}
のようなパターンを設定すると、
0000.1234
のようなパスの0000
と1234
をそれぞれ取得できます。
例)
@Path("/pathparam/{parameter1}.{parameter2}")
@PathParam("parameter1") parameter1: String?
@PathParam("parameter2") parameter2: String?
http://localhost:8080/myapp/parameters/pathparam/1234.5678
@GET @Path("/pathparam/{parameter1}.{parameter2}") @Produces(MediaType.TEXT_PLAIN) fun pathParamSplit( @PathParam("parameter1") parameter1: String?, @PathParam("parameter2") parameter2: String? ): String { return (parameter1 ?: "") + "." + (parameter2 ?: "") }
リクエストパスから正規表現に対応した値を取り出す
パターンは正規表現で記述することもできます。
例)
@Path("/pathparam/regex/{regexMatched:.*}")
@PathParam("regexMatched") regexMatched: String?
http://localhost:8080/myapp/parameters/pathparam/regex/hogefuga/hoge
@GET @Path("/pathparam/regex/{regexMatched:.*}") @Produces(MediaType.TEXT_PLAIN) fun pathParamRegex(@PathParam("regexMatched") regexMatched: String?): String { return if (regexMatched.isNullOrEmpty()) { "Not matched by regex." } else regexMatched }
Formから送信されたリクエストを取得する
application/x-www-form-urlencoded
形式で送られたリクエストのパラメータは、
@FormParam
で取り出すことができます。
例)
@FormParam("form1") form1param : String?
@FormParam("form2") form2param : String?
POSTなのでブラウザから直接たたけないため、CLI上で下記を叩いてください。
curl -d "form1=form1text" -d "form2=form2text" http://localhost:8080/myapp/parameters/formparam
@POST @Path("/formparam") @Produces(MediaType.TEXT_PLAIN) fun formParam( @FormParam("form1") form1param : String?, @FormParam("form2") form2param : String? ): String { return buildString { appendln("form1 : $form1param") appendln("form2 : $form2param") } }
ファイルアップロードに対応する
ほぼ以前書いた下記記事のままです。
【Kotlin/Java】Jersey2でファイルアップロードを扱う - B-Teck!
POSTなのでブラウザから直接たたけないため、CLI上で下記を叩いてください。
curl --header "Content-Type:application/octet-stream" -d "{"hoge": "fuga"}" http://localhost:8080/myapp/parameters/upload
@POST @Path("/upload") @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.TEXT_PLAIN) fun upload(input : ByteArray): String { return input.toString(Charset.defaultCharset()) }
ここまでの作業
下記のタグまでが今回の記事の作業分です。
https://github.com/beatdjam/Jersey-On-Kotlin-Sample/tree/chapter2
作成したファイル
https://github.com/beatdjam/Jersey-On-Kotlin-Sample/blob/chapter2/src/main/kotlin/com/example/ParametersResource.kt
https://github.com/beatdjam/Jersey-On-Kotlin-Sample/blob/chapter2/src/main/kotlin/com/example/form/BeanParamSample.kt