JSP和JSTL板块:第二节 JSP的指令和动作
- 一、page指令:页面设置
- (1)导入包:import属性
- (2)设定字符集:pageEncoding属性
- (3)设定错误页面:errorPage/isErrorPage属性
- (4)设定MIME类型和字符编码:contentType属性
- 二、include指令:包含
- (1)静态包含:指令
- (2)动态包含:动作
- 三、forward动作:请求转发
JSP指令告诉JSP引擎对JSP页面如何编译,不包含控制逻辑,不产生任何可见的输出,只对当前文件做导入、设定当前文件特殊属性等操作。
用法:
<%@ 指令类别 属性1="..." 属性2="..." ... %>
JSP只包含三个指令:page,include,taglib
,其中前两个最常用
一、page指令:页面设置
(1)导入包:import属性
在编写程序时,可能需要用到JDK的其他类或者自己定义的别的类,这时候就需要使用improt
属性进行导入。import
属性用法如下
<%@ page import="包名.类名" %>
如果想把包下面的所有类都导入,可以用.*
<%@ page import="包名.*" %>
如
<%@ page import="java.util.*"%>
导入包中多个类时,用逗号隔开
<%@ page import="java.io.*","java.awt.*" %>
(2)设定字符集:pageEncoding属性
在Servlet中,可以使用request对象的两个属性:
request.setCharacterEncoding("UTF-8");
request.setContentType("text/html;charset=UTF-8");
设置前后两端的编码格式。
当然,在page指令的pageEncoding
属性也可进行编码的指定。但是注意pageEncoding
指的是JSP文件本身的编码,而contentType
中的charset
指的是服务器向客户端发送为客户端的内容编码(优先起决定作用的是pageEncoding
)
例
<%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%>
<html>
<head>
<title>test pageEncoding</title>
</head>
<body>
<center><h2>pageEncoding属性测试</h2></center>
</body>
</html>
(3)设定错误页面:errorPage/isErrorPage属性
在每个网站中都少不了设置错误页面,用于在网站发生错误时向用户显示一些网站管理员想让用户看到的信息,一般情况下,可以将异常现象在一个统一的网页中显示。我们可以通过errorPage
属性和isErrorPage
属性来指定错误页。
要完成错误页的操作,我们需要满足两个条件:
- 使用
errorPage
属性指定错误出现时要跳转的页面。 - 使用
isErrorPage
属性指明该页面是错误页。
注意:错误页的跳转属于服务器跳转(request域对象),页面内容改变,地址栏的地址不改变。
例:
报错页
JSP code
<%@ page language="java" contentType="text/html"pageEncoding="GBK"%>
<%@ page errorPage="error.jsp"%>
<html>
<head>
<title>test errorPage</title>
</head>
<body>
<center><h2>errorPage属性测试</h2></center>
</body>
</html>
错误处理页error.jsp
code
<%@ page language="java" contentType="text/html" pageEncoding="UTF-8"%>
<%@ page isErrorPage="true"%> <%--定义该页面是错误页 --%>
<html>
<head>
<title>test isErrorPage</title>
</head>
<body>
<center><h2>isErrorPage属性测试</h2></center>
</body>
</html>
(4)设定MIME类型和字符编码:contentType属性
在page指令中,contentType
属性可以指定JSP页面的编码方式和JSP页面响应的MIME
类型,默认的MIME
类型为text/html
,默认的字符集类型为charset=ISO-8859-1
。什么?你问我什么是MIME?
MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准,使用MIME类型可以设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。通用结构
contentType="type/subtype"
。点此了解更多关于MIME
例:为JSP页面指定MIME
类型为text/html
,编码为UTF-8
JSP code
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<html>
<head>
<title>test MIME</title>
</head>
<body>
<center><h2>contentType属性的设置测试</h2></center>
</body>
</html>
以上就是page指令的四个常用属性
二、include指令:包含
使用包含操作,可以将同一段代码包含进JSP文件重复使用。例如,一般网页的组成可以分为几个区域,其中的一些区域可能是一直不需要改变的,比如顶部的菜单栏、底部的版权栏。只需要改变其中的一个具体区域,比如淘宝网中间的店铺内容。
在JSP中如果要想实现包含的操作,有两种做法:静态包含、动态包含
静态包含使用include
指令即可,动态包含则需要使用include
动作标签。
(1)静态包含:指令
静态包含就是将要包含的内容原封不动复制进当前文件,与JSP中的Java脚本段一样,在Servlet引擎转译时,就把此文件内容包含了进去(两个文件的源代码整合到一起,全部放到_jspService
方法中,回顾上一小节【第一节 JSP追根溯源】),所以只生成了一个Servlet,导致两个页面不能有同名的变量。运行效率高一点点,但耦合性较高,不够灵活。
语法
<%@ include file="要包含的文件路径"%> <!-- 相对路径 -- >
例
被包含的页面 included.jsp
<%--
Created by IntelliJ IDEA.
User: TommyNike
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>被包含的页面</title>
</head>
<body>
<h1>Hello Include</h1>
</body>
</html>
拿包含的页面 include.jsp
<%--
Created by IntelliJ IDEA.
User: TommyNike
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>拿包含的页面</title>
</head>
<body>
<%@ include file="included.jsp "%>>
</body>
</html>
访问拿包含的页面
底层原理
找到 拿包含的页面Servlet
include_jsp.java code
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>拿包含的页面</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <title>被包含的页面</title>\r\n");
out.write(" </head>\r\n");
out.write(" <body>\r\n");
out.write(" <h1>Hello Include</h1>\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
out.write(">\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
可以看到底层就是拿包含的页面Servlet把被包含页面的代码在服务器里输出了一遍而已
(2)动态包含:动作
JSP动作指使用XML语法格式的标记来控制服务器的行为。
语法
<jsp:动作名 属性1="..." 属性2="..." ... />
或者
<jsp:动作名> ... </jsp:动作名>
include的动态包含
动态包含底层是Servlet中调用了一个方法来完成包含,会生成多个源码文件,所以可以定义同名变量,效率高,耦合度低
语法
<jsp:include page="文件名" />
例
被包含的页面 included.jsp
<%--
Created by IntelliJ IDEA.
User: TommyNike
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>被包含的页面</title>
</head>
<body>
<h1>Hello Include</h1>
</body>
</html>
拿包含的页面 include.jsp
<%--
Created by IntelliJ IDEA.
User: TommyNike
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>拿包含的页面</title>
</head>
<body>
<%--现在改成动态包含了--%>
<jsp:include page="included.jsp" />
</body>
</html>
访问拿包含的页面
那为什么说相当于Servlet中调用了一个方法?
底层原理
同样找到拿包含页面的Servlet
include_jsp.java code
out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>拿包含的页面</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write('\r');
out.write('\n');
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "included.jsp", out, false);
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
可以看到,包含处代码变成了org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "included.jsp", out, false);
Servlet调用了一个叫include
的方法,而不是像静态包含一样直接输出代码了,所以动态包含可以定义同名变量,效率高,耦合度低。
三、forward动作:请求转发
我们已经在include的动态包含里介绍了什么是JSP的动作,除了include动作,还有一个重要的知识点,jsp:forward
动作:请求转发。当forward动作被执行后,当前的页面将不再执行,而是去执行指定的目标页面
语法
<jsp:forward page="文件名" />
例
跳转前页面 start.jsp
<%--
Created by IntelliJ IDEA.
User: TommyNike
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>跳转前页面</title>
</head>
<body>
<jsp:forward page="after.jsp" /> <%--请求转发动作--%>
<h1>Hello 跳转前</h1>
</body>
</html>
跳转后页面 after.jsp
<%--
Created by IntelliJ IDEA.
User: TommyNike
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>跳转后页面</title>
</head>
<body>
<h1>Hello 请求转发</h1>
</body>
</html>
访问跳转前页面:
可以看到跳转前页面在请求转发动作之后的内容都被跳过了,因为跳转去执行的跳转后页面了
请求转发:从服务器跳转到客户端,是服务器行为,在Servlet中对应方法是
request.getRequestDispather("url").forward(request,response);
特点
- 地址栏不变
- 从始至终只有一个请求,在同一个request的域对象中,request与response两个参数传的值可以共享。更多的请求转发内容见Servlet模块