goo blog サービス終了のお知らせ 

Psalm

プログラマ向け技術メモ

struts-tilesを使って、includeする。

2008-09-04 11:35:15 | Struts
Tilesを使うと、サイトの部品の使いまわしができる。
・・・そこまで複雑なサイトを作ることはないだろうけど。
うちはweb屋さんじゃないから。
一応、便利そうなので書いておく。

tiles-def.xmlを書く。

<definition name="name" path="/pages/header.jsp">
</definition>

struts-config.xmlにプラグインを設定。

<plug-in className="org.apache.struts.tiles.TilesPlugin">
<set-property property="moduleAware" value="false" />
<set-property property="definitions-debug" value="0" />
<set-property property="definitions-parser-details" value="0" />
<set-property property="definitions-parser-validate" value="false" />
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
</plug-in>

JSPにタグを書く。

<tiles:insert definition="header" flush="false"/>

includeと何処が違うんじゃ!と起こられそうなソースだ。
が、まあ、実は色々なことができるらしい。
暇があったら調べてみようと思う。

フォームで送信された日本語の文字化け対策

2008-09-04 11:25:14 | Struts
Strutsは、エンコード方式の情報を得る前にリクエストデータ情報を
beanに格納してしまうので、JSPとサーブレットでエンコードを
設定していても文字化けが発生する。
ので、Filterを使って回避する。

/**
* 日本語エンコードフィルター
*
*/
public class EncodingFilter implements Filter {

/** エンコード */
protected String encoding = null;

/** filterConfig */
protected FilterConfig filterConfig = null;


/**
* doFilter
*
* @param request 処理している Servlet リクエスト
* @param response 処理している Servlet レスポンス
* @param chain FilterChain
* @throws IOException 入出力例外
* @throws ServletException サーブレット例外
*/
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {

String encoding = filterConfig.getInitParameter("encoding");

if (encoding != null) {
request.setCharacterEncoding(encoding);
}

// Pass control on to the next filter
chain.doFilter(request, response);
}

/**
* init
*
* @param filterConfig フィルタ設定のためのオブジェクト
* @throws ServletException サーブレット例外
*/
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;

}

/**
* destroy
*
*/
public void destroy() {
this.encoding = null;
this.filterConfig = null;

}
}

で、web.xmlに

<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>util.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>encodingFilter</filter-name>
<servlet-name>action</servlet-name>
</filter-mapping>

を追加する。

タグライブラリ拡張

2008-09-03 18:47:51 | Struts
Strutsのhtmlライブラリの<html:textarea>にはwrap属性が
用意されていない。
ということで、ライブラリを拡張してwrap属性を装備することにした。
手順は意外と簡単。
まず、org.apache.struts.taglib.html.TextareaTagをextendsした
オリジナルのtextareaクラスを作成して、wrap変数を持たせて
変数を有効にする。

public class ExTextareaTag extends org.apache.struts.taglib.html.TextareaTag {

/** wrap属性 */
private String wrap;

/**
* wrap属性を取得
* @return the wrap
*/
public String getWrap() {
return wrap;
}

/**
* wrap属性を設定
* @param wrap the wrap to set
*/
public void setWrap(String wrap) {
this.wrap = wrap;
}

/**
* wrap属性を有効とする
*/
@Override
protected void prepareOtherAttributes(StringBuffer handlers) {
prepareAttribute(handlers, "wrap", getWrap());
}
}

さて、次はstruts-html.tldの拡張。
textareaのタグを探してコピペ。nameとtagclassを変更、
attributeにwrapを追加。
ちなみに、requiredにtrueを設定すると属性が必須になる。
wrap属性は必須ではないのでfalseを設定。
rtexprvalueは、属性値をJSPのスクリプトで指定できるか。
一応、trueにしておく。

<tag>
<name>extextarea</name>
<tagclass>util.ExTextareaTag</tagclass>
<attribute>
<name>wrap</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
以降はtextareaと同じ

