Java for Web学习笔记(十三):JSP(3)Directive

属性

import

我们在Java中需要import相关的类,在JSP也一样,方式如下。多个引入可以用逗号进行份额,我们也可以采用写import可以分开写的方式。

<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.util.*,java.io.IOException" %> 用逗号进行分隔或者写多行
<%@ page import="java.util.Map" %>
<%@ page import="java.util.List" %>
<%@ page import="java.io.IOException" %>

Directive、declaration和scriptlet会输出一个空行,如下所示。

Java for Web学习笔记(十三):JSP(3)Directive_第1张图片

为例避免太多的空行输出,在书写上通常首尾衔接,如下:

<%@ page import="java.util.Map"
%><%@ page import="java.util.List"
%><%@ page import="java.io.IOException" %>

pageEcoding

相当于在HttpServletResponse中设置setCharacterEncoding,例子:

<%@ page language="java"contentType="text/html"pageEncoding="UTF-8"%>

session

值为true或者false,表明JSP是否在HTTP sessions中,缺省为true。如果我们不需要session,刻意设置为false以提升性能。

isELIgnored

用于表明EL(Express Language)是否解析和翻译。在JSP 2.0之前,缺省值是true,如果要使用EL,就必须设置为false,在JSP 2.0之后,缺省值为false。目前使用JSP2.3。

buffer和autoFlush

缺省值分布是8kb和true。Buffer是JSP输出的缓存大小,可以设置为某kb或者none(none表示不缓存),autoFlush是buffer满的时候,是否马上输出。如果buffer为none,autoFlush为false,则在翻译为javacode的时候报异常,如果buffer为某个值,autoFlush为flash,如果缓存满,则报异常。所以autoFlash一般都应采用缺省值true。

如果buffer="none",会马上发送,效率会提高,但是也有缺点。在TCP的传输中,这回销毁更多的带宽。另外采用buffe的r,则可以在发送前(即buffer满之前)就设置HTTP的headers,或进行重定向,而没有buffer,这些都必须在任何的write之前设定好,编程上会带来某些不便。

isErrorPage

缺省为false,如果设置为true,会隐含Exception,如果页面的Exception没有被捕获,将在该jsp中处理,当然我们也可以在web container中定义(web.xml)作为error的页面。

isThreadSafe

缺省为true,表明jsp可以安全地给多个请求同时访问。如果设置为false,只能one by one。一般不应修改此值。

extends

用于继承的基类,但更换web container会有问题,不要使用。

我们可以参考http://www.jb51.net/article/73428.htm。

在大多数的JSP中,一般会修改Content-Type(有时包括pageEncoding)的缺省值,此外session和isErrorPage可能是最多用的属性,偶尔可能会关闭buffer,而其他的应该不进行修改。

包含其他JSP

在Servlet中通过include可以将两个页面结合,在JSP中也一样,通过 include将另一个页面结合过来:

静态方式

<%@ includefile="/index.jsp" %>

如果是绝对路径,就是在根目录就是应用的webapp/,如果a.jsp位于WEB-INF/下,则路径为/WEB-INF/a.jsp。如果相对路径,就是相对本jsp的路径而言。

如果引入的jsp已经包含了<%@ pagecontentType="text/html; charset=UTF-8" language="java"%>,那么在本jsp要么编写,要么保证完全一模一样,多个空格多不行,否则会报错。下面就是在分号后面多了个空格,本质内容是一致的,也会报错。

严重: Servlet.service() for servlet [jsp] in context withpath [/chapter04] threw exception [/index.jsp (line: 1, column: 2) Pagedirective:illegal to have multipleoccurrences of contentType with different values (old: text/html;charset=UTF-8, new: text/html;charset=UTF-8)] with root cause

org.apache.jasper.JasperException: /index.jsp (line: 1, column: 2) Page directive:illegal to have multiple occurrences of contentType with different values (old:text/html; charset=UTF-8, new: text/html;charset=UTF-8)

在翻译的java代码中,我们可以看到:

static {
  _jspx_dependants = new java.util.HashMap(1);
  _jspx_dependants.put("/index.jsp", Long.valueOf(1449717101338L));
}

在这个例子中,我们<%@ includefile="index.jsp" %>,采用了相对路径,会被翻译为绝对路径,而index.jsp相关的内容,已经翻译为java代码合并进来。

动态方式

/index.jsp" />

这没有使用directive。我们在java代码中可能看到区别:

public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {
……
try {
response.setContentType("text/html;charset=gb2312");
      … …
      out = pageContext.getOut();
      jspx_out = out;

      out.write('\n');
      org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "index.jsp",
 out, false);
      out.write("\n");
……
} catch(java.lang.Throwable t){
   ……
} finally {
      ……
   }
   ……
}

这里并没有引入index.jsp的代码,而是在运行时临时转到相关的jsp进行输出(写response的content,没有对于response进行设置),处理之后,回来继续进行out输出。由此,被引用jsp的不同属性不影响到本jsp,例如本jsp的编码可以设置为gd2312,而index.jsp为UTF-8。输出的结果Content-Type:"text/html;charset=gb2312"。

一般而言,静态方法的效率更高,所有引入jsp的都在视图中,我们可以使用引用jsp在其declaration和scriptlet中的定义的类、变量和方法,但也用注意到不用重复定义。此外,java方法编译为bytecode有大小限制,为65,534 bytes,静态方法会导致_jspService()更大,不过一般不用担心会超过这个大小。书推荐使用directive的方式,但我觉得从编程独立性而言,使用动态方法无需担心定义的歧义,似乎更好。*.jspf是jsp的fragment,提供include的内容,需要采用静态方式,即directive include方式。

Tag库

引入tag库:

<%@ tagliburi="http://java.sun.com/jsp/jstl/core" prefix="c" %>

URI给出namespace,prefix给出别名,具体将在后面学习。


相关链接: 我的Professional Java for Web Applications相关文章

你可能感兴趣的:(JAVA,愷风(Wei)之Java,for,Web学习笔记)