BeanParamをネストさせる
【エントリ変更履歴】
- Jerseyのバージョンを1.19 => 2.21 に変更
【概要】
BeanParamアノテーションをネストさせて使う方法です。
結論から先に行くとアノテーションつけるだけ。
今回のやり方をやるのであれば、
JSONで渡したほうが使いやすいかなというところです。
もっと良いやり方がある可能性はありますが。
【設定周り】
pom.xmlとApplicationクラスです。
この辺は基本的な設定しかしていないので読み飛ばして問題ないです。
実際に動かしてみたい人はコピーすれば動くと思います。
[pom.xml]
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jp.glory</groupId> <artifactId>JAX-RS</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>JAX-RS</name> <properties> <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>javax.enterprise</groupId> <artifactId>cdi-api</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>javax.ws.rs</groupId> <artifactId>javax.ws.rs-api</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>2.21</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> <compilerArguments> <endorseddirs>${endorsed.dir}</endorseddirs> </compilerArguments> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.3</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.6</version> <executions> <execution> <phase>validate</phase> <goals> <goal>copy</goal> </goals> <configuration> <outputDirectory>${endorsed.dir}</outputDirectory> <silent>true</silent> <artifactItems> <artifactItem> <groupId>javax</groupId> <artifactId>javaee-endorsed-api</artifactId> <version>7.0</version> <type>jar</type> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
[Applicationクラス]
package jp.glory.jax.rs.applicaion; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("service") public class ApplicationSetting extends Application { }
【ネストさせる】
親となるRootParamBeanと子となるChildParamBeanの二つを作成します。
[RootParamBean]
package jp.glory.jax.rs.applicaion.resource.beanparam.nest; import javax.ws.rs.BeanParam; import javax.ws.rs.FormParam; public class RootParamBean { @FormParam("name") private String name = null; @FormParam("age") private Integer age = null; @BeanParam private ChildParamBean child = null; // アクセサは省略 }
ネストさせたいBeanにBeanParamアノテーションをつけるだけです。
[ChildParamBean]
package jp.glory.jax.rs.applicaion.resource.beanparam.nest; import javax.ws.rs.FormParam; public class ChildParamBean { @FormParam("skill.name") private String name = null; @FormParam("skill.year") private Integer year = null; public String getName() { return name; } // アクセサは省略 }
子側のBeanでは通常どおりにFormParamアノテーションを使っているのですが、
その中のvalue値は注意が必要です。
RootParamBeanの変数名childと
Child ParamBeanのFormParamアノテーションでつけた名前を
組み合わせてくれると 思っていたのですがそうではないみたいです。
(今回の例では”child" + “.” + FormParamアノテーションのvalue値を期待していました)
どうやら完全に一致させていないと値が設定されないようです。
この辺は調べ切れていないところもあり、実は簡単にできるというのはあるかもしれないです。
【リソースクラスと画面】
リソースクラスでは受け取ったBeanの中身をコンソールに出力します。
[リソースクラス]
package jp.glory.jax.rs.applicaion.resource.beanparam.nest; import javax.ws.rs.BeanParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; @Path("/beanparam/nest") public class NestParam { @POST public Response send(@BeanParam RootParamBean param) { System.out.println("param.name : " + param.getName()); System.out.println("param.age : " + param.getAge()); System.out.println("param.skill.name : " + param.getChild().getName()); System.out.println("param.skill.year : " + param.getChild().getYear()); return Response.ok().build(); } }
[画面]
画面はFormParamアノテーションで指定した値と同じ入力フォームがあるだけです。
<!DOCTYPE html> <html> <head> <title>BeanParamのネスト</title> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> </head> <body> <form action="/JAX-RS/service/beanparam/nest" method="post"> <dl> <dt>名前</dt> <dd> <input type="text" name="name" value="シュンツ" /> </dd> <dt>年齢</dt> <dd> <input type="text" name="age" value="28" /> </dd> <dt>スキル</dt> <dd> <dl> <dt><input type="text" name="skill.name" value="Java" /></dt> <dd><input type="text" name="skill.year" value="10" /></dd> </dl> </dd> </dl> <button>送信</button> </form> </body> </html>
【実行結果】
情報: param.name : シュンツ 情報: param.age : 28 情報: param.skill.name : Java 情報: param.skill.year : 10
ということでネストさせたパラメータも受け取れています。
【動いたけど・・・】
以下の二点によりちょっとこのやり方はやらないほうがいいかなぁと。
- パラメータの名前が固定化される
- リストとしては受け取れない
[パラメータの名前が固定化される]
ChildParamBean内でパラメータ名が固定化はされるのは当然なのですが、
ChildParamBean自体のパラメータ名が固定化されるのは微妙かなと。
今回はskillという変数名で固定化されています。
場所によってはBean自体の名前は変えたいというときにこのやり方だと対応できないです。