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会输出一个空行,如下所示。
为例避免太多的空行输出,在书写上通常首尾衔接,如下:
<%@ 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,或进行重定向(<jsp:forward/>),而没有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,而其他的应该不进行修改。
在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<java.lang.String,java.lang.Long>(1); _jspx_dependants.put("/index.jsp", Long.valueOf(1449717101338L)); }
在这个例子中,我们<%@ includefile="index.jsp" %>,采用了相对路径,会被翻译为绝对路径,而index.jsp相关的内容,已经翻译为java代码合并进来。
<jsp:includepage="/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库:
<%@ tagliburi="http://java.sun.com/jsp/jstl/core" prefix="c" %>
URI给出namespace,prefix给出别名,具体将在后面学习。
相关链接: 我的Professional Java for Web Applications相关文章