最後に実際のJSPの指定方法。
htmlタグの名前にextextareaを指定するだけ。

<html:extextarea property="xxxxx" rows="5" cols="54" wrap="phycical" />

完成!

Struts validatorとvalidateメソッドを併用する

2008-09-01 17:25:58 | Struts
両方使おうとしたが、Struts validatorが実行されない。
何故かと思ったら、varidateメソッドの中でStruts validatorの
実行結果を取得していないのだった・・・
Strutsの仕組みを理解していればすぐに分かるはずなのだが。
付け焼刃はつらい。

varidateメソッドで以下を実行すべし。

// Validator の検証結果を取得
ActionErrors errors = super.validate(mapping, req);

メッセージリソースの使い方

2008-08-28 14:30:18 | Struts
キー org.apache.struts.action.MESSAGE に対するメッセージリソースが見つかりません

そのまんま、JSPで指定したキーがない。
チェックするべき点はいくつかある。

1、WEB-INF/classesの下にメッセージリソースファイルはあるか
 Eclipseくんが親切にもclean upしてくれてることがある。
 プロジェクトのクリーンをした場合は要チェック。

2、struts-config.xmlの記述
 こんな感じ↓
 <message-resources parameter="ApplicationMessageResources" key="messages" />
 意外と間違いやすいのが「parameter」はファイル名ではないという点。
 ここには拡張子はいらない。
 classesにディレクトリを掘ってる場合はディレクトリのパスから書くこと。
 keyを書かない場合はデフォルトが使われるらしいけど、動かなかった。

3、JSPの記述は合ってる?
 JSPから直接メッセージリソースを読み出すときは
 <bean:message bundle="messages" key="key名" />

 ActionMessagesを使ったときは
 <html:messages id="msg" bundle="messages" message="true">
  <bean:write name="msg" ignore="true"/>
 </html:messages>

 ActionMessagesのときは、keyを指定しない。
 ・・・微妙。
 struts-configでkeyを指定した場合は、bundle必須。

日本語ファイル文字化け

2008-08-28 14:27:32 | Struts
日本語ファイルダウンロードの文字化け問題。
IE ONLY。
簡単なのでずばり解決方法。

fileName = new String(fileName.getBytes("Shift_JIS"), "ISO-8859-1");

IEはUTF-8のファイル名を勝手にShift_JISに変換するので
予めShift_JISで送ればOK。

Validatorが動かない

2008-08-28 14:10:04 | Struts
解決した。
実に馬鹿馬鹿しい理由だった。
validation.xmlで設定したメッセージが見つからないためだった。
もともと、struts-config.xmlには
<message-resources parameter="ApplicationMessageResources" key="messages" />
を指定していたのだが、ここにkeyを指定しているのが原因だったらしい。
validation.xmlに
<msg name="required" key="error.txUserId.required" />
という指定をすると、デフォルトのリソースからkeyを探してしまうのだ。
当たり前だ。
だって、リソースファイルの指定してないもん。
validation.xmlでリソースファイルの指定をすれば良いのだろうが
もう調べるのも疲れたので、validator用にデフォルトのリソースを
用意することにした。

さて、めでたくvalidatorは動いたのだが、予想していた問題が発生した。
Dispatchアクションを使って1つのアクションに複数の処理を
書いていると、Validateして欲しくない処理にまでValidateが
走ってしまうのだ。
ログアウトしてログイン画面を表示すると「ユーザIDを入力してください」って
ありえん。笑
はて、どうしてくれようか。
Mappingで無理矢理Validateありなしを分けてもいいんだけど
なんかスマートじゃない気がする。
普通はどうやるんだろう?

Validatorプラグインありでのtomcat起動エラー

