ラベル struts2 の投稿を表示しています。 すべての投稿を表示
ラベル struts2 の投稿を表示しています。 すべての投稿を表示

2009年6月27日土曜日

struts2のResult Type

アクションクラスのアノテーションで指定する@Resultに指定するtypeですが以下のようなものがあります。

chain
別のActionクラスを呼び出します。urlは最初のアクション呼び出し時のままです。
redirect
指定したURLにリダイレクトします。urlはリダイレクト先に変わります。
redirectAction
指定したActionにリダイレクトします。urlは指定したActionのものに変わります。
他にも下記のようなタイプがいろいろあるようですが、使ってみてないんであまりわかってません。

dispatcher,freemarker,velocity,xslt,stream,plainText,tiles,jasper

大体みたまんまの感じのものだと思います。

dispatcherはjspを呼び出します。tilesはそーゆーフレームワークのようです。jasperは帳票フレームワーク?

2009年6月25日木曜日

Struts2 自作インターセプターでexcludeMethodsを有効にする。

インターセプターの自作で調べたことのメモ。

struts2関連でインターセプターを調べてるとstruts.xmlに

以下のようにparamのexcludeMethodsに書くとそのメソッド実行時はインターセプターは実行されないとあったので
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>


インターセプターを自作してこのような設定を書いてみたんですが、設定したメソッドの実行時にインターセプターが実行されてしまいました。

で、何が悪いのか調べてみたんですが、この設定を有効にするには、MethodFilterInterceptorを継承しないと駄目だということがわかりました。(試しに作ったインターセプターはAbstractInterceptorを継承してました。)

ですんで、MethodFilterInterceptorを継承して、doInterceptというメソッドに処理を記述すると上記の設定で実行しないメソッドの指定が有効になりました。

2009年6月10日水曜日

Struts2.1を使ってみる。単純な入力フォームの例

単純に表示するだけは出来たので、入力フォームから入力するような機能を試してみます。
環境はすでに用意してあるものを使います。

1 アクションクラス作成。

net.ukauka.lab.action.test2にHello2Action.javaを作成します。
package net.ukauka.lab.action.test2;

import org.apache.struts2.convention.annotation.ParentPackage;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.EmailValidator;
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;

@ParentPackage(value="default")

public class Hello2Action extends ActionSupport{

public String name;
public String email;

private static final long serialVersionUID = 1L;

public String execute() throws Exception {
return "input";
}

@Validations(requiredStrings=@RequiredStringValidator(fieldName="name",message="名前いれて"))
public String inputName() throws Exception {
return "ok";
}

@Validations(
requiredStrings=@RequiredStringValidator(fieldName="email",message="メールアドレスいれて"),
emails=@EmailValidator(fieldName="email",message="メールアドレスがおかしい")
)
public String inputEmail() throws Exception {
return "ok";
}

}

http://localhost:8080/app1/test2/hello2.action でアクセスします。

入力用にname,emailという変数をpublicで作成します。この変数に入力値が設定されます。
inputName,inputEmailというメソッドは入力実行時に呼び出されます。
今回は無意味に送信ボタンを二つ用意してそれぞれの動作がわかるようにしています。
@ParentPackage(value="default")
という記述は、どの設定を使用するかです。これを書いていないとデフォルトではstruts-defaultが使用されます。
後述のインターセプタ設定に関連するので必要です。

@Validations うんたらかんたらの部分はバリデーションの設定です。極力設定ファイルを書きたくないのでアノテーションで設定するようにしました。
メソッド毎に違うバリデーションを行いたいので、二つのメソッドで別のバリデーションを設定してあります。

2 jspを作成

入力用と表示用のビューを作成します。

入力用 test2/hello2-input.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>入力</title>
<style>
.errorMessage {
color:red;
}
.errorLabel {
color:red;
}

</style>
</head>
<body>
<h1>入力</h1>
<s:form>
<s:textfield label="名前" name="name" />
<s:textfield label="メールアドレス" name="email" />

