JSP第一章:JSP技术
文章目录
1.JSP技术简介
背景:随着因特网的来临,单层应用程序架构已转变为多层客户机/服务器架构。对服务器端脚本的需求 开始逐渐主导 Web 编程。微软引入了 Active Server Pages (ASP) 来捕捉服务器端脚本的市场需 求。同样,Sun Microsystems 发布了 JavaServer Pages (JSP) 来为 Java 添加服务器端编程 的功能。
1.1JSP技术介绍
典型的 Web 应用程序由表示静态内容的表示逻辑组成,其中静态内容用于设计页面布局、颜色及文 本等网页结构。业务逻辑或动态内容涉及到财务和业务计算等业务智能和诊断的应用程序。开发 Web 应用程序时,如果要求开发人员编写静态内容,会耗费大量时间。
JSP 技术简化了 Web 设计师和 Web 开发人员工作职责的划分。Web 设计师使用 HTML 设计和 规划网页布局。另一方面,Web 开发人员可以独立工作,用 Java 代码和其他 JSP 特有标记编写 业务逻辑。同时构造静态和动态内容有助于开发优质应用程序并提高生产率。
JSP 页面编译后会生成 servlet,从而合并所有 servlet 功能。尽管 servlet 和 JSP 有一些相同的 功能,如平台独立、创建数据库驱动的 Web 应用程序以及服务器端编程,但 servlet 和 JSP 之间 还是有一些基本区别:
- Servlet 绑定文件(HTML 文件用于静态内容,Java 文件用于动态内容)以独立处理静态表 示逻辑和动态业务逻辑。因此,对任何文件进行修改都要重新编译 servlet。而 JSP 则可以 使用特殊标记直接将 Java 嵌入 HTML 页面。还可以在单独的文件中替换 HTML 内容和 Java 内容。对 HTML 内容所做的任何修改都自动编译并载入到服务器中。
- servlet 编程涉及大规模的代码编写。因此,对代码进行的任何修改都要求识别出静态代码内 容(对于设计师)和动态代码内容(对于开发人员),以便合并修改。而 JSP 页面把静态和 动态内容分开存放,从而有助于 Web 开发人员和 Web 设计师独立工作。
1.2JSP生命周期
客户机浏览器请求特定的 JSP 页面时,服务器向 JSP 引擎发送请求。JSP 引擎是 Web 容器中将 JSP 页面编译成 servlet 的部分。下图显示了在客户机请求 JSP 页面后发生的事件流的过程:
请求-响应周期主要包括两个阶段,即转换阶段和请求处理阶段。转换阶段由 JSP 引擎实现,涉及到 生成 servlet。在内部,这会为 JSP 页面生成一个类文件以便实现 servlet 接口。在请求处理阶 段,根据请求规范生成响应。servlet 发送与所收到请求对应的响应。servlet 第一次载入后将保持 激活并处理后续所有请求,从而节约了为每个请求重新载入 servlet 所耗费的时间。
JSP 转换为 servlet 后,容器调用在 javax.servlet.jsp.JspPage 接口中定义的 servlet 上 的生命周期方法:
- jspInit():servlet 初始化时调用此方法。
- jspService():收到对 JSP 页面的请求时调用此方法。
- jspDestroy():从服务中删除 servlet 之前调用此方法。
如下图表示
1.3JSP的页面结构
JSP 页面由表示静态内容的常规 HTML 标记和嵌入到特殊标记中表示动态内容的代码组成。这些标 识以“<%”符号开始,以“%>”符号结束。脚本和指令元素都写在“<%”和“%>”符号之间。脚本 元素由 Java 代码段组成。指令用于定义整个 JSP 页面的规范。注释行放在“<%–”和“–%>” 符号之间,提供关于代码各部分的其他信息。例如,以下 JSP 代码在浏览器上显示服务器时间。该 代码包含分开放在各自标记中的 HTML 内容和 JSP 内容。(如果404尝试删除JSP代码中的空格).
<%--This is the HTML content--%>
<%@ page language=”java” %>
<HTML>
<HEAD><TITLE>Simple JSP example></TITLE></HEAD>
<BODY>
<H1> This is a code within the JSP tags to display the server time</H1>
<%--This is the JSP content that displays the server time by using the
Date class of the java.util package--%>
<%--注意下面三种方法已经被弃用,这里只用来举例--%>
<% java.util.Date now=new java.util.Date(); %>
<H2><%= now.getHours() %>:<%=now.getMinutes() %>:<%=now.getSeconds() %></H2>
</BODY>
</HTML>
输出结果
2.JSP页面组件
JSP 页面由各种组件组成,可以在 JSP 应用程序中使用这些组件来添加其他功能,如添加条件和循 环结构或使用 JavaBean 组件。JSP 页面的四个组件为:
- JSP 指令
- JSP 脚本
- JSP 隐式对象
- JSP 动作
2.1JSP 指令
JSP 页面中的指令元素提供关于特定 JSP 页面的全局信息,有三种类型:
- page 指令
- taglib 指令
- include 指令
要调用指令,需要使用符号 <%@ 和符号 %> 分别作为指令名称的前缀和后缀。指令有多个属性。定 义指令的语法为:
<%@ directive attribute=”value” %>;
2.1.1page指令
page 指令定义将关于 JSP 页面一般设置通知给 Web 容器的属性。您可以用 page 指令指定不同 属性。page 指令的语法为:
<%@ page attribute_list %>;
下表为page指令支持的各种属性及其描述
属性 | 描述 |
---|---|
Extends | 定义 JSP 生成的 servlet 扩展的父类。 |
Import | 将包、类或接口的列表导入生成的 servlet 中。 |
Session | 指定所生成的 servlet 能否访问会话。如果属性值设置为 true,将生成隐式对象 session。session 属性的默认 值是 true。 |
Buffer | 指定输出缓冲区的大小。如果大小设置为 none,则不进行 任何缓冲。buffer 大小的默认值是 8 KB。 |
autoflush | 如果此属性值设置为 true,则自动刷新输出缓冲区。如果 属性值设置为 false,则缓冲区满时将引发异常。 autoFlush 属性的默认值是 true。 |
isThreadSafe | 指定 JSP 页面是否线程安全 |
errorPage | 指定将任何已生成而未处理的异常指向到该 URL。 |
isErrorPage | 如果此属性值设置为 true,则指定当前 JSP 页面为错误 页面。isErrorPage 属性的默认值是 false。 |
contentType | 定义响应的 MIME 类型。contentType 属性的默认值是 text/html。 |
Language | 定义 JSP 页面的脚本语言。 |
例如创建JSP文件时的page指令代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
2.1.2include指令
指定要插入文件的路径。include 指令用于在 JSP 页面编译期间以相对 URL 的形式指定要插入的文件的名称。所插入文件 的内容成为 JSP 页面的组成部分。include 指令还可用于插入代码中多个页面共用的部分,从而 避免为每个代码分别使用 bean。定义 include 指令的语法为:
<%@ include file = ”URLname” %>
例如在上面的JSP文件插入hello.html文件(注意include指令代码不要放在html的< head>中.)
<%@include file="../JSP/hello.html"%>
输出结果
2.1.3taglib 指令
taglib 指令将自定义标记导入当前 JSP 页面上。自定义标记指用户定义的标记,用于在 JSP 页面 中执行重复性任务。标记库描述符(TLD)文件定义自定义标记的功能。
taglib 指令将其自身与 URI 相关联,以便唯一地标识一个自定义标记。它还和能将此自定义标记与 JSP 页面上使用的其他标记库区分开的标记前缀字符串相关联。在 JSP 页面上导入 taglib 指令的 语法为:
<%@ taglib uri=“tag_lib_URI” prefix=”prefix” %>
这里举个引入核心标签库的例子
<%@ taglib uri=“http://java.sun.com/jsp/jst1/core” prefix=”c” %>
prefix里起的名字随意,这里叫c。
taglib 指令接受两种属性。下表列出了 taglib 指令的两种属性及其描述:
属性 | 描述 |
---|---|
URi | 查找自定义标记的 TLD 文件。 |
prefix | 定义用于区分自定义标记实例的前缀字符串。 |
2.2JSP脚本元素
JSP 脚本元素用于直接将 Java 代码嵌入到 HTML 页面中。可以在 JSP 页面中使用的各种类型的 JSP 脚本元素有:
- 声明:JSP 声明提供了一种定义变量和方法的机制。声明语句放在 <%! 和 %> 符号之间, 始终以分号结尾。 使用 JSP 声明定义变量的代码段如下:
<%!
int i=0;
int x=0;
%>
- 表达式:JSP 表达式用于直接将值插入到输出中。JSP 表达式在用户做出 HTTP 请求时求 值。在 JSP 文件中包括 JSP 表达式的语法为:
<%= expression%>
- Scriptlet:JSP scriplet 由包含在 <% 和 %> 符号内的有效 Java 代码段组成。JSP scriptlet 在请求时执行,且可以使用声明、表达式或 JavaBean。声明 JSP scriptlet 包括 有效 Java 代码的语法为:
<% Java code %>
2.3隐式对象
JSP 中的对象可以使用指令隐式创建、使用标准操作显式创建或通过在 scriptlet 中声明来直接创 建。JSP 隐式对象指可以纳入到 JSP 表达式和 scriptlet 中的特定预定义的变量。JSP 的隐式对象 通过 servlet 类和接口实现。下表列出了各种隐式变量及其类和描述:
隐式对象 | 类 | 描述 |
---|---|---|
application | javax.servlet.ServletContext | 定义 Web 应用程序,一般是当前 Web 上下文中的应用程序。 |
config | javax.Servlet.ServletConfig | 表示 ServletConfig 类的 对象。 |
exception | java.lang.Throwable | 表示 JSP 页面中的 Throwable 异常。用于JSP中的错误处理,exception对象只能在错误页面中使用. |
Out | javax.servlet.jsp.JspWriter | 表示向客户机发送响应的 JspWriter 的对象。 JspWriter 扩展了 PrintWriter 类,一般由 JSP 页面用于发送客户机响应。 |
page | java.lang.Object | 表示当前JSP页面本身. |
session | javax.servlet.http.HttpSession | 表示 HttpSession 接口的 会话对象。 |
response | javax.servlet.http.HttpServl etResponse | 表示 HttpServletResponse 对 象的响应对象,用于向客户 机发送 HTML 输出。 |
request | javax.servlet.http.HttpServletRequest | 表示HttpServletRequest 对 象的请求对象。用于检索和 请求一起提交的数据。 |
pageContext | javax.servlet.jsp.PageContext | 表示 JSP 页面的页面上下文。 |
JSP 隐式对象,如 request 和 response 可用于接收客户机发送的请求并发送响应。例如,要 接受和处理用户输入的两个数值,可以用请求对象检索通过 HTML 页面输入的值。
以下两个文件用于接受和处理输入并显示结果:
-
AcceptInput.htm:接受用户输入的两个数值。可对输入数值执行加减等各种数学函数。 这些数值输入值作为参数传送给 Calculate.jsp。
-
Calculate.jsp:处理用户提供的输入并显示结果。
对应代码AcceptInput.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="RequestCalculate.jsp" method="post">
<!-- radio为单选框-->
<input type="radio" name="r1" value="add" checked="false">Addition<br>
<input type="radio" name="r1" value="sub" checked="false">Substraction<br>
<input type="radio" name="r1" value="div" checked="false">Divisn<br>
<input type="radio" name="r1" value="mul" checked="false">Multiplication<br>
Enter First Number:<input type="text" name="t1"><br>
Enter Second Number:<input type="text" name="t2"><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
RequestCalculate.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" import="java.lang.*" %>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%
<%-- 获取参数--%>
String choice=request.getParameter("r1");
int num1=Integer.parseInt(request.getParameter("t1"));
int num2=Integer.parseInt(request.getParameter("t2"));
int num3=0;
String output=" ";
if(choice.equals("add"))
{
num3= num1+num2;
output="Addition";
}
if(choice.equals("sub"))
{
num3= num1-num2;
output="Substraction";
}
if(choice.equals("div"))
{
num3= num1/num2;
output="Divison";
}
if(choice.equals("mul"))
{
num3= num1*num2;
output="Multiplication";
}
%>
<%
out.println("The result is:"+num3);
out.println("The operation is:"+output);
%>
</body>
</html>
当输入12和12,选择相乘后,点击提交会跳转到RequestCalculate.jsp,这时out隐式调用,在页面上输出对应内容。
输入值
输入完成提交后,
2.3.1Out隐式对象
out隐式对象表示向客户机发送响应的 JspWriter 的对象。 类似PrintWriter,out隐式对象相当于带缓存功能的PrintWriter。当out调用时,out对象会将数据写入JspWriter对象缓冲区中。当调用ServResponse.getWriter()方法时,缓冲的数据才写入Servlet引擎的缓冲区中.
举个简单例子,使用out对象在页面上输出内容
<%
int num1=10;
int num2=12;
out.print(num1+num2);
%>
运行后页面输出
2.3.2application隐式对象
“application”对象是javax.servlet.ServletContext interface.ServletContext接口。用于获取上下文初始化参数,以及在整个系统中共享属性及其值.即它作用于整个Web应用程序,保存的值可以被所有访问该网站的用户访问到.
“application”对象当Web服务器启动时,由web容器创建,每个容器一个。这意味着所有访问该网站的用户都共用一个application.
application的生命周期由Web服务器开始运行时开始,服务器关闭时结束.
举个简单例子,在xml文件设置参数,用application对象保存参数.
xml文件参数配置
<context-param>
<param-name>username</param-name>
<param-value>jack</param-value>
</context-param>
<context-param>
<param-name>email</param-name>
<param-value>2333@ee.com</param-value>
</context-param>
JSP
The name is :<%= application.getInitParameter("username")%><br>
The email is :<%= application.getInitParameter("email")%>
输出
2.3.3config隐式对象
config对象代表JSP的配置信息, 表示 ServletConfig 类的 对象。可用于指定web.xml文件中的配置参数.
举个例子,获取xml文件中的name参数和邮箱参数的值.
Config.jsp,配置完后会在页面输出对应值,如果没有配置对应参数,将三个值输出JSP,null,null
<!-- 输出getServletName()的值-->
The servlet name is :<%=config.getServletName()%>
The name is :<%= config.getInitParameter("username")%><br>
The email is :<%= application.getInitParameter("email")%>
xml文件配置如下
<servlet>
<!-- 指定Servlet名字-->
<servlet-name>config</servlet-name>
<!-- 指定JSP文件配置成Servlet-->
<jsp-file>/Config.jsp</jsp-file>
<!-- 配置两个参数-->
<init-param>
<param-name>name</param-name>
<param-value>jack</param-value>
</init-param>
</servlet>
<!-- 指定将config servlet配置到/config路径-->
<servlet-mapping>
<servlet-name>config</servlet-name>
<url-pattern>/config</url-pattern>
</servlet-mapping>
运行后会直接输出配置信息.
这里可以发现config的用法和application有些类似,列表比较
config | application |
---|---|
ServletConfig是特定的Servlet | ServletContext是针对整个web项目。 |
ServletConfig的参数在< servlet>中的< init-param>中以名值对的形式出现。 | ServletContext的参数设置在< context-param>中 |
只能向一个servlet/jsp共享信息。 | 它在整个web项目中共享信息 |
2.3.4request对象
http通信协议是用户与服务器之间一种提交(请求,request)与响应信息(response)的通信协议,在jsp中,request对象用于保存(封装)用户提交信息,同时我们可以通过request对象方法获取封装的信息.
<form action="Session1.jsp" method="post">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
<input type="submit" value="sumbit">
</form>
使用request对象方法获取封装信息,注意request是依据标签的name属性获取值,不是id
String username=request.getParameter("username");
String password=request.getParameter("password");
2.3.5Session会话对象
会话,从一个用户打开浏览器某个网站开始,直到关闭浏览器.期间不论在网站中打开了多少网页,都属于同一个会话.Session默认有效期是30分钟.由服务端创建,同时保存在服务端.
使用Session对象可以用于
- 记录购物车里有哪些商品
- 保存用户信息
- 设置属性保存数据,当使用该数据时可以直接读取
以保存用户信息为例,先设置一个前端页面获取用户输入;
Session.html
<form action="Session1.jsp" method="post">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
<input type="submit" value="sumbit">
</form>
使用JSP保存用户数据,Session1.jsp
<%
//使用request对象方法获取用户输入
String username=request.getParameter("username");
String password=request.getParameter("password");
if (username.equals("Johnson")&&password.equals("12345")){
// 设置属性,同时保存属性在会话中。
session.setAttribute("username",username);
response.sendRedirect("Session2.jsp");
}
else {
response.sendRedirect("InvalidLogin.html");
}
%>
另一个jsp获取保存的用户名并输出
<body>
<%--跨页面读取会话保存属性--%>
Welcome <%=session.getAttribute("username")%>
</body>
2.3.6response对象
response对象包含了响应客户请求的有关消息.即服务端对客户端的响应.一般jsp中很少使用response对象,因为存在着out对象可以直接生成响应.
例如用户登录,用户名密码正确则服务端会重定向客户当前页面到用户页面,登录失败则显示登录失败信息.
2.3.7pageContext对象
表示 JSP 页面的页面上下文。主要用于访问JSP之间共享的数据。
获取jsp之间共享数据对应方法:
- getAttribute(String name):当没有指定范围时,默认的是page范围
- getAttribute(String name,int scope),后面形参为即为范围,取得指定范围内的name属性。有下面4个范围可以使用
- PageContext.PAGE_SCOPE:对应于page范围。
- PageContext.REQUEST_SCOPE:对应于request范围。(response范围换成RESPONSE_SCOPE:)
- PageContext.SESSION_SCOPE:对应与session范围。
- PageContext.APPLICATION_SCOPE:对应于application范围。
举例,运行后会输出变量内容.
<body>
<%
String txt="dream";
session.setAttribute("txt",txt);
%>
变量内容是:<%=pageContext.getAttribute("txt",PageContext.SESSION_SCOPE)%>
</body>
ttribute(String name,int scope),后面形参为即为范围,取得指定范围内的name属性。有下面4个范围可以使用
- PageContext.PAGE_SCOPE:对应于page范围。
- PageContext.REQUEST_SCOPE:对应于request范围。(response范围换成RESPONSE_SCOPE:)
- PageContext.SESSION_SCOPE:对应与session范围。
- PageContext.APPLICATION_SCOPE:对应于application范围。
举例,运行后会输出变量内容.
<body>
<%
String txt="dream";
session.setAttribute("txt",txt);
%>
变量内容是:<%=pageContext.getAttribute("txt",PageContext.SESSION_SCOPE)%>
</body>