2008-08-26 19:29:01 | Struts
javax.servlet.UnavailableException: org.apache.commons.validator.ValidatorResources.<init>([Ljava/net/URL;)V

Strutsバージョン1.2.9なのに1.3系のjarをlibに入れてた。
struts-XXX.jarは全部1.3系。
1.2系にはstruts.jarだけあれば良い。
・・・私のバカ。

libからjarを削除してめでたくtomcat起動成功。
が、今度はvaridatorが効かない。
現在原因究明中。
考えられることは全部チェックしたのだが。
参考URL:http://kamakura.cool.ne.jp/oppama/ssja/struts-shoot.html

validation.xmlによるバリデーションが効かない
・struts-config.xmlのplug-in要素でValidationプラグインの設定を書いていない。
・validator-rules.xml、validation.xmlが/WEB-INFに存在しない。
・struts-config.xmlのActionの設定でvalidate="false"になっている。
・Form BeanがActionFormのサブクラスになっている。 ValidatorFormのサブクラスにしないとバリデーションは動作しません。
・Form BeanがDynaActionFormのインスタンスになっている。 DynaValidatorFormのインスタンスにしないとバリデーションは動作しません。
・struts-config.xmlのActionの設定で、name属性を書き、attribute属性は省略している場合に、 nameの値と同じ名前のform要素がvalidation.xmlに存在しない。
・struts-config.xmlのActionの設定で、name属性とattribute属性の値が異なる場合に、 attributeの値と同じ名前のform要素がvalidation.xmlに存在しない。
・ValidatorForm#getValidationKey()をオーバーライドしているとき、そのメソッドが返す値と同じ名前のform要素がvalidation.xmlに存在しない。
・struts.jar、commons-validator.jar、validator-rules.xmlのバージョンが合っていない (ログを注意深く見るとエラーになっているはず。必ず同じstruts配布から展開したものを使いましょう)
・message-resourcesの指定内容に相当致命的なエラーがあり、メッセージリソースの初期化がされていない (paramter属性にカンマや空白が含まれている等。ログには何も出ませんが)
・web.xmlに、struts-config.xmlをカンマで区切って複数指定しているとき、それぞれのstruts-config.xmlに別々の controller、message-resources、plug-in要素のいずれかを書いていて、その内容が違う。
⇒controller、message-resources、plug-inは"static"な設定要素で、別々の内容を二度以上書くと設定が効かなくなります。完全に同じ内容を2個所以上に書くのはOKみたいです。

上記項目はチェック済み。
何か見落としがあるのだろうか・・・

Tomcatの起動でエラー

2008-08-26 14:20:24 | Struts
tomcat単体では正常に起動するがプロジェクトを読み込ませると
どえらい量のエラーログを吐く。
ほとんどが以下のログ。

致命的: Parse Error at line 10 column 9: cvc-elt.1: Cannot find the declaration of element 'taglib'.
org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'taglib'.

DTDが見つからないんだか、書き方が悪いんだか、
バージョンに不整合があるんだか、結局のところ良く分からなかった。
とりえあず、できることを片端から試してみたところ直ってしまった・・・
検索してみるとEclipseを使っていると頻繁に遭遇するエラーらしい。
J2EEに対応していないプラグインだとか、web.xmlの宣言が悪いとか
情報は錯綜していて決め手に欠ける。

以下、試したこと。
・Tomcat再インストール(関係なさげ)
・EclipseのTomcat設定クリア(クラスパス辺りがあやしい)
・Eclipseのネットワーク設定(通信にプロキシを設定)
・Eclipseプロジェクトの作り直し
・似たようなプロジェクトの削除
・web.xmlの宣言部書き直し

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
version="2.4">



<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

に修正。
しかし、前者でも以前は動いていたので問題はないように思える。
ちなみにソースはすべてVSSで管理しており、プロジェクトメンバは
同じ設定ファイルを使用しているにも関わらず、この症状が出たのは
私だけだった。
ということは、問題はおそらくローカルの設定だろう。
疑うべきはやはりEclipseのtomcat周りか?