<s:submit value="名前入力" method="inputName" />
<s:submit value="メールアドレス入力" method="inputEmail" />
</s:form>
</body>
</html>

入力フォームはstrutsタグを使うと楽です。基本は

s:formの中に書く入力用タグを配置するだけです。

s:formを指定するだけで、入力欄とかサブミットボタンとかは勝手にtableタグで適当に整形されて表示されます。

これはthemeを指定することでいろいろ変更できるようです。とりあえず勝手に整形されるのは困るって場合は<s:form theme="simple'>を指定すればいいです。デフォルトはtheme=xhtmlらしいです。他にもcssレイアウトやajaxを使うものとかあるようですが、面倒なのでデフォルトでやっときます。

見たまんまですが、s:submitでmethodを指定してますがこれが実行したいメソッドの名前になります。

cssでerrorMessage、errorLabelを指定してますが、これはエラー時に出力されるメッセージ用です。色でも変えておかないとわかりづらいです。

出力用 test2/hello2-ok.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>出力</title>
</head>
<body>
<h1>出力</h1>
名前:${name}<br/>
メールアドレス:${email}
<a href="hello2.action">戻る</a>
</body>
</html>

3 設定ファイル
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />

<package name="default" extends="struts-default">
<interceptors>
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception" />
<interceptor-ref name="alias" />
<interceptor-ref name="servletConfig" />
<interceptor-ref name="i18n" />
<interceptor-ref name="prepare" />
<interceptor-ref name="chain" />
<interceptor-ref name="debugging" />
<interceptor-ref name="profiling" />
<interceptor-ref name="scopedModelDriven" />
<interceptor-ref name="modelDriven" />
<interceptor-ref name="fileUpload" />
<interceptor-ref name="checkbox" />
<interceptor-ref name="staticParams" />
<interceptor-ref name="actionMappingParams" />
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
<param name="validateAnnotatedMethodOnly">true</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
</package>
</struts>

今回この設定を調べるのに結構時間食いましたw
アノテーションでメソッド毎にバリデーションを実行するのに、

<interceptor-ref name="validation">
<param name="validateAnnotatedMethodOnly">true</param>
</interceptor-ref>

validateAnnotatedMethodOnlyをtrueに設定する必要があるんですが、この方法がよくわかんなかったのです。

まぁ、わかってみると簡単なんですが、struts-defaultを継承したpackageを作成しinterceptor-stackのdefaultStackを上書きすればよかったです。

で、ここで指定しているpackageをアクションクラス側で指定しないとデフォルトのstruts-defaultが使用されてうまくいきません。(結構悩みました)

defaultStackはstruts-defaultの内容をそのままコピーしてもってきてvalidation部分だけ追加しました。いらなそうなインターセプターは削除しておいてもいいと思います。

4 実行

http://localhost:8080/app1/test2/hello2.action にアクセスすると入力画面が表示されます。
「名前入力」ボタンを押すと、名前欄のみチェックされて、問題なければ出力画面が表示されます。

「メールアドレス入力」も同様です。

二つのボタンで別々のバリデーションが働きます。

hello2Action#execute 実行

test2/hello2-input.jsp 表示

hello2Action#inputName 実行

test2/hello2-ok.jsp 表示

という流れになります。

2009年6月9日火曜日

Struts2.1を使ってみる。単純に表示するだけの例

http://struts.apache.org/2.1.2/index.html

struts2で検索すると、解説ページは出てくるんですが肝心のダウンロード先がすぐわからないんで、真っ先に書いておきますw
まず、本家のURLを提示してくれよ。解説はいいからさ。
現時点では2.1.6が最新のようですので、

http://struts.apache.org/download.cgi
こちらから
struts-2.1.6-all.zipをダウンロードします。
allなんでソースとかサンプルとかドキュメントとかいろいろ入ってると思います。

eclipseのwtpで一番単純な表示するだけの機能を作ってみました。

1 wtpの動的Webプロジェクトを作成。

とりあえずapp1という名前のプロジェクトを作成してみました。

