前回、いきなりout.printlnという命令を書いていましたが、このoutはメソッドを見てわかるとおりPrintWriterオブジェクトです。
Javaサーブレットでは毎回毎回PrintWriter out = response.getWriter();と書く必要がありましたが、JSPでは何の宣言も無くいきなり使用しています。
どうなっているのでしょうか。
JSPでは、面倒なクラスのインスタンス化宣言をしなくてすむように、よく使うクラスは最初から自動的にインスタンス化されています。
つまり、こちらの目に見えないところでJspWriter out = pageContext.getOut();が実行されているということです。
これらはJSPの暗黙オブジェクトと呼ばれ、out以外にも最初からインスタンス化されているオブジェクトが幾つか存在します。
前回使ったところではapplication、これは見てのとおりアプリケーションスコープのことで、pageContext.getServletContext()を示します。
applicationに突っ込んだ変数は、Javaサーブレット同様どのファイルからでも参照することができます。
それ以外に有用なところとしては文字通りセッションスコープを示すsession、リクエストとレスポンスを示すrequestとresponseがあります。
他にも何種類かありますが、どうせ使わないので覚えなくていいです。
データをDBに保存する等の永続化の必要がないサイトであれば、概ね暗黙オブジェクトだけで作成することができるでしょう。
ところでこれまでアプリケーションスコープにいろいろなデータを突っ込んできました。
アプリケーションスコープの利点は各サーブレットで簡単にデータを共有できることですが、逆に言うとこれがアプリケーションスコープの欠点となります。
Javaサーブレットで作成したカウンター
http://yuubiseiharukana.blog.shinobi.jp/Entry/26/
JSPで作成したカウンター
http://yuubiseiharukana.blog.shinobi.jp/Entry/28/
同時に動かしてみるとわかりますが、両者で変数strCntが共有されています。
これが一人で作成しているのであれば変数名を変更するだけですみますが、これが複数人で開発しているシステムだったら、あるいは一人で行っていても規模が大きくなってきたら把握しきれるものではありません。
両カウンターともstrCntのパース時に例外処理を行っていないため、誰かが変数strCntに文字を入れたりしたらエラーが発生してしまいます。
場合によってはクラックの突破口となってしまうかもしれません。
Javaにはvar_dumpのような便利関数も存在しないため、どの変数が何処で使われているのかといった情報を調べるのも簡単なことではありません。
面倒なことになる前に面倒なことになる危険性のある行為はやめましょう。
最後にいろいろなスコープに値を突っ込んだ場合の取り出し方を見てみましょう。
どのようなスコープに変数をどうやって突っ込んで、どうやって取り出せばいいかがわかると思います。
セッションやアプリケーションスコープについてはこの例ではあまり意味がないのですが。
ページスコープは本当に1ページだけしか値を保持してくれないので、一回のリクエストで完結するならリクエストスコープ、繋がっている間データを保存したいならセッションスコープが適当です。
ELについてはまた次回。
src/xxx/scopetest.java
package xxx; import java.io.*; public class scopetest extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String strContext="strContext"; //アプリケーションスコープにセット //セッションスコープにセット //リクエストスコープにセット //指定したページをインクルードします |
/jsp/scopetest.jsp
<%@ page contentType="text/html;charset=Shift_JIS" %> session.getAttributeで呼んでみる<br> application.getAttributeで呼んでみる<br> EL:pageScopeで呼んでみる<br> EL:requestScopeで呼んでみる<br> EL:sessionScopeで呼んでみる<br> EL:applicationScopeで呼んでみる<br> EL:いきなり呼んでみる<br> </body> |