文章目录
Java Server Page(JSP)
JSP简介
- 在传统的网页HTML文件(.htm,.html)中加入Java程序片段(Scriptlet)和JSP标签,就构成了JSP网页
- Java程序片段可以操纵数据库、重新定向网页以及发送E-mail等,实现建立动态网站所需要的功能。所有程序操作都在服务器端执行,网络上传送给客户端的仅是得到的结果,这样大大降低了对客户浏览器的要求,即使客户浏览器端不支持Java,也可以访问JSP网页。
- Servlet简化设计,逻辑与界面设计分开,开发更方便;HTML语法的 Java 扩展,加入新的标签(<%, %>,…);强大的组件(Java Bean)支持功能。
JSP文件结构及主要标签
JSP执行过程
JSP 执行流程:
JSP 执行详细流程:
JSP语法概述
- JSP原始代码中包含了JSP元素和Template(模板) data两类
- Template data指的是JSP引擎不处理的部分,即标记<%……%>以外的部分,例如代码中的HTML的内容等 ,这些数据会直接传送到客户端的浏览器
- JSP元素则是指将由JSP引擎直接处理的部分,这一部分必须符合JAVA语法,否则会导致编译错误。
- • JSP语法分为三种不同的类型
编译器指令(DIRECTIVE) 例如: <%@ page import=“java.io.*” %>
脚本语法(SCRIPTING)
动作语法(ACTION) 例如: jsp:forward,jsp:getProperty,jsp:include
脚本语法
“HTML注释”:<!— comments -->
“隐藏注释”:<%-- comments --%>
“声明”
“表达式”
“脚本段”
HTML注释和隐藏注释
JSP 语法格式如下:
< !-- comment [ <%= expression%> ] --> 或< !-- 注释 [<%= 表达式 %> ] -->
这种注释发送到客户端,但不直接显示,在源代码中可以查看
JSP 语法格式如下:<%-- 注释 --%>不发送到客户端。
<%@page import="org.apache.naming.java.javaURLContextFactory"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 这是HTML注释,发送给客户端 -->
<!-- <%= new java.util.Date() %> -->
<%-- 这是JSP注释,不发送给客户端 --%>
<form action="result.jsp" method="post">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
repassword:<input type="password" name="repassword"><br>
age:<input type="text" name="age"><br>
<input type="submit" value="submit">
<input type="reset" value="reset">
</form>
</body>
</html>
结果是:
查看网页源代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 这是HTML注释,发送给客户端 -->
<!-- Mon Jan 28 22:10:17 CST 2019 -->
<form action="result.jsp" method="post">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
repassword:<input type="password" name="repassword"><br>
age:<input type="text" name="age"><br>
<input type="submit" value="submit">
<input type="reset" value="reset">
</form>
</body>
</html>
编译器指令
编译器指令包括“包含指令”,“页指令”和“taglib指令”,它们包含在“<%@ %>”卷标里。两个主要的指令是page与include。
声明
JSP 语法格式如下:<%! declaration; [ declaration; ] …%> 或<%! 声明; [声明; ] … %>
这个jsp被转译为servlet后,应用到单例模式,当用户第二次访问时,已经加载到内存的servlet不会再被加载,对于servlet是单实例的,只要一次被加载到内存就不会再生成对象了,因此成员变量是会变化的。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 声明,a为成员变量 -->
<%! int a = 3; %>
<!-- 脚本段 -->
<% int b = 3; %>
<%= a-- %>
<%= b-- %>
</body>
</html>
结果是:
刷新3次后
JSP 声明的格式:<%! int a = 3;%>,脚本段的形式:<% int b = 3;%>,当服务器将 JSP 转换为 Servlet 时,会将 JSP 中的声明转换为类的成员变量,而将脚本段转换为方法中的局部变量,Servlet 是单实例的,这样成员变量的值就只有一个,每个用户都会访问到它,而脚本段中的值则是局部变量,每个用户访问的时候各有一份,互不影响。
表达式
用于在页面上输出信息,语法格式如下:<%= expression %> 或<%= 表达式%>
脚本段
JSP 语法格式如下:
<% code fragment %> 或
<% 代码 %>
转义符: 双引号 \“
,单引号\’
,反斜杠\,回车\r,换行\n,制表符\t,退格 \b
包含指令
include指令:向当前页中插入一个静态文件的内容。
JSP 语法格式如下:<%@ include file=“relativeURL” %> 或<%@ include file=“相对位置” %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
The current date and time are
<%@ include file="test5_1.jsp" %>
</body>
</html>
<%@ page import="java.util.*"%>
<br>
<%= (new Date()).toLocaleString()%>
结果是:
Page指令
“Page”指令用于定义JSP文件中的全局属性。JSP 语法格式如下:
<%@ page[ language="java" ][ extends="package.class" ][import="{package.class | package.*},..." ][ session="true | false" ][ isThreadSafe="true | false" ][ errorPage="relativeURL" ][ contentType="mimeType [;charset=characterSet]" | "text/html ; charset=ISO-8859-1" [ isErrorPage="true | false" ]
属性:
- language=“java"声明脚本语言的种类,目前只能用"java” 。
- import="{package.class | package.* },…" 需要导入的Java包的列表,这些包作用于程序段,表达式,以及声明。下面的包在JSP编译时已经导入了,所以就不需要再指明了:java.lang.* javax.servlet.* javax.servlet.jsp.*
javax.servlet.http.* - errorPage="relativeURL"设置处理异常事件的JSP文件。
- isErrorPage="true | false"设置此页是否为出错页,如果被设置为true,你就能使用exception对象
- “<%@ page %>”指令作用于整个JSP页面,同样包括态的包含文件。但是“<%@ page %>”指令不能作用于动态的包含文件,比如 “jsp:include”。
- 可以在一个页面中用上多个“<%@ page %>”指令,但是其中的属性只能用一次,不过也有例外,那就是import属性。因为import属性和Java中的import语句类似(参照Java Language,import语句引入的是Java语言中的类),所以此属性就能用多次。
- 无论把“<%@ page %>”指令放在JSP的文件的哪个地方,它的作用范围都是整个JSP页面。不过,为了JSP程序的可读性,以及好的编程习惯,最好还是把它放在JSP文件的顶部。
jsp:forward
JSP 语法格式如下:
- <jsp:forward page={“relativeURL” | “<%= expression %>”} />
<jsp:forward page={“relativeURL” | “<%= expression %>”} >
<jsp:param name=“parameterName” value="{parameterValue | <%= expression %>}" />
[<jsp:param … />]
</jsp:forward>
(“[<jsp:param … />]”指可以有多个“jsp:param/”标记。)
- page="{relativeURL | <%= expression %>}"这里是一个表达式或是一个字符串用于说明你将要定向的文件或URL。这个文件可以是JSP,或程序段
- jsp:forward指令用于转向页面,在该指令后面的所有代码都没有机会执行了,因为页面的流程已经转向了另外一个页面了。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>test</title>
</head>
<body>
<jsp:forward page="forwardTo.jsp">
<jsp:param name="userName" value="riso"/>
</jsp:forward>
<% System.out.println("hello world");%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- forwardTo.jsp -->
<% String useName = request.getParameter("userName");
String outStr = "谢谢光临! ";
outStr += useName;
out.println(outStr);
%>
结果是:
所有不会输出hello word
jsp:include
• 包含一个静态或动态文件.
• JSP 语法格式如下:
1.<jsp:include page="{relativeURL | <%=expression%>}" flush=“true” />
2.
<jsp:include page="{relativeURL | <%=expression %>}" flush=“true” >
<jsp:param name=“parameterName” value="{parameterValue |
<%= expression %>}" />
[<jsp:param …/>]
</jsp:include>
(“[<jsp:param … />]”指可以有多个“jsp:param/”标记。)
3. page="{relativeURL | <%=expression %>}" 参数为一相对路径,或者是代表相对路径的表达式。
4. <jsp:param name=“parameterName"value=”{parameterValue | <%=expression %> }" />
“jsp:param”用来传递一个或多个参数到指定的动态文件,能在一个页面中使用多个“jsp:param”来传递多个参数,
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="output.jsp">
row: <input type="text" name="row"><br>
col: <input type="text" name="col"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
int row = 0;
int col = 0;
try{
row = Integer.parseInt(request.getParameter("row"));
col = Integer.parseInt(request.getParameter("col"));
}
catch(Exception exception){
out.println("请输入数字");
return;
}
%>
<table border="1" width="80%" align="center">
<% for(int i = 0;i < row; i++){ %>
<tr>
<% for(int j = 0;j < col; j++){ %>
<td>
这是第<%= i+1%>第<%= j+1%>列
</td>
<% } %>
</tr>
<% } %>
</table>
</body>
</html>
结果是:
JSP内置对象
JSP 有以下九种内置对象,包括:
• ·request,请求对象
• ·response,响应对象
• ·pageContext,页面上下文对象
• ·session,会话对象
• ·application,应用程序对象
• ·out,输出对象
• ·config,配置对象
• ·page,页面对象
• ·exception,异常对象
综述
有几种对象看起来和ASP的内置对象差不多,功能也类似,这是因为这些内置对象的构建基础是标准化的HTTP协议。如果使用过ASP,又对Java有一定的了解的话,那么对这几种JSP内置对象的使用应该能迅速掌握。需要注意的问题是对象名的写法,包括这些对象方法的调用时也要书写正确,因为Java语言本身是大小写敏感的。
从本质上讲,JSP的这些内置对象其实都是由特定的Java类所产生的,在服务器运行时根据情况自动生成,所以如果你有较好的Java基础,可以参考相应的类说明,表3.1给出了他们的对应关系。更进一步的讲解将会在讲解Servlet的一章中展开,如果你的Java基础不太好,可以先熟悉在这一章里所介绍的各种方法的使用。
JSP内置对象映射表 | ||
---|---|---|
对象名 | 类型 | 作用域 |
request | javax.servlet.ServletRequest的子类 | Request |
response | javax.servlet.ServletResponse的子类 | Page |
PageContext | javax.servlet.jsp.PageContext | Page |
session | javax.servlet.http.HttpSession | Session |
application | javax.servlet.jsp.JspWriter | Page |
config | javax.servlet.ServletConfig | Page |
Page | java.lang.Object | Page |
exception | java.lang.Throwable | Page |
- “request” 对象代表的是来自客户端的请求,例如我们在FORM表单中填写的信息等,是最常用的对象 。 关 于 它 的 方 法 使 用 较 多 的 是getParameter 、 getParameterNames 和getParameterValues,通过调用这几个方法来获取请求对象中所包含的参数的值
<%@page import="org.apache.naming.java.javaURLContextFactory"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 这是HTML注释,发送给客户端 -->
<!-- <%= new java.util.Date() %> -->
<%-- 这是JSP注释,不发送给客户端 --%>
<form action="result.jsp" method="post">
username:<input type="text" name="username"><br>
password:<input type="password" name="password"><br>
repassword:<input type="password" name="repassword"><br>
age:<input type="text" name="age"><br>
age2:<input type="text" name="age"><br>
<input type="submit" value="submit">
<input type="reset" value="reset">
</form>
</body>
</html>
<% Enumeration<String> e = request.getParameterNames();
while(e.hasMoreElements()){
System.out.println(e.nextElement());
}
String[] values = request.getParameterValues("age");
for(String value : values){
System.out.println(value);
}
%>
结果是:
username
password
repassword
age
2342
2342
getParameter 方法是 getParameterValues 方法的特例,表示请求参数值只有一个,如果请求参数值有多个,请使用 getParameterValues方法。在多选框的情况下,需要使用 getParameterValues 方法来获取用户所选择的多个复选框的值。
- “response” 对象代表的是对客户端的响应,也就是说可以通过“response”对象来组织发送到客户端的数据。但是由于组织方式比较底层,所以不建议普通读者使用,需要向客户端发送文字时直接使用“out” 对象即可。
response多用于文件下载,在后面会讲。
session对象
“session” 对象代表服务器与客户端所建立的会话,当需要在不同的JSP页面中保留客户信息的情况下使用,比如在线购物、客户轨迹跟踪等。
概要
– HTTP是无状态(stateless)协议;
– Web Server 对每一个客户端请求都没有历史记忆;
– Session用来保存客户端状态信息;
application对象
“application” 对象负责提供应用程序在服务器中运行时的一些全局信息,常用的方法有getMimeType和getRealPath等。
out
“out” 对象代表了向客户端发送数据的对象,与“response” 对象不同,通过“out” 对象发送的内容将是浏览器需要显示的内容,是文本一级的,可以通过“out” 对象直接向客户端写一个由程序动态生成HTML文件。常用的方法除了print和println之外,还包括clear、clearBuffer 、 flush 、 getBufferSize 和getRemaining,这是因为“out” 对象内部包含了一个缓冲区,所以需要一些对缓冲区进行操作的方法。
config、page、exception
- “config” 对象提供一些配置信息,常用的方法有getInitParameter和getInitParameterNames,以获得Servlet初始化时的参数。
- “page” 对象代表了正在运行的由JSP文件产生的类对象,不建议一般读者使用。
- “exception” 对象则代表了JSP文件运行时所产生的异常对象,此对象不能在一般JSP文件中直接使用 , 而只能在使用了 “ <%@ pageisErrorPage="true "%>”的JSP文件中使用
request请求对象
- getAttribute
• 原型:public java.lang.Object getAttribute(java.lang.String name)
• 说明:以对象的形式返回特定名称的属性值。这个方法允许Servlet引擎给出一个客户请求的特定信息。
• 如果所给名称的属性不存在将返回空值。
• 参数:name 一个标示属性名的字符串
• 返回值:一个包含属性值的对象,当属性不存在时为空。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="request2.jsp">
username: <input type="text" name="username">
<input type="submit" value="submit">
</form>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<% String username = request.getParameter("username");%>
username: <%= username %>
<% request.setAttribute("username", username); %>
<%--
<jsp:forward page="request3.jsp"></jsp:forward>
--%>
<a href="request3.jsp">request3.jsp</a>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<% String username = (String)request.getAttribute("username"); %>
<%= username %>
</body>
</html>
结果是:
如果用forward结果如下:
-
request 的 setAttribute 与 getAttribute 方法一般都是成对出现的,首先通过 setAttribute 方 法 设 置 属 性 与 属 性 值 , 然 后 通 过getAttribute 方法根据属性获取到与该属性对应的对象值(获取到之后一般都需要进行向下类型转换,将属性值转换为真正的对象)。setAttribute 与 getAttribute 方法都是在服务器端内部执行的,客户端不知道服务器端是否执行过这两个方法。
-
request 的 getParameter 方法的作用是获取到客户端 通过表单或url 请求参数所发送过来的参数值,是客户端与服务器端之间的交互,服务器端要想获取到客户端发送过来的数据,就需要使用getParameter 方法来获取。没有与 getParameter 方法对应的setParameter 方法。
-
request 对象内数据的存活范围就是在 request 对象的存活范围内,当客户端向服务器端发送一个请求,服务器向客户端返回一个响应后,该请求对象就被销毁了;之后再向服务器端发送新的请求时,服务器会创建新的 request 对象,该 request 对象与之前的request 对象没有任何关系,因此也无法获得在之前的 request 对象中所存放的任何数据。
session对象
session 对象内数据的存活范围也就是 session 对象的存活范围(?只要浏览器不关闭,session 对象就会一直存在?),因此在同一个浏览器窗口中,无论向服务器端发送多少个请求,session 对象只有一个。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html><body>
<form action="session2.jsp">
姓名<input type="text" name="username">
<input type="submit" value="提交">
</form>
</body></html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@page import="java.util.*" %>
<HTML>
<BODY>
<%
String name=request.getParameter("username");
session.setAttribute("logName", name);
%>
你的名字"<%=name%>"已经写入session
<br>
<a href='session3.jsp'>check</a>
</BODY>
</HTML>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<HTML><BODY>
<%
String yourName=(String)session.getAttribute("logName");
if (yourName == null)
{
%>您还未登录
<%
}else
{
%>
"<%=yourName%>"已经登录
<%
}
%>
</BODY></HTML>
结果是:
application(应用对象)
网页计数器
<%--用application对象实现网页计数器peixun2.14.jsp文件代码--%<%@ page contentType="text/html;charset=gb2312"%><html><head><title>网页计数器</title><head><body><% if (application.getAttribute("counter")==null)application.setAttribute("counter","1");else{String strnum=null;strnum=application.getAttribute("counter").toString();int icount=0;icount=Integer.valueOf(strnum).intValue();icount++;application.setAttribute("counter",Integer.toString(icount));} %>您是第<%=application.getAttribute("counter")%>位访问者!</body></htm
结果是:
刷新后:
application(应用对象):存活范围最大的对象,只要服务器没有关闭,application 对象中的数据就会一直存在。在整个服务器运行过程当中,application 对象只有一个。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%--application对象示例,application2.jsp文件代码--%>
<head>
<title>application</title>
<head>
<body>
<% out.println("Java Servlet API Version "
+application.getMajorVersion()+"."
+application.getMinorVersion()+"<br>");
out.println("URL of 'application2.jsp' is: "
+application.getResource("/application2.jsp")+"<br>");
out.println("getServerInfo()="
+application.getServerInfo()+"<br>");
//getRealPath方法会返回资源在服务器上的绝对路径
out.println(application.getRealPath("application2.jsp"));
%>
<%-- getRealPath着重记住,当我们以后学文件上传时,
String newsPath = application.getRealPath("/news");
File file = new File(newPath,"新建文件夹");
file.mkdir();
--%>
</body>
</html>
结果是:
Java Servlet API Version 4.0
URL of ‘application2.jsp’ is: file:/E:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/JavaWeb/application2.jsp
getServerInfo()=Apache Tomcat/9.0.11
E:\workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\JavaWeb\application2.jsp
request、session以及application这3个对象的范围是逐个增加的:request 只在一个请求的范围内;?session 是在浏览器窗口的范围内?;application 则是在整个服务器的运行过程中。