2011年4月8日金曜日

Struts2 + Spring + Slim3 サンプル

今回は、 【修正版】 Struts2 + Spring + Slim3で構築したフレームワークを使ってサンプルのソースを書いてみます。

サンプルは簡単なデータ登録と表示の実装です。

作成するファイル一覧
今回、作成するファイルは以下の通りです。それ以外のファイルは一切触りません。
ファイル一覧
/src/com/brightgenerous/s3/sample/action/Sample_Action.java
/src/com/brightgenerous/s3/sample/action/Sample_Service.java
/src/com/brightgenerous/s3/sample/action/Sample_ServiceImpl.java
/src/com/brightgenerous/s3/sample/data/model/Account.java
/src/com/brightgenerous/s3/sample/data/meta/AccountMeta.java
/war/WEB-INF/content/sample/index.jsp
/war/WEB-INF/content/sample/show.jsp
「Account.java」と「AccountMeta.java」はSlim3のプラグインを使って自動生成します。
javaのソースコード
1.com.brightgenerous.s3.sample.action.Sample_Action.java
  1. package com.brightgenerous.s3.sample.action;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.apache.struts2.convention.annotation.Action;  
  6. import org.apache.struts2.convention.annotation.Namespace;  
  7. import org.apache.struts2.convention.annotation.ParentPackage;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9.   
  10. import com.brightgenerous.s3.sample.data.model.Account;  
  11. import com.opensymphony.xwork2.ModelDriven;  
  12.   
  13. @ParentPackage("struts-default")  
  14. @Namespace("/sample")  
  15. public class Sample_Action implements ModelDriven<account> {  
  16.   
  17.  private Account p_model = new Account();  
  18.   
  19.  @Autowired  
  20.  private Sample_Service p_service;  
  21.   
  22.  @Override  
  23.  public Account getModel() {  
  24.   return p_model;  
  25.  }  
  26.   
  27.  public List<account> getAccounts() {  
  28.   return p_service.get();  
  29.  }  
  30.   
  31.  /** 
  32.   * [Action:初期表示] 
  33.   */  
  34.  @Action("index")  
  35.  public String index() {  
  36.   
  37.   return "index";  
  38.  }  
  39.   
  40.  /** 
  41.   * [Action:表示] 
  42.   */  
  43.  @Action("show")  
  44.  public String show() {  
  45.   
  46.   return "show";  
  47.  }  
  48.   
  49.  /** 
  50.   * [Action:登録] 
  51.   */  
  52.  @Action("regist")  
  53.  public String regist() {  
  54.   p_service.regist(p_model);  
  55.   return show();  
  56.  }  
  57. }  
  58. </account></account>  
2.com.brightgenerous.s3.sample.action.Sample_Service.java
  1. package com.brightgenerous.s3.sample.action;  
  2.   
  3. import java.util.List;  
  4.   
  5. import com.brightgenerous.s3.sample.data.model.Account;  
  6.   
  7. interface Sample_Service {  
  8.   
  9.  Account regist(Account x_account);  
  10.   
  11.  List<Account> get();  
  12. }  
3.com.brightgenerous.s3.sample.action.Sample_ServiceImpl.java
  1. package com.brightgenerous.s3.sample.action;  
  2.   
  3. import java.util.List;  
  4.   
  5. import org.slim3.datastore.Datastore;  
  6. import org.springframework.stereotype.Component;  
  7.   
  8. import com.brightgenerous.s3.sample.data.meta.AccountMeta;  
  9. import com.brightgenerous.s3.sample.data.model.Account;  
  10.   
  11. @Component  
  12. class Sample_ServiceImpl implements Sample_Service {  
  13.   
  14.  @Slim3GlobalTransaction  
  15.  private GlobalTransaction p_tx;  
  16.   
  17.  @Override  
  18.  public Account regist(Account x_account) {  
  19.   p_tx.put(x_account);  
  20.   return x_account;  
  21.  }  
  22.   
  23.  @Override  
  24.  public List<account> get() {  
  25.   AccountMeta meta = AccountMeta.get();  
  26.   return Datastore.query(meta).asList();  
  27.  }  
  28. }  
  29. </account>  
