ディレクティブ内で「out」変数 (および他の「事前宣言された」スクリプトレット変数) を使用することはできません。
JSP ページは、Web サーバーによって Java サーブレットに変換されます。たとえば、Tomcat の内部では、すべての静的 HTML とともに、スクリプトレット (「<%」で始まる) 内のすべてが、「out」と呼ばれる JspWriter インスタンスに行ごとにページを書き込む 1 つの巨大な Java メソッドに変換されます。これが、スクリプトレットで「out」パラメーターを直接使用できる理由です。一方、ディレクティブ (「<%!」で始まる) は、別個の Java メソッドとして変換されます。
例として、非常に単純なページ (foo.jsp と呼びましょう):
<html>
<head/>
<body>
<%!
String someOutput() {
return "Some output";
}
%>
<% someOutput(); %>
</body>
</html>
最終的には次のようになります (明確にするために多くの詳細は無視されています)。
public final class foo_jsp
{
// This is where the request comes in
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
// JspWriter instance is gotten from a factory
// This is why you can use 'out' directly in scriptlets
JspWriter out = ...;
// Snip
out.write("<html>");
out.write("<head/>");
out.write("<body>");
out.write(someOutput()); // i.e. write the results of the method call
out.write("</body>");
out.write("</html>");
}
// Directive gets translated as separate method - note
// there is no 'out' variable declared in scope
private String someOutput()
{
return "Some output";
}
}