FAQ

Requirement (Java6 to Java8)

use version 1.3.x

Requirement (Java11 or higher)

use version 1.4.x

servlet-apiに依存していますか?

いいえ。servlet-apiには依存していません。依存関係のページには servlet-apiがprovided(実行時に必要なもの)として表示されていますが、 これはoptionalであるという表示に注目してください。 SpringMVC用のViewクラスを使う場合にのみservlet-apiが必要になります。

対応しているxhtmlバージョン、タグ、属性

xhtml1.0-transitional(strictも可)およびXML構文で書かれたhtml5に対応しています。 html5の仕様は2011年5月現在の仕様に準拠します。

なお、xhtml1.0-transitionalに準拠しているということは、 xhtml1.0-strictなテンプレートでもよいということです。 xhtml1.0-strictはxhtml1.0-transitionalのsubsetだからです。

html5のdata-*やaria-*等の属性にも対応しています。

ただし、htmlタグそのものについてはxhtml1.0およびhtml5で規定されているタグのみ対応しています。 任意のオリジナルタグ、例えば <foo>bar</foo>のようなタグを テンプレートに書いてもmixer2はそれを削除します。

frame, frameset文書には対応していません

xhtml1-transitional と xhtml1-frameset は明確に異なる文書型です。 mixer2はframeタグやframesetタグに対応していませんので、 テンプレートにあってもそれを削除します。 <iframe>タグには対応しています。

正しいxhtmlを書いてください

mixer2は、テンプレートhtml文字列の読み込み(load≒unmarshal)時、 およびHtmlオブジェクトの文字出力(save≒marshal)時のそれぞれのフェーズで、 特にValidation(検証)をしていません。 したがって、xhtmlの文法的に間違ったタグであってもmarshalは完了します。 例えば、次のようなケースです。

テンプレート(抜粋):

<b> aaa <div>bbb</div> ccc </b>

mixer2でloadし、何もせずにsaveToString()した結果(抜粋):

<b>aaa   ccc</b>

インライン要素であるbタグに、ブロック要素であるdivタグを含めることは htmlの仕様に照らして明らかにNGです。mixer2はテンプレートのロード(unmarshal)の 段階でこれを無かったことにしてしまいます。警告も出しません。

また、次のようなケースもあります。

テンプレート(抜粋):

<div id="a">xxx</div>
<div id="a">yyy</div>

上のテンプレートはhtmlの仕様に照らして明らかにNGです。 ひとつのWebページ内に同じid属性を持つタグが複数存在できないからです。 しかしmixer2はこれについても何もしません。

mixer2でloadし、何もせずにsaveToString()した結果(抜粋):

<div id="a">xxx</div>
<div id="a">yyy</div>

このように、少なくともテンプレートを作成する際には、Webオーサリングツール (ex. Dreamweaver)のチェック機能やあるいはhtmllint等のツールを用いて ある程度の妥当性検証を行っておくことをおすすめします。

DOCTYPE宣言は削除されます

テンプレートの冒頭にどのようなDOCTYPE宣言があっても、mixer2はそれを無かったことにします。 JAXB-APIがテンプレートの解析するときにDOCTYPE宣言を発見すると、そのURIにhttpアクセスする ことがあり、大きなオーバーヘッドとなってしまうからです。

アプリケーションの最終的な出力にDOCTYPE宣言が必須であれば、mixer2による出力結果に対して 手動でDOCTYPE宣言の文字列を追加してください。

コメントは削除されます

<!-- コメント... -->
<!--[if IE]>
<link rel="stylesheet" href="layout_ie.css" type="text/css" />
<![endif]-->

テンプレート上にhtmlコメントがあっても、すべて削除されます。 これはJava6のJAXB-APIのUnmarshallerの仕様です。 ということは、 http://msdn.microsoft.com/en-us/library/ms537512 で 解説されているコンディショナルコメント(分岐条件コメント)も削除されてしまいます。

JavaScript

JavaScriptは、できるだけ外部ファイル化することをおすすめします。

テンプレート:

