2004 Marty Hall 控制所生成的 servlet 的结构 :JSP page 指令 JSP, Servlet, & Struts Training Courses: http://courses.coreservlets.com Available in US, China, Taiwan, HK, and Worldwide 2 JSP and Servlet Books from Sun Press: http://www.coreservlets.com Available in English, Chinese (simplified and traditional script), and 12 other languages 议程 page 指令的用途 指定导入类 指定页面的 MIME 类型 生成 Excel 电子表格 会话的共享 设置输出缓冲区的大小和行为 指定处理 JSP 错误的页面 控制线程的行为 3 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
page 指令的用途 为根据 JSP 页面生成的 servlet 指定高层的信息 能够控制 导入哪些类 该 servlet 扩展哪个类 产生哪种 MIME 类型 如何处理多线程 servlet 是否共享会话 输出缓冲区的大小的行为 由哪个页面来处理意外的错误 4 JSP/servlet/Struts/JSF training: http://www.coreservlets.com import 属性 <%@ page import="package.class" <%@ page import="package.class1,...,package.classn" 在 servlet 定义的顶部生成导入语句 尽管 JSP 页面几乎可以放在服务器的任何位置, 但由 JSP 使用的类必须放在常规的 servlet 目录中 例如 : /WEB-INF/classes 或 /WEB-INF/classes/directoryMatchingPackage 由 JSP 使用的实用工具类一定要使用包! 5 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
使用包的重要性 系统会认为 SomeHelperClass 和 SomeUtilityClass 在哪个包中呢?... public class SomeClass { public String somemethod(...) { SomeHelperClass test = new SomeHelperClass(...); String somestring = SomeUtilityClass.someStaticMethod(...);... } } 6 JSP/servlet/Struts/JSF training: http://www.coreservlets.com 使用包的重要性 ( 续 ) 系统会认为 SomeHelperClass 和 SomeUtilityClass 在哪个包中呢?... <% SomeHelperClass test = new SomeHelperClass(...); String somestring = SomeUtilityClass.someStaticMethod(...); 7 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
import 属性 : 示例 ( 代码 ) <H2>The import Attribute</H2> <%@ page import="java.util.*,coreservlets.*" <%! private String randomid() { int num = (int)(math.random()*10000000.0); return("id" + num); } private final String NO_VALUE = "<I>No Value</I>"; <% String oldid = CookieUtilities.getCookieValue(request, "userid", NO_VALUE); if (oldid.equals(no_value)) { String newid = randomid(); Cookie cookie = new LongLivedCookie("userID", newid); response.addcookie(cookie); } This page was accessed on <%= new Date() with a userid cookie of <%= oldid. </BODY></HTML> 8 JSP/servlet/Struts/JSF training: http://www.coreservlets.com import 属性 : 示例 ( 结果 ) 9 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
contenttype 和 pageencoding 属性 <%@ page contenttype="mime-type" <%@ page contenttype="mime-type; charset=character-set" <%@ page pageencoding="character-set" 指定由 JSP 页面生成的 servlet 生成的页面的 MIME 类型 属性值不能在请求期间计算得出 常见 MIME 类型的表格, 参见介绍响应报头的章节 10 JSP/servlet/Struts/JSF training: http://www.coreservlets.com 生成 Excel 电子表格 First Last Email Address Marty Hall hall@coreservlets.com Larry Brown brown@coreservlets.com Steve Balmer balmer@ibm.com Scott McNealy mcnealy@microsoft.com <%@ page contenttype="application/vnd.ms-excel" <%-- There are tabs, not spaces, between cols. -- 11 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
条件性地生成 Excel 电子表格 不能使用 contenttype 属性完成这项任务, 因为我们不能根据条件生成 contenttype 下面的代码产生的一定是 Excel MIME 类型 <% boolean usingexcel = checkuserrequest(request); <% if (usingexcel) { <%@ page contenttype="application/vnd.ms-excel" <% } 解决方案 : 使用常规的 JSP scriptlet, response.setcontenttype 语句 12 JSP/servlet/Struts/JSF training: http://www.coreservlets.com 条件性地生成 Excel 电子表格 ( 代码 ) <BODY> <CENTER> <H2>Comparing Apples and Oranges</H2> <% String format = request.getparameter("format"); if ((format!= null) && (format.equals("excel"))) { response.setcontenttype("application/vnd.ms-excel"); } <TABLE BORDER=1> <TR><TH></TH> <TH>Apples<TH>Oranges <TR><TH>First Quarter <TD>2307 <TD>4706 <TR><TH>Second Quarter<TD>2982 <TD>5104 <TR><TH>Third Quarter <TD>3011 <TD>5220 <TR><TH>Fourth Quarter<TD>3055 <TD>5287 </TABLE> </CENTER></BODY></HTML> 13 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
条件性地生成 Excel 电子表格 ( 结果 ) 14 JSP/servlet/Struts/JSF training: http://www.coreservlets.com session 属性 <%@ page session="true" <%-- Default -- <%@ page session="false" 指定页面不是会话的一部分 默认地, 它是属于会话 如果网站的流量较大, 可以节省服务器端的内存 要想真正起到作用, 所有的相关网页都必须这样做 15 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
iselignored 属性 <%@ page iselignored="false" <%@ page iselignored="true" 控制是否应该忽略 JSP 2.0 表达式语言 (EL)(true), 还是应该正常求值 (false) 如果您的 web.xml 指定 servlets 2.3( 对应 JSP 1.2) 或更早的版本, 默认值为 true 但改变默认值依旧是合法的 在 JSP-2.0- 兼容的服务器上, 不管 web.xml 的版本如何, 都可以使用这个属性 如果您的 web.xml 指定 servlets 2.4( 对应 JSP 2.0) 或更新的版本, 默认值为 false 16 JSP/servlet/Struts/JSF training: http://www.coreservlets.com buffer 属性 <%@ page buffer="sizekb" <%@ page buffer="none" 指定 out 变量所使用的缓冲区的大小 通过缓冲, 我们甚至能够在某些页面内容已经生成后再去设置 HTTP 报头 ( 只要缓冲区没有被充满或被显式地清空 ) 服务器可以使用比请求的大小更大的缓冲区, 但不会小于所请求的大小 默认值和系统相关, 但至少 8kb 17 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
errorpage 属性 <%@ page errorpage="relative URL" 指定一个 JSP 页面, 抛出的任何异常如果未在当前页面内被捕获, 则由该页面进行处理 指定的错误处理页面可以通过 exception 变量来访问所抛出的异常 web.xml 文件允许我们指定适用于整个应用的错误页面, 当任何确定的异常或确定的 HTTP 状态代码产生时, 都会使用该页面来处理 errorpage 属性仅用于指定特定页面的错误页面 18 JSP/servlet/Struts/JSF training: http://www.coreservlets.com iserrorpage 属性 <%@ page iserrorpage="true" <%@ page iserrorpage="false" <%-- Default -- 标示当前页面是否可以作为其他 JSP 页面的错误页面 名为 exception 的新预定义变量会被创建, 并能够在错误页面中对其进行访问 只能将其作为紧急备份 ; 明确地处理尽可能多的各种异常 不要忘记一定要检查查询数据中的值是否缺失或异常 19 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
错误页面 : 示例 <BODY> <%@ page errorpage="/web-inf/speederrors.jsp" <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE">Computing Speed</TABLE> <%! private double todouble(string value) { return(double.parsedouble(value)); } <% double furlongs = todouble(request.getparameter("furlongs")); double fortnights = todouble(request.getparameter("fortnights")); double speed = furlongs/fortnights; <UL> <LI>Distance: <%= furlongs furlongs. <LI>Time: <%= fortnights fortnights. <LI>Speed: <%= speed furlongs per fortnight. </UL> </BODY></HTML> 20 JSP/servlet/Struts/JSF training: http://www.coreservlets.com 错误页面 : 示例 ( 续 ) <BODY> <%@ page iserrorpage="true" <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> Error Computing Speed</TABLE> <P> ComputeSpeed.jsp reported the following error: <I><%= exception </I>. This problem occurred in the following place: <PRE> <%@ page import="java.io.*" <% exception.printstacktrace(new PrintWriter(out)); </PRE> </BODY></HTML> 21 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
错误页面 : 结果 22 JSP/servlet/Struts/JSF training: http://www.coreservlets.com isthreadsafe 属性 <%@ page isthreadsafe="true" <%-- Default -- <%@ page isthreadsafe="false" 用来告诉系统什么时候您的代码不是线程安全的, 从而, 系统能够阻止并发的访问 一般用以告诉 servlet 实现 SingleThreadModel 要尽可能避免这种用法 某些情况下会带来性能上的损失 另一些情况可能会得到不正确的结果 23 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
非线程安全代码的例子 (ID 必须惟一 ) 下面的代码有什么问题呢? <%! private int idnum = 0; <% String userid = "userid" + idnum; out.println("your ID is " + userid + "."); idnum = idnum + 1; 24 JSP/servlet/Struts/JSF training: http://www.coreservlets.com 此处需要 isthreadsafe 吗? 不需要! <%! private int idnum = 0; <% synchronized(this) { String userid = "userid" + idnum; out.println("your ID is " + userid + "."); idnum = idnum + 1; } 在高业务量环境中可以获得较好的性能 如果服务器使用实例共享的方案, 则 isthreadsafe="false" 会完全失败 25 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
extends 属性 <%@ page extends="package.class" 指定由 JSP 页面转换而成的 servlet 的父类 使用时要极端小心 可能阻止系统使用高性能的定制超类 (superclasses) 典型的目的是让用户扩展由服务器供应商提供的类 ( 举例来说, 为支持个性化的特性而提供的类 ), 而不是扩展您自己的类 26 JSP/servlet/Struts/JSF training: http://www.coreservlets.com 小结 import 属性 改变由 JSP 页面生成的 servlet 导入的类 实用工具类一定要使用包! contenttype 属性 指定结果的 MIME 类型 不能根据条件来使用 要想条件性地设置 MIME 类型, 请使用 <% response.setcontenttype(...); errorpage 和 iserrorpage 属性 指定 紧急情况 错误处理页面 isthreadsafe 属性 关闭并行访问 请使用显式的同步, 而非这个属性 27 JSP/servlet/Struts/JSF training: http://www.coreservlets.com
2004 Marty Hall 问题? JSP, Servlet, & Struts Training Courses: http://courses.coreservlets.com Available in US, China, Taiwan, HK, and Worldwide 28 JSP and Servlet Books from Sun Press: http://www.coreservlets.com Available in English, Chinese (simplified and traditional script), and 12 other languages