-サービスパラメータ(1)

サービスパラメータは、とても強力な仕組みです。HTTPリクエストパラメータに似て、URL中に埋め込まれる文字列を介してクライアントとサーバーで情報をやり取りする機能ですが、HTTPリクエストパラメータが受け渡しできる情報が文字列のみであるのに対して、サービスパラメータはオブジェクトを交換できます。
たとえば以下のようなページがあったとします。

<page-specification class="sample.serviceparam.Home">
  <component id="direct" type="DirectLink">
    <binding name="listener" expression="listeners.click"/>
    <binding name="parameters" expression="sparam"/>
  </component>
</page-specification>

この、DirectLinkコンポーネントに設定している、"parameters"プロパティはサービスパラメータが利用されています。このプロパティはObject型ですが、基本的にList型もしくはObject配列が入ってくることを想定して作られています。サービスパラメータはObject配列を取り扱うので、DirectLinkコンポーネント内部でObjrctもしくはListの場合は、Object[]に変換して内部処理に渡しています。
対応するHTMLは以下のとおりです。

<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <a href="#" jwcid="direct">click</a>
  </body>
</html>

シンプルにリンクが一つあるだけです。Javaのページオブジェクトは以下のとおりです。

public class Home extends BasePage {
  public Object getSparam() {
    Object ret = new Object[2];
    ret[0] = new Integer(999);
    Person person = new Person();
    person.setName("masataka");
    person.setAge(31);
    ret[1] = person;
    return ret;
  }
  public void click(IRequestCycle cycle) {
    Object[] params = cycle.getServiceParameters();
    int value = *1;
    System.out.println("[1].age=" + person.getAge()); 
  }
}

getSparam()では、以下のシンプルなBeanを使ってます。

public class Person implements Serializable {
  private String name;
  private int age;
  public int getAge() {
    return age;
  }
  public String getName() {
    return name;
  }
  public void setAge(int age) {
    this.age = age;
  }
  public void setName(String name) {
    this.name = name ;
  }
}

この出力ページソースは以下のとおりです。

<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <a href="(URL+シリアライズされたパラメータ文字列。長いので後述)">click</a>
  </body>
</html>

URL+シリアライズされたパラメータ文字列は以下のとおりです。

/app?service=direct/0/Home/direct&sp=999&sp=OH4sIAAAAAAAAAFvzloG1uIhBpDgxtyAnVa84E0wFpBYV5-cp3LoveoyjQ4CJgcmTgTkxPdWHgSUvMTe1hEHIJyuxLFE_JzEvXT-4pCgzL926ooCBgUG-hIEjN7E4sSQxOxEAnKgp81oAAAA.

見事に、IntegerとPersonがURLの一部になっています。「sp=」が二度URL中に出現していることに注意してみてください。一つ目の「sp=」に続く「999」はIntegerの値、二つ目の「sp=」の後に続くのはPersonオブジェクトのシリアライズ結果です。このように、サービスパラメータはObject配列を文字列化してリンクURLに埋め込む機能を提供しています。クリック後のサーバーの受け取りは文字列からObject配列に自動的に戻され、IRequestCycle#getServiceParameters()によって取得することができます。
この仕組みは、URLに情報をエンコードしてしまうので、完全にServletセッションを使わないで、Servletセッションと同様の機能を提供するものです。既存のコンポーネントではただそれまでの内容ですが、この機能は独自にサービスを実装する場合に活用することができます。(つづく)

*1:Integer)params[0]).intValue(); Person person = (Person)params[1]; System.out.println("[0]=" + value); System.out.println("[1].name=" + person.getName(