4.com.brightgenerous.s3.sample.data.model.Account.java
  1. package com.brightgenerous.s3.sample.data.model;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import com.google.appengine.api.datastore.Key;  
  6.   
  7. import org.slim3.datastore.Attribute;  
  8. import org.slim3.datastore.Model;  
  9.   
  10. @Model(schemaVersion = 1)  
  11. public class Account implements Serializable {  
  12.   
  13.  private static final long serialVersionUID = 1L;  
  14.   
  15.  @Attribute(primaryKey = true)  
  16.  private Key key;  
  17.   
  18.  @Attribute(version = true)  
  19.  private Long version;  
  20.   
  21.  private String nickname;  
  22.   
  23.  private String email;  
  24.   
  25.  /** 
  26.   * Returns the key. 
  27.   *  
  28.   * @return the key 
  29.   */  
  30.  public Key getKey() {  
  31.   return key;  
  32.  }  
  33.   
  34.  /** 
  35.   * Sets the key. 
  36.   *  
  37.   * @param key the key 
  38.   */  
  39.  public void setKey(Key key) {  
  40.   this.key = key;  
  41.  }  
  42.   
  43.  /** 
  44.   * Returns the version. 
  45.   *  
  46.   * @return the version 
  47.   */  
  48.  public Long getVersion() {  
  49.   return version;  
  50.  }  
  51.   
  52.  /** 
  53.   * Sets the version. 
  54.   *  
  55.   * @param version the version 
  56.   */  
  57.  public void setVersion(Long version) {  
  58.   this.version = version;  
  59.  }  
  60.   
  61.  public String getNickname() {  
  62.   return nickname;  
  63.  }  
  64.   
  65.  public void setNickname(String x_nickname) {  
  66.   nickname = x_nickname;  
  67.  }  
  68.   
  69.  public String getEmail() {  
  70.   return email;  
  71.  }  
  72.   
  73.  public void setEmail(String x_email) {  
  74.   email = x_email;  
  75.  }  
  76.   
  77.  @Override  
  78.  public int hashCode() {  
  79.   final int prime = 31;  
  80.   int result = 1;  
  81.   result = prime * result + ((key == null) ? 0 : key.hashCode());  
  82.   return result;  
  83.  }  
  84.   
  85.  @Override  
  86.  public boolean equals(Object obj) {  
  87.   if (this == obj) {  
  88.    return true;  
  89.   }  
  90.   if (obj == null) {  
  91.    return false;  
  92.   }  
  93.   if (getClass() != obj.getClass()) {  
  94.    return false;  
  95.   }  
  96.   Account other = (Account) obj;  
  97.   if (key == null) {  
  98.    if (other.key != null) {  
  99.     return false;  
  100.    }  
  101.   } else if (!key.equals(other.key)) {  
  102.    return false;  
  103.   }  
  104.   return true;  
  105.  }  
  106. }  
Slim3プラグインのantから「gen-model」を選択して、自動生成されたソースをもとにしています。
追加部分は「nickname」と「email」の変数と、そのgetter・setterだけです。
jspのソースコード
1./WEB-INF/content/sample/index.jsp
  1. <%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%>  
  2. <%@ taglib uri="/struts-tags" prefix="s" %>  
  3.   
  4. <s:form>  
  5.  <s:textfield label="ニックネーム" name="nickname"></s:textfield>  
  6.  <s:textfield label="Email" name="email"></s:textfield>  
  7.  <s:submit action="regist"></s:submit>  
  8. </s:form>  
  9.    
  10.   
  11.  <s:a action="show">表示</s:a>  
2./WEB-INF/content/sample/show.jsp
  1. <%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%>  
  2. <%@ taglib uri="/struts-tags" prefix="s" %>  
  3.   
  4. <s:iterator value="%{getAccounts()}">  
  5.   </s:iterator><table border="1">  
  6.  <tbody>  
  7. <tr><th>ニックネーム</th><th>Email</th></tr>  
  8.   
  9. <tr>  
  10.    <td><s:property value="%{getNickname()}"></s:property></td>  
  11.    <td><s:property value="%{getEmail()}"></s:property></td>  
  12.   </tr>  
  13. </tbody></table>  
  14. <s:a action="index">戻る</s:a>  

以上で実装は完了です。

ここまで書いておいて、言ってしまうのですが、GlobalTransactionのインスタンスが直に注入されるのは気持ち悪いです。無理にSpringを使うことは無いと思い直しました。さらに、Springだけが原因かは調べていませんが、spin-upの時間もかなり掛かっています。

実行してみる
折角なので、動かしてみます。

Transactionは上手く機能しました。画像ではお見せできていませんが、例外が発生した場合は、ちゃんとrollbackしてくれています。

なんとかNo-configurationで書けたのですが、この方法を続けるにはDIを軽量化する必要があるのかなぁ...と思ってみたりみなかったり。

近いうちに、GWTとStruts2の連携についても書ければいいかな、なんて考えています。

0 件のコメント:

コメントを投稿