2009-07-27

SAStrutsでエラーメッセージを設定してエラー画面に遷移する方法 2

前回のSAStrutsでエラーメッセージを設定してエラー画面に遷移する方法だと記述量が多いので扱いにくい。
static importや可変長パラメータを使用して書きやすくしてみた。

ユーティリティクラス
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

public class AppUtil {
public static ActionMessages getErrors(String msgKey, String ...args) {
ActionMessages errors = new ActionMessages();
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage(msgKey, args));
return errors;
}
}


使用クラスメソッド(ここではアクションクラスのメソッド)
import static org.seasar.struts.util.ActionMessagesUtil.*;
import static org.seasar.struts.util.MessageResourcesUtil.*;
import org.seasar.struts.util.RequestUtil;
import static sample.AppUtil.*;
・・・
Integer id;
try {
id = Integer.parseInt(form.id);
} catch(NumberFormatException e) {
addErrors(RequestUtil.getRequest(),
getErrors("errors.integer", getMessage("labels.workstyleId")));
return "/error/";
}
・・・

2009-07-26

SAStrutsで時間の条件チェック

開始時間と終了時間の条件チェックを行う。
Validwhenで挑戦してみたが、できなかったのでメソッドを作成。
ミソは終了時間の最大を00:00としているところ。
画面表示時に24:00に書きかえる。

import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.seasar.framework.beans.converter.TimeConverter;

public ActionMessages validate() {
ActionMessages errors = new ActionMessages();
if (!endTime.equals("00:00")) {
TimeConverter timeConverter = new TimeConverter("HH:mm");
java.sql.Time startTimeValue
= (java.sql.Time) timeConverter.getAsObject(startTime);
java.sql.Time endTimeValue
= (java.sql.Time) timeConverter.getAsObject(endTime);
if (!startTimeValue.before(endTimeValue)) {
errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
"errors.startTimeBeforeEndTime"));
}
}
return errors;
}

2009-07-20

s2jdbcでタイプセーフなクエリを実現。たとえば外部参照データで条件指定。

エンティティクラスを作成しておけば、s2jdbc-genでエンティティ参照用の*Namesクラスを自動作成できる。
target=gen-ddl(default)

これを使用して文字列に頼らず、タイプセーフなクエリを作成できる。

使用するNamesクラスをstatic importする。
これはXxxServiceでは、対応するXxxNamesがよい。

where句を構成するため、Operationsクラスもstatic importする。

結合したテーブルの情報を条件にしたいときはinnerJoin等でまず結合する。
関連が1対多で多側を参照するときはinnerJoin(viewGroupList())などとする。
(1側ならinnerJoin(dept())などになる。)
多側のIDで絞り込みたいなら以下のようにする。
.where(viewGroupList().id(), viewId))

ポイントはDeptNames内のviewGroupList()を使用するってことだろう。

以下作成したサンプル
import static org.seasar.extension.jdbc.operation.Operations.*;
import static sastrutsSample.entity.DeptNames.*;

import sastrutsSample.entity.Dept;

public class DeptService extends AbstractService {

public List findByViewId(String viewId) {
return jdbcManager.from(Dept.class).innerJoin(viewGroupList())
.where(eq(viewGroupList().id(), viewId))
.getResultList();
}
}

SAStrutsでURLにパラメータを渡したい、できる限り全画面で。

セッションが切れても場合分けできるようにURLで区別したい要望に対応したいと考えている。

SAStrutsでURLにパラメータを含めたい時はよくスラッシュ区切りを使用する。
これだとGETでやりとりするときは問題ないが、POSTで送信すると、パラメータがうまく設定できない。
POST処理そのもののURLに追加はできないとしても、せめてPOSTで保存完了後の画面のためにパラメータを渡したい。

全画面のURLにパラメータを含めたいが、うまく設定できない場合はPOSTにパラメータを設定してそれを読むようにしたい。
下記のように、urlPatternの違うメソッドを2つ用意して同じ処理を実行させる。

@Execute(input = "edit.jsp", urlPattern = "update/{viewId}", redirect = true)
public String updateByViewId() {
return update();
}

@Execute(input = "edit.jsp", redirect = true)
public String update() {
...
return "/deptView/index/" + form.viewId;
}

SAStrutsでエラーメッセージを設定してエラー画面に遷移する方法

アプリケーションに設定しているメッセージリソースをActionで取得してエラー画面で読み出すようにしてみた。

Actionでは以下の記述を追加する。
エラー画面はErrorActionを作成して飛ばしている。
リソースを参照して文字置換を行っている。
"{0}"の部分はObjectに渡しているが今回はlabelsにしていたメッセージに置換した。


import org.apache.struts.action.ActionMessages;
import org.apache.struts.action.ActionMessage;
import org.seasar.struts.util.ActionMessagesUtil;
import org.seasar.struts.util.MessageResourcesUtil;
import org.seasar.struts.util.RequestUtil;


ActionMessages errors = new ActionMessages();
errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
"errors.required"
new Object[] { MessageResourcesUtil.getMessage("labels.viewId") }));
ActionMessagesUtil.addErrors(RequestUtil.getRequest(), errors);
return "/error/";

2009-07-17

JDBC Realm(アプリケーションごと個別指定)

JDBC Realmを設定してみた。

使いようによってはすごく便利。

テーブルはユーザーID,パスワードのテーブル、ユーザーID,ロール名のテーブルの2つを用意する。
ユーザーIDのカラム名は同じである必要がある。
ロール名は複数指定する場合、必要なだけレコードを追加する。

アプリケーションごとにRealmを指定する場合、Realm設定を<Context>の中に配置する。

<Realm className="org.apache.catalina.realm.JDBCRealm"
dataSourceName="jdbc/userdb"
userTable="users"
userNameCol="user_id"
userCredCol="password"
userRoleTable="role"
roleNameCol="role" />


*Tableにテーブル名を記載する。DB2の場合スキーマも合わせて指定する。
例:
userdbschema.user
userdbschema.role

Servletエンジンの認証であれば認証前のアクセスしていたURLに認証後アクセスする。
認証後のユーザーはHttpServletRequest#getRemoteUser()で取得する。
名前などの付加情報は認証後の最初に必要とされる処理で記述する。

SAStrutsであればボタンごとの権限チェックも簡単にできる。