With a single step

~千里の道も一歩からと信じたいノート~

繰り返し

今日は繰り返しを学ぶ。
例のごとく、SAStruts本家のサイトは当てにしないφ(・ω・ )

ソース

index.jsp
<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Foreach</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Foreach</h1>


<table border="1">
<c:forEach var="m" varStatus="s" items="${mapItems}">
<tr style="background-color:${s.index % 2 == 0 ? 'pink' : 'yellow'}">
<td>${f:h(m.id)}</td>
<td>${f:h(m.name)}</td>
<td><s:link href="result/${m.id}">結果ページへ</s:link></td>
</tr>
</c:forEach>
</table>

</body>
</html>
result.jsp
<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Foreach result</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Foreach result</h1>

id: ${f:h(id)}
</body>
</html>
ForeachAction.java
package tutorial.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

import tutorial.form.ForeachForm;

public class ForeachAction {

	public List<Map<String, Object>> mapItems = new ArrayList<Map<String, Object>>();

	@ActionForm
	@Resource
	protected ForeachForm foreachForm;

	@Execute(validator = false)
	public String index() {
		for (int i = 0; i < 10; i++) {
			Map<String, Object> m = new HashMap<String, Object>();
			m.put("id", i);
			m.put("name", "name" + i);
			mapItems.add(m);
		}
		return "index.jsp";
	}

	@Execute(validator = false, urlPattern = "result/{id}")
	public String result() {
		return "result.jsp";
	}
}
ForeachForm.java
package tutorial.form;

public class ForeachForm {

	public String id;
}

ポイント

・c:forEach
・s:link
・@Execute urlPattern属性

c:forEach

struts.wasureppoi.com
なるほどね、jspでfor文のように使う場合のタグなのね(*´ω`*)

SAStruts/JSP [俺の基地]
まぁ、これは容易に想像がつくけど、確認できて良かった。
コンテキストパスからの指定が可能なのね。

@Execute urlPattern属性

SAStruts/Action/URLとのマッピング [俺の基地]
そっか!普段はinputタグのname属性次第で、actionの中の動作するメソッドが決まるけど、urlPatternを指定することで、特定のURLを任意のメソッドで処理できるわけね。

セッションスコープのアクションフォーム

今日はSAStrutsチュートリアルのセッションスコープを学ぶ。
。。。( ̄△ ̄;)エッ・・?
本家のサイトに説明ないのね。。。

sastruts.seasar.org

ということで、本家のサイトを当てにするのはやめる

ソース

index.jsp
<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Session index</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Session index</h1>
<html:errors/>
<s:form>
First:<html:text property="first"/><br />
<input type="submit" name="goSecond" value="Secondへ"/>
</s:form>
</body>
</html>
second.jsp
<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Session second</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Session second</h1>

<html:errors/>
<s:form>
<table>
<tr><td>First</td><td>${f:h(first)}</td></tr>
<tr><td>Second</td><td><html:text property="second"/></td></tr>
</table>
<input type="submit" name="goThird" value="Thirdへ"/>
<input type="submit" name="index" value="戻る"/>
</s:form>
</body>
</html>
third.jsp
<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Session third</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Session third</h1>

<s:form>
<table>
<tr><td>First</td><td>${f:h(first)}</td></tr>
<tr><td>Second</td><td>${f:h(second)}</td></tr>
</table><br />
<input type="submit" name="backSecond" value="戻る"/>
<input type="submit" name="clear" value="クリアして最初の画面へ"/>
</s:form>
</body>
</html>
SessionAction.java
package tutorial.action;

import javax.annotation.Resource;

import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

import tutorial.form.SessionForm;

public class SessionAction {

	@ActionForm
	@Resource
	protected SessionForm sessionForm;

	@Execute(validator = false)
	public String index() {
		return "index.jsp";
	}

	@Execute(input = "index.jsp")
	public String goSecond() {
	    return "second.jsp";
	}

	@Execute(input = "second.jsp")
	public String goThird() {
	    return "third.jsp";
	}

	@Execute(validator = false)
	public String backSecond() {
		return "second.jsp";
	}

	@Execute(validator = false, removeActionForm = true)
	public String clear() {
		return "index.jsp";
	}
}
SessionForm.java
package tutorial.form;

import java.io.Serializable;

import org.seasar.framework.container.annotation.tiger.Component;
import org.seasar.framework.container.annotation.tiger.InstanceType;
import org.seasar.struts.annotation.Required;

@Component(instance = InstanceType.SESSION)
public class SessionForm implements Serializable {

	private static final long serialVersionUID = 1L;

	@Required
	public String first;

	@Required(target = "goThird")
	public String second;
}

ポイント

・${}
・f:h()
・@Component(instance = InstanceType.SESSION)
・removeActionForm属性
・implements Serializable
・private static final long serialVersionUID = 1L;
・@Resouse
・protected

${}

これに関しては、セッションスコープに登録したオブジェクトのフィールドを参照しているのわかるけど、
「名前何だっけ?」
状態だったので、振り返る。
qiita.com

f:h()

SAStruts 入門
なるほど、HTMLエスケープを行うためね(。 ・ω・))フムフム
エスケープって何(゚Д゚ll)???
viral-community.com
あ~、サニタイジングのことね( ̄▽ ̄)
ただ、頭では理解しているつもりだけど、サニタイジングしないと実際にどうなるかは試したこと無い。やってみよう。

f:h()使用の場合(サニタイジングしている場合)

ボタン押下前
f:id:who_is_unfair:20160702214650p:plain
ボタン押下後
f:id:who_is_unfair:20160702215416p:plain
入力内容が正常に表示されていることがわかる。
念のため、Chromeの開発ツールを確認。
f:id:who_is_unfair:20160702215521p:plain
正常ですね。

f:h()未使用の場合(サニタイジングしない場合)

ボタン押下前
f:id:who_is_unfair:20160702214650p:plain
ボタン押下後
f:id:who_is_unfair:20160702215621p:plain
なんかおかしな事になっとる。
Chromeの開発ツールを確認。
f:id:who_is_unfair:20160702220413p:plain
やはり、異常事態発生。
タグが埋め込まれてる。
サニタイジングの本来の目的とは違う検証だが、
これだけでも、サニタイジングすることが
大切であることを確認できた。

@Component(instance = InstanceType.SESSION)

d.hatena.ne.jp
ActionFormのスコープをデフォルトのrequestから、sessionに変更したい場合
に利用するのね。

removeActionForm属性

d.hatena.ne.jp
セッションからActionFormを削除する場合に利用するのね。

implements Serializable

シリアライズ : kei@sodan
正直、チンブンカンプンだったため、非常に勉強になった。
シリアライズって内部的にどんなことをしてるの?
→メモリ上のオブジェクトをバイト列 (ストリーム) にする
そもそも何のためにやってるの?
→、ネットワークを通じて離れたマシンとデータをやりとりする時や、データをファイルに保存する時etc

private static final long serialVersionUID = 1L;

d.hatena.ne.jp
これに関しては、もう少し勉強する必要がありそう。
役割は理解できたが、コメント者の情報が気になる。

@Resouse

tomame0se.blog.shinobi.jp
わかったような、わからないような、DI対象のものね。。。(´・ω・`)
dev.classmethod.jp
Springの話だが、これが一番DIについて理解しやすい気がする^_^

