[Java][Tips] JSPのスクリプトレットで{ }のないループ処理を書いたらどうなるか

今週は、研修講師でサーバサイドJavaを教えておりますが、受講生からこのような質問が。
「{ }のないループをスクリプトレットで書いたらどうなりますか?」

普段、自分が担当する研修では、「forループやif文では、{ }をつけずに記述することも出来るが、可読性も考慮して普通は{ }をつけるようにしましょう」と指導していることが多いので、こういった質問が出ることも少なく、実は自分でも検証してみたことがなかったので、質問されたその場で、実験してみました。

たとえば、

<% for(int i=0;i<10;i++) %>
こんにちは

のようなコードを書くと、エラーにこそなりませんが、画面には何も表示されません。このようなコードは、Javaに変換されると、以下のようなコードになってしまうんですね。


for(int i=0;i<10;i++)
out.write("\r\n");
out.write("こんにちは\r\n");

つまり、スクリプトレットの後に続く「改行」が、1行分の「out.write文」に変換されてしまうために、「改行が10回表示されるだけ」で、期待されたような「こんにちは」を表示するループ処理にならないというわけです。

それならば、こういうコードなら良いのか?と試してみましたところ

<% for(int i=0;i<10;i++) %>こんにちは

こちらは、期待どおり?に

for(int i=0;i<10;i++)
out.write("こんにちは\r\n");

と変換され、「こんにちは」と10回表示させることが出来ます。

しかしながら、ループさせたいHTMLに、以下のようにExpressionを混ぜてしまうと

<% for(int i=0;i<10;i++) %>こんにちは< %= i %>

Expressionの処理の部分が1行で変換され、前後のHTMLドキュメントと合わせて複数行に分割されてしまうため、変数iが参照できずコンパイルエラーになってしまいます。変換はこんな感じになります。

for(int i=0;i<10;i++)
out.write("こんにちは");
out.print( i );
out.write("\r\n");

以上の結果はTomcat5.5.27で試したものです。このようなJSPからサーブレットへの変換に関して、仕様でどの程度決められているものなのか、調べていないので、どんなサーブレットのコードに変換されるのかは、実装依存なのかもしれません。

ご参考までに・・・。