CodeZine(コードジン)

特集ページ一覧

Struts 2入門(8)~Struts2で構築するToDoアプリケーション~

作りながら学ぶJavaアプリケーションフレームワーク (8)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2009/08/24 14:00
目次

Actionメソッドの処理

 では、画面遷移に従って、それぞれのActionメソッドを見ていきましょう。まずは、ログイン処理のActionです。

 未ログイン時には、addActionErrorで何らかのメッセージが登録されていますので、Actionメソッドの処理はスキップされ、login.jspにて、ユーザーIDとパスワードを入力するフォームが表示されます。

[リスト5]login.jspの一部
<s:actionerror />
<s:form action="login" >
<s:textfield label="ユーザーID" name="userid"  />
<s:password label="パスワード" name="password" />
<s:submit value="ログイン" />
</s:form>

 ログインボタンにて、loginアクションがsubmitされます。

ログイン処理

 ToDoLoginActionクラスで、loginアクションを定義しています。

[リスト6]ToDoLoginAction.javaの一部
@Action("/login")
public String excute() throws Exception {

    LoginDao login = new LoginDao();

    // DBへ問い合わせ
    if (login.confirm(this.user.getUserid(), this.user.getPassword())) {
        this.user.setUsername(login.getUsername());
        this.user.setState(1); // ログイン状態に更新
    }
    else {
        addActionError("ユーザーIDの登録がないか、パスワードが異なっています。");
        this.user.setPassword("");
        return "input";
    }
    return "todo";
}

 フィールドのuserが、Modelオブジェクトで、フォームから入力された値がセットされています。

 LoginDaoクラスが実際のログイン処理を行うクラスです。confirmメソッドにユーザーIDとパスワードを渡して、データベースに登録されているかどうかを問い合わせます。

 LoginDaoクラスのconfirmメソッドは、次のようなコードになっています。

[リスト7]LoginDao.javaの一部
public boolean confirm(String userid, String password){

    try {
        User[] user = BaseDao.getInstance().getEntityManager().find(User.class,
                "userid=? and password=?",userid,password );

        if ( user.length>0 ){
            this.username = user[0].getUsername();
            return true;
        }
    }
    catch (SQLException e) {
        System.out.println(e.getMessage());
    }
    return false;
}

 ActiveObjectsのfindメソッドを用いて、データベースに問い合わせ、ユーザーIDとパスワードが登録されていれば、そのユーザーのユーザー名を取得しています。

ユーザーテーブル

 ここで、今回のアプリケーションのデータベースについて説明しておきましょう。データベースのEntityとしては、ユーザー情報と、ToDO情報の2つになります。それぞれを定義したインターフェイスは、次のようになります。

[リスト8]User.javaの一部
public interface User extends Entity {

    @Unique
    @Default("")
    public String getUserid();
    public void setUserid(String userid);

    @Default("")
    public String getPassword();
    public void setPassword(String password);

    @Default("")
    public String getUsername();
    public void setUsername(String username);
}

 ユーザーEntityの要素としては、ユーザーID、パスワード、ユーザー名となります。

 ToDoを格納するEntityは、次のTodoListです。要素は、ユーザーID、完了すべき日時、ToDO内容、有効無効フラグとなります。

[リスト9]TodoList.javaの一部
public interface TodoList extends Entity  {

    @Default("")
    public String getUserid();
    public void setUserid(String userid);

    @Default("CURRENT_TIMESTAMP")
    public Date getDeadline();
    public void setDeadline(Date deadline);

    @Default("")
    public String getTodo();
    public void setTodo(String todo);

    @Default("1")
    public int getValid();
    public void setValid(int valid);
}

 これら2つのインターフェイスの実装は、フレームワークのActiveObjectsが自動生成します。また、テーブルの作成も、この定義を用いて行うことができます。例えば、次のようなコードを実行すると、データベース上にテーブルが作成されます(あらかじめデータベースの作成は必要です)。

[リスト10]Migrate.javaの一部
EntityManager manager =
    new EntityManager("jdbc:mysql://localhost/todo", "root", "wings");

// テーブル作成
manager.migrate(TodoList.class, User.class);

 ローカルホストのtodoデータベースに、root/wingsにて接続し、migrateメソッドにて、インターフェイス定義にしたがったテーブルを作成します。

Actionのchain

 ログイン処理の説明に戻りましょう。データベースにユーザーの登録があることが確認できれば、状態をログイン済みに更新し、Result値の"todo"を返します。"todo"の遷移先は、Resultアノテーションのlocation属性でtodoアクションを指定しています。

@Result(name = "todo", location = "todo", type = "chain")

 "chain"は、アクションからアクションに遷移する場合に使用します。

 なお、Conventionプラグインのマニュアルには、同じパッケージ内であれば、Result値の指定のみで、chain遷移できると書いてあります。ところが指定どおりに記述しても、うまく動作しませんでした(同じActionクラス内のメソッドには遷移できます)。そのため、ここではResultアノテーションで指定しています。

todoアクション

 ログインから遷移したtodoアクション(ToDoActionクラスで定義)の目的は、メイン画面の表示です。Actionメソッドのコードは、単にResult値の"success"を返すだけで、直ちに、次のlist.jspのビュー表示となります。このように書くと、todoアクションに遷移しなくても、ログインのResultで、list.jspを指定すればいいように思えます。しかし、それではうまくいかない箇所がlist.jspにはあるのです。

 list.jspでは、2つのフォームを定義しています。まず最初は、ToDoメッセージの追加用です。

[リスト11]list.jspの一部
<s:form action="entryexec" >
<s:textfield name="todoStr" label="ToDo" size="50"/>
<s:submit value="Add TODO"/>
</s:form>
<s:actionmessage  />

 Todoメッセージの追加処理は、特に問題ないでしょう。submitにて、entryexecアクションを呼び出しています。entryexecアクションのコードは、次のようになります。

[リスト12]ToDoAction.javaの一部
private String todoStr;     // ToDo追加データ用

// ToDo追加
@Action("/entryexec")
public String entryexec() throws Exception {

    // 入力なしの場合は、何もしない
    if ( this.getTodoStr()==null || this.getTodoStr().length()==0 )
        return "success";

    // バリデーション
    if (this.getTodoStr().length()>80) {
        addActionMessage("文字数オーバーです");
        return "success";
    }

    // 日本語文字変換(Struts2の暫定バグ対応)
    this.setTodoStr( FixString.encoding(this.getTodoStr()));

    // DB登録
    TodoDao todo = new TodoDao();
    todo.entry( this.user.getUserid(), this.getTodoStr() );
    this.setTodoStr("");

    return "success";
}

 データベースへの登録は、次のTodoDaoクラスのentryメソッドで行います。

[リスト13]TodoDao.javaの一部
public boolean entry(String userid, String str){

    try {
        TodoList todo = BaseDao.getInstance().getEntityManager().create(TodoList.class);

        todo.setTodo(str);      // ユーザーIDのセット
        todo.setUserid(userid); // メッセージのセット

        todo.save();

        return true;

    } catch (SQLException e) {
        System.out.println(e.getMessage());
    }
    return false;
}

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:作りながら学ぶJavaアプリケーションフレームワーク

もっと読む

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 高江 賢(タカエ ケン)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5