6.5.2 <jsp:forward>标签
<jsp:forward>标签用于转发Web资源。<jsp:forward>标签的语法格式如下:
<jsp:forward page="relativeURL | <%=expression%> | EL " />
<jsp:forward>标签和pageContext.forward方法的功能完全一样。看如下的代码:
<!-- forward.jsp -->
<%@ page language="java" pageEncoding="UTF-8"%>
<jsp:forward page="/test.html"/>
上面的代码通过<jsp:forward>标签转入“/test.html”,查询由forward.jsp页面翻译成的Servlet源文件,其中和<jsp:forward>标签相关的代码如下:
out.write('\r');
out.write('\n');
if (true) {
_jspx_page_context.forward("/test.html");
return;
}
out.write('\r');
out.write('\n');
从上面的代码可以看出,<jsp:forward>标签实际上被翻译成了调用pageContext对象的forward方法。因此,<jsp:forward>标签和pageContext.forward方法是完全一样的。但它们有一点不同,虽然<jsp:forward>标签和pageContext.forward方法等效,但是由<jsp:forward>标签翻译成的Java代码在调用完forward方法后,直接通过return语句退出了_jspService方法,也就是说,使用<jsp:forward>标签转发Web资源,不管在<jsp:forward>标签后面有没有静态的内容,都不会被写入out对象的缓冲区,自然也就不会使用PrintWriter对象将信息输出的客户端了。从这一点可以看出,在<jsp:forward>标签后面的内容是不会造成由于同时使用PrintWriter和ServletOutputStream对象而抛出异常的结果的。
从上面的描述可能看出,在JSP页面中使用<jsp:forward>标签转发Web资源将大大降低抛出异常的可能性。但<jsp:forward>标签至少在如下三种情况下仍然会抛出异常:
l page指令的buffer属性值为none。
2 在调用<jsp:forward>标签之前,out对象缓冲区中的内容的大小由于已经超过了缓冲区的大小,从而被刷新了。
3 显示调用out.flush方法刷新out对象缓冲区。
上面的三种情况之所以会抛出异常,是由<jsp:forward>标签的一个特性决定的,由于调用<jsp:forward>标签时,out对象缓冲区会被清空,而在调用clear方法清空缓冲区时,不能在此之前调用flush来刷新缓冲区,否则会抛出IOException异常。因此,在调用<jsp:forward>标签之前,不能通过任何方式刷新out对象的缓冲区。
对于上述情况的第一种,如果将buffer属性设为none,那么只要有一个字节的数据被写入out对象的缓冲区,该缓冲区都会被刷新。而对于第二种和第三种情况则毫无疑问会刷新缓冲区。但第三种情况则仍然会在浏览器中显示out对象缓冲区中的内容,而抛出的异常将在Tomcat控制台中显示(这种情况将会抛出java.io.IOException:异常)。前两种情况则既会在浏览器中显示异常,也会在Tomcat控制台中显示异常,而且抛出的异常是java.lang.IllegalStateException。