2 必要ライブラリを配置。
app1/WebContent/WEB-INF/libにライブラリを配置します。解凍したファイルに入ってます。
とりあえ以下を入れてみます。今のところ使わなさそうなのも入ってますが。

commons-fileupload-1.2.1.jar
commons-loggin-1.0.4.jar
freemaker-2.3.13.jar
ognl-2.6.11.jar
struts2-convention-plugin-2.1.6.jar
struts2-core-2.1.6.jar
xwork-2.1.2.jar

ビルドパスの設定でこれらのライブラリを追加しておきます。

3 web.xmlの変更
app1/WebContent/WEB-INF/web.xmlを修正します。
以下を追加します。
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>

<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

struts2自体はfilterとして動くのでその設定ですね。
2.1からは
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

を使用するようなんですが、これ使うと日本語が文字化けしちゃうんですよね。無理やり文字化けしないようにも出来ないことはないですが面倒くさいのでorg.apache.struts2.dispatcher.FilterDispatcherを使ってます。2.1からは非推奨のようですが特段問題はありません。


4 struts.xmlの追加

設定の記述量が少なくなると言っても最低限の設定は必要ですので、struts.xmlを作成します。
app1/src/struts.xmlを作成します。中身はこんな感じです。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
   
<constant name="struts.devMode" value="false" />
</struts>

struts.enable.DynamicMethodInvocationはアクション名!メソッドという形式のURLでのメソッド実行を有効にするかどうか。
struts.devModeは開発モードでtrueの場合はデバック用のインターセプターとかが有効になるようです。

5 アクションクラスの作成

srcにnet.ukauka.lab.action.test.HelloAction.javaを作成します。
こんな感じです。
package net.ukauka.lab.action.test;

public class HelloAction {
public String message;

private static final long serialVersionUID = 1L;

public String execute() throws Exception {
this.message = "<strong>こんにちは!</strong>";
return "success";
}
}

これで
http://localhost:8080/app1/test/hello.action というURLへのアクセスでこのアクションが実行されるようになります。
で呼ばれます。

これはパッケージ名から判断されます。actionという部分の下のパッケージ名が対応します。

action.test.HelloActionなので/test/hello.actionになります。

アクションクラス自体はPOJOってやつです。特になにも継承したりしません。
このサンプルでは単純にmessageという変数に値を設定して、リターンコードを返すだけです。このリターンコードに対応したviewが表示されます。

6 ビューの作成

ビューはとりあえずjspで作成します。(他にもfreemakerとかvelocityとかのテンプレートも使えるようですがよく知らないので。)

app1/WebContent/WEB-INF/content/test/hello.jsp を作成します。

WEB-INF/content/test以下が参照されるのはアクションクラスのパッケージ構造に対応しています。

WEB-INF/content 以下からビュー用のファイルを探すのがデフォルトになっています。

まぁ、この辺は設定で変えられるようですがこの構造で覚えときゃいいかなと思ってます。

hello.jspは以下のような感じです。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<body>
<h1>単純に表示するだけ</h1>
1 <s:property value="message" /><br/>
2 ${message}
</body>
</html>

表示はs:propertyを使えば表示できます。これはhtmlエンコードをやってくれますんで、< を &lt;とかに変換してくれます。
${}の場合はそのまんま表示されます。

7 実行
サーバーを起動してhttp://localhost:8080/app1/test/hello.actionをブラウザで見てみると
<html>
<body>
<h1>単純に表示するだけ</h1>
1 &lt;strong&gt;こんにちは!&lt;/strong&gt;<br/>
2 <strong>こんにちは!</strong>
</body>
</html>

と表示されます。

hello.actionなのでhelloActionが実行されて、hello.jspが表示される。という流れになっています。アクションクラスでsuccessという文字コードを返してますがこいつで表示するビューを指定することが出来ます。ちょっとややこしいですが、ビューは以下のような感じで探すようです。

successがリターンコードの場合。

1 hello-success.jsp
2 hello.jsp
3 hello-success.vm
4 hello.vm
5 hello-success.ftl
6 hello.ftl

今回は1のファイルは用意されていないので2が採用されたってことになります。