<script type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

mixer2による出力:

<script type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"> </script>

空白がひとつ入ってしまうのは仕様です。Mixer2Engine内部で使用しているtransformerが、 属性のみでコンテンツのないscriptタグを <script type="text/javascript" src="foo.js" /> のように 空要素にしてしまうのを防ぐためです。 (FireFox等では空要素のscriptタグは正常に作動しないことがあります)

JavaScript (Inline)

どうしてもxhtml内部にインラインでJavaScriptを書きたい場合には、 CDATAと//(コメントアウト)を組み合わせてテンプレートを書いてください。

<script type="text/javascript">
//<![CDATA[
var foo = 1;
var bar = 2;
if (foo > bar || foo < bar) {
    var bar = 3;
}
//]]></script>

output by mixer2:

<script type="text/javascript">
//<![CDATA[

var foo = 1;
var bar = 2;
if (foo > bar || foo < bar) {
    var bar = 3;
}

//]]>
</script>

IDREF(S) 属性 (例: labelタグのfor属性)

IDリファレンス(IDREF)型の属性へのアクセスは注意が必要です。 典型的なのが<label for="foo">のようなlabelタグです。 たとえば下記のようなテンプレートをロードしたとします。

<label id="barInputLabel" for="barInput">input bar:</label>
<input id="barInput" type="text" name="barInput" />

このとき、 html.getById("barInputLabel", Label.class).getFor() で得られるオブジェクトは、 "barInput"というStringではありません。 そのfor属性が示す文字列をid属性として持っているInputクラスのインスタンスです。 つまりid=barInputであるinputタグのオブジェクトです。

同様に、labelタグオブジェクトに新たにfor属性をセットする場合、 label.setFor("barInput") のようにStringを直接渡しても例外を発生してしまいます。 上のテンプレートの例で言えば、

Input barInput = html.getById("barInput", Input.class);
html.getById("barInputLabel", Label.class).setFor(barInput);

のように、そのlabelタグのfor属性が指し示すタグのオブジェクトそのものを setFor()メソッドの引数に渡す必要があります。

Thread safe

mixer2が提供するほとんどのクラスはスレッドセーフです。 スレッドセーフではないことが明白なクラスについては JavaDocに「スレッドセーフではありません」と書いてあります。

Mixer2Engineはシングルトンで

Mixer2Engine自体のインスタンス生成はかなりのオーバーヘッドがかかります。 アプリケーションの起動時にDIコンテナ等でsingletonとして コンポーネント登録してしまうことをお勧めします。

Security

Mixer2はセキュリティ面でも優れています。 例えば、<script>タグを作るには、テンプレート上にもともとそれが存在するか、 あるいはJavaコード上で明示的に Script script = new Script(); 等と書くしかありません。 想定外のタグが出力されることに起因するXSS等の脆弱性が発生する余地はほとんどありません。

XML-API

mixer2はXHTMLをXMLとして扱います。JavaでXMLを操作するAPIは 様々なものがありますが、主にJAXBを使用しています。 DOMはメモリを消費しすぎるため使用していません。

Caching

なお、全てのhtmlタグのクラスは implements Serializable であり、 copy()メソッドを備えています。 Java向けの汎用キャッシングフレームワークを組み合わて キャッシュ機能を実装することは可能でしょう。

See also Mixer2-Cacheable project.

Use Maven through web proxy

Mixer2のサンプルアプリケーションはmavenを使用しています。 mavenは必要なライブラリをインターネット上のセントラルリポジトリからhttp(s)で自動的にダウンロードします。 ネットワーク環境によっては外部へのhttp(s)アクセスのために認証つきのWebプロキシサーバを 通過させなければならない場合があります。

proxy設定の方法はmavenの公式サイトにありますので参考にしてください。

  • Guide to using proxys
  • Password encryption 通常は、認証つきWebプロキシーサーバのパスワードを、ホームディレクトリ/.m2/settings.xmlファイルに平文で書きますが、 平文保存を避けたい場合は暗号化機能を使います。