protected

d.hatena.ne.jp
なぜ、SessionFormがprotectedなのか調べてみたら、
どうも、DI用のフィールドは、protectedにして、@Resourceをつけることが推奨らしい。

SAstrutsのf:url()の意味

なんとなくで理解していたf:url()の意味について、備忘録として振り返る。
sastruts.seasar.org
お、お~。。。
まぁ、理解はできるけど、具体例ないのね。。。

参考サイト

f:url()の使用方法の具体例
SAStruts 入門 f:urlサンプル

コンテキストルートってどこで設定してるんだっけ?
contextpath.zealseeds.com

学習点

f:url()の使用方法に関して理解できた。
それよりも今回の学習で大きかったのは、
「コンテキストルート」や「コンテキストパス」
というフレーズで覚えていた自分を発見できたこと。
「そもそもコンテキストって何よ?」
と聞かれると上手く答えられなかった。

感じたこと

今後、月一で帰社することで、Java研修生に教える機会が増えていく。
人に対して、説明に困りそうなことを1つずつ潰していこうと思う。

未来への気付き

・自社名を入れた基本技術書を出版してみたい

クライアントサイドのバリデート

今日はSAStrutsチュートリアルを使用して、クライアントサイドのバリデートを学ぶ。
JavaScriptを使用して、バリデートエラーを出力するらしい。
仕組みを理解するため、チュートリアルの説明を見てみる。。。
sastruts.seasar.org
ようわからんわ!
サイトに掲載されているチュートリアルの説明とソースが一致してないし!
どうなっとるんじゃ!!
ということで、本家のサイトは当てにせず、ソースを紐解いていく。

ソース

index.jsp
<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>Tutorial: Client Validator</title>
<link rel="stylesheet" type="text/css" href="${f:url('/css/sa.css')}" />
</head>
<body>

<h1>Tutorial: Client Validator</h1>

<html:errors/>

<s:form>
	<table>
		<tr><td>aaa</td><td><html:text property="aaa"/></td></tr>
		<tr><td>bbb</td><td><html:text property="bbb"/></td></tr>
	</table>
	<s:submit property="submit" clientValidate="true">aaaが必須</s:submit>
	<s:submit property="submit2" clientValidate="true">bbbが必須</s:submit>
</s:form>
</body>
</html>
ClientValidatorAction.java
package tutorial.action;

import javax.annotation.Resource;

import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;

import tutorial.form.ClientValidatorForm;

public class ClientValidatorAction {

	@ActionForm
	@Resource
	protected ClientValidatorForm clientValidatorForm;

	@Execute(validator = false)
	public String index() {
		return "index.jsp";
	}

	@Execute(input = "index.jsp")
	public String submit() {
		return "index.jsp";
	}

	@Execute(input = "index.jsp")
	public String submit2() {
		return "index.jsp";
	}
}
ClientValidatorForm.java
package tutorial.form;

import org.seasar.struts.annotation.Required;

public class ClientValidatorForm {

	@Required(target = "submit")
	public String aaa;

	@Required(target = "submit2")
	public String bbb;
}

今日の初めて

・html:javascript タグ

・s:submit タグ

学習点

どうやらs:sbumitタグのclientValidate属性をtrueにすることで、普段はhtml:errorsタグを使用した箇所に出力されるバリデートエラーの内容を、JavaScriptのアラート表示的に出力できるらしい。
これがクライアントサイドでのバリデートを行うかどうかのトリガーになる模様。
ただしトリガーを指定しても、html:javascriptタグを指定していないと、普段通りの赤文字でのバリデートエラーが表示される。
html:javascriptタグを指定することで初めて、アラート表示でバリデートエラーの内容をアラート的に表示できる。

まとめ

・s:sbumitタグclientValidate属性の指定とhtml:javascriptタグはセットで使用する。
・s:sbumitタグclientValidate属性はクライアントサイドのバリデートのトリガー。
・html:javascriptタグを指定しないと、アラート表示されない。