1. 简介
需要准备以下软件工具:
- Eclipse 4.6(NEON)
- Tomcat Web Server 9.x
在开始学习JSP之前,建议你了解Servlet。可以通过以下链接访问学习:
- Java Servlet初学者教程
2. 安装Tomcat Web服务器
要编写和运行JSP程序,需要下载Tomcat Web Server并在Eclipse中对它进行配置声明。可以在此处查看说明:
- 在Eclipse中安装和配置Tomcat服务器
3. 创建JSP项目
在Eclipse中,选择:
然后输入项目名称:JspTutorial,如下所示:
创建项目成功后,目录结构如下所示:
接下来,创建一个简单的JSP文件,选择File/New/Other...,
填写新创建的JSP文件名称:index.jsp,如下所示:
可以选择一个模板,这里按默认选择,如下所示:
文件:index.jsp 已创建,但是可能有错误通知。不用担心 这是未声明Servlet库的结果。接下来使用Tomcat的Servlet库以及Web服务器的配置来运行此项目就可以了。
接下来简单的修改这个JSP文件,以打印当前系统时间。修改后的代码如下所示:
文件:index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
第一个JSP程序
Hello JSP
<%
java.util.Date date = new java.util.Date();
%>
当前时间: <%=date.toString()%>
4. 配置Tomcat Web服务器并运行WebApp
右键单击“JspTutorial”项目,然后选择“属性(Properties)”,选择Project Facets,如下图所示:
然后点击:Apply and Close,就可以了。
现在,“JspTutorial”项目应该没有错误提示通知了。如下图所示:
右键单击项目,然后选择“Run As/Run on Server”。
运行应用程序得到结果如下:
以下是程序的执行流程:
访问以下URL => http://localhost:8080/JspTutorial/index.jsp ,得到同样的结果:
5. JSP和Servlet的关系
当用户向JSP页面发送请求时,例如hello.jsp页面:
第一次,Web Server将hello.jsp
页更改为hello_jsp.java
文件,并将其编译为hello_java.class
。 这是一个Servlet,它将创建HTML以响应用户的请求。
从第二次请求开始,它将检查hello.jsp
文件是否有任何更改。 如果没有更改,它将调用servlet(hello_jsp.class)并将HTML数据回复给用户。 如果有更改,它将重新创建hello_jsp.java
并将其重新编译为hello_jsp.class
文件。
因此,当更改jsp文件时,不需要重新运行Web服务器。
6. JSP示例
6.1. JSP中的预定义变量
导入声明 -
<%@ page import="java.util.*, java.text.*" %>
<%@ page import="java.util.List, java.text.*" %>
在JSP中的预定义变量,可以使用:
-
equest
:javax.servlet.http.HttpServletRequest
-
response
:javax.servlet.http.HttpServletResponse
-
out
:javax.servlet.jsp.JspWriter
如下示例:
<%
// Using out variable:
out.println("Now is "+ new Date()+"
");
// Using request variable:
String serverName= request.getServerName();
// Using response variable:
response.sendRedirect("http://eclipse.org");
%>
6.2. HTML(JSP)中的Java代码
创建一个新的jsp文件:demo/javaInHtml.jsp,代码如下:
<%@ page import="java.util.Random,java.text.*"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
返回随机数
<%
Random random = new Random();
// 返回随机数: (0, 1 or 2)
int randomInt = random.nextInt(3);
if (randomInt == 0) {
%>
0.随机数是:<%=randomInt%>
<%
} else if (randomInt == 1) {
%>
1.随机数是:<%=randomInt%>
<%
} else {
%>
2.随机数是:<%=randomInt%>
<%
}
%>
重新试一下
访问以下URL: http://localhost:8080/JspTutorial/demo/javaInHtml.jsp ,得到以下结果:
如果在浏览器中查看生成的HTML代码,应该会发现生成的代码有变化。
6.3. 在JSP定义方法
本质上,JSP最终被编译为Servlet(一个类)。 因此,JSP还允许在其中创建方法,就和Java中的方法一样。方法在标记<%!
和!%>
内部声明。
<%!
// 定义一个方法
public int sum(int a, int b) {
return a + b;
}
public void exampleMethod() {
// Code here
}
%>
在JSP定义方法的示例文件:methodInJsp.jsp
<%!
public int sum(int a, int b) {
return a + b;
}
%>
在JSP定义方法
1 + 2 = <%=sum(1, 2)%>
7. JSP指令
JSP指令为容器提供了指导和说明,告诉容器如何处理JSP的某些方面。以下是JSP中的指令和说明:
指令 | 说明 |
---|---|
<%@ page ... %> |
定义与页面有关的属性,例如脚本语言,错误页面和缓冲要求。 |
<%@ include ... %> |
在编译阶段包含文件。 |
<%@ taglib ... %> |
声明在页面中使用的包含自定义操作的标记库。 |
7.1. JSP指令page
page
指令用于提供与容器当前JSP页面相关的指令。可以在JSP页面中的任何位置使用page
指令代码。 按照惯例,page
指令位于JSP页面的顶部。
属性 | 目的 | 描述 |
---|---|---|
buffer |
指定输出流的缓冲模型。 | |
autoFlush |
控制Servlet输出缓冲区的行为。 | |
contentType |
定义字符编码方案。 | contentType="text/html;charset=UTF8" |
errorPage |
定义另一个报告Java未经检查的运行时异常的JSP的URL。 | errorPage="error.jsp" |
isErrorPage |
指示此JSP页面是否是另一个JSP页面的errorPage 属性指定的URL。 |
|
extends |
指定生成的servlet必须扩展的超类 | extends="com.Xntutor.MyServlet" |
import |
指定要在JSP中使用的软件包或类的列表,就像Java import 语句对Java类所做的那样。 |
import="java.io.*, java.utils.List" |
info |
定义一个可以使用servlet的getServletInfo() 方法访问的字符串。 |
info="Login Page" |
isThreadSafe |
为生成的servlet定义线程模型。 | |
language |
定义JSP页面中使用的编程语言。 | language = "java" |
session |
指定JSP页面是否参与HTTP会话 | |
isELIgnored |
指定是否将忽略JSP页面内的EL表达式。 | |
isScriptingEnabled |
确定是否允许使用脚本元素。 | - |
例如,在指令<%@ page ... %>
中使用errorPage
属性。创建两个新文件:
文件:pageHasError.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" errorPage ="error.jsp"%>
<%@ page errorPage ="error.jsp"%>
有错误页面
有错误页面
<%
// Error divided by 0
int i = 10 / 0;
%>
文件:error.jsp
<%@ page isErrorPage="true" import="java.io.*"%>
错误
页面中有些错误
错误信息如下:
<%=exception.getMessage()%>
StackTrace:
<%
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
exception.printStackTrace(printWriter);
out.println("");
out.println(stringWriter);
out.println("
");
printWriter.close();
stringWriter.close();
%>
运行并访问页面:pageHasError.jsp
- http://localhost:8080/JspTutorial/demo/pageHasError.jsp
7.2. JSP指令include
JSP允许在JSP页面编译变成Servlet时将文件内容嵌入到JSP中。示例:
<%@ include file="url" %>
<%@ include file = "header.html" %>
<%@ include file = "footer.html" %>
<%@ include file = "fragment.jsp" %>
在下面示例中,将创建几个文件 -
文件:header.html
我的页面
搜索:
文件:footer.html
@Copyright xntutor.com
文件:includeDemo.jsp
<%@ page import="java.util.Random,java.text.*"%>
Jsp Include指令示例
<%@ include file="../fragment/header.html"%>
Jsp初学教程
Hi! This is Jsp Tutorial...
<%@ include file="../fragment/footer.html"%>
8. JSP标准动作
标准动作是在JSP本身中定义的动作,不需要使用taglib
指令进行声明。JSP中的所有标准动作都有一个默认前缀jsp
。
因此,从本质上讲,JSP标准动作是JSP的大量可用标记。 按照惯例,它们集成在JSP页面中,无需通过声明指令<%@ taglib ... %>
来声明。
以下是JSP中的标准动作列表:
语法 | 目的 |
---|---|
jsp:include |
在请求页面时包含一个文件。 |
jsp:useBean |
查找或实例化JavaBean |
jsp:setProperty |
设置JavaBean的属性 |
jsp:getProperty |
将JavaBean的属性插入输出到页面 |
jsp:forward |
将请求者转发到新页面 |
jsp:plugin |
生成特定于浏览器的代码,为Java插件创建OBJECT 或EMBED 标签 |
jsp:element |
动态定义XML元素。 |
jsp:attribute |
使用jsp:attribute 元素,可以在XML元素的主体中而不是XML属性的值中定义标记属性的值。 |
jsp:body |
定义动态定义的XML元素的主体。 |
jsp:text |
用于在JSP页面和文档中编写模板文本。 |
8.1. JSP动作jsp:include
用于在请求时将页面嵌入JSP。相反,指令<%@ include %>
在将JSP解析为Servlet时将文件嵌入JSP。
参见示例:
文件:fragment/dateTime.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.Date,java.text.*"%>
当前时间
<%
Date now = new Date();
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss SSS");
%>
当前时间:
<%=df.format(now)%>
文件:demo/jspIncludeDemo.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
JSP Action jsp:include
JSP动作jsp:include示例:
jspIncludeDemo.jsp
的运行结果如下:
- http://localhost:8080/JspTutorial/demo/jspIncludeDemo.jsp
8.2. JSP动作jsp:useBean
jsp:useBean
动作用于操作Java类,首先创建一个类和一个JSP文件,如下图所示:
文件:HelloBean.java
package com.xntutor.beans;
public class HelloBean {
private String name;
// Class is required default constructor.
public HelloBean() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHello() {
if (name == null) {
return "Hello,大家好";
}
return "Hello " + name;
}
}
文件:usebean.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
使用Bean
调用HelloBean类的getName()方法:
调用HelloBean类的setName()方法
运行usebean.jsp,得到以下结果:
- http://localhost:8080/JspTutorial/demo/usebean.jsp
8.3. JSP动作 jsp:element,jsp:attribute和jsp:body
在某些情况下,我们可能想用xml数据回复用户,以换取HTML数据。 结合使用
,
和
可使代码易于阅读。 让我们来看看下面这些组合的例子。
JSP本质上是带有HTML标记的文件。 因此,最好使用HTML标记或JSP定制标记,而不是在JSP中插入Java代码。 这使代码易于阅读和理解。创建一个Java类文件和一个JSP文件,如下所示:
文件:Employee.java
package com.xntutor.beans;
public class Employee {
private String empNo;
private String empName;
public Employee() {
}
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
}
文件:jspelement.jsp
<%@ page pageEncoding="UTF-8"%>
请查看此页面的源代码
<%-- Create Employee object and setting value for its fields --%>
运行上面代码,得到以下结果:
- http://localhost:8080/JspTutorial/demo/jspelement.jsp
让我们看看在不使用jsp:element/attribute/body
标记的情况下的JSP代码。
<%@ page pageEncoding="UTF-8"%>
Please view source of this page
<%-- Create Employee and set value for its fields --%>
<%=emp.getEmpName()%>
9. JSP表达语言
通过JSP表达式语言(EL),可以轻松访问存储在JavaBeans组件中的应用程序数据。 JSP EL允许创建算术表达式和逻辑表达式。 在JSP EL表达式中,可以使用整数,浮点数,字符串,布尔值的内置常量true
和false
以及null
。
JSP EL已从2.0
版添加到JSP。 这是一种替换表达式标记<%=expression%>
的用法。应该在JSP页面上的任何地方使用JSP EL代替使用JSP 表达式标签。
语法:
${expression}
下面来看看一个例子 -
文件:jspel.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
JSP表达式语言
员工:
员工姓名:
运行上面示例代码,得到以下结果:
10. 表单处理
在Web应用程序中,处理表单是最重要的功能之一。下面是表单处理示例中涉及的两个文件:
- form.html
- formProcessing.jsp
注意:这只是一个示例,我们应该通过Servlet而不是JSP来处理表单数据。JSP应该仅用于显示内容。
用户将在form.html
上的表单上输入信息,并将该信息发送到formProcessing.jsp
,由formProcessing.jsp
负责接收和处理。
文件:form.html
JSP表单处理(xntutor.com)
用户注册表单
文件:formProccess.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
表单处理结果
你提交的注册信息:
<%
String userName = request.getParameter("userName");
String password = request.getParameter("password");
String gender = request.getParameter("gender");
String[] addresses = request.getParameterValues("address");
%>
用户名:<%=userName%>
密码:<%=password%>
性别: <%=gender%>
<%
if (addresses != null) {
for (String address : addresses) {
%>
地址:
<%=address%>
<%
}
}
%>
运行上面示例代码,得到以下结果:
10.1. GET方法
form.html
文件的代码中表单使用GET
方法提交:。运行上面代码
- http://localhost:8080/JspTutorial/demo/form.html
填写表单后提交。浏览器将地址栏更改为formProcessing.jsp
页面,并带有用参数括起来的URL地址。这是由于使用表格的GET方法所致。
- http://localhost:8080/JspTutorial/demo/formProcessing.jsp?userName=user001&password=&gender=%E4%B7&address=%E6%%82&address=%E4%F%B7&address=xx%E7%A6
10.2. POST方法
如果在上更改属
性method="POST"
,如下所示:
输入数据,然后单击提交。浏览器将地址栏更改为formProcessing.jsp
页面,URL中不包括附带的参数和值,而数据则隐藏地发送到formProcessing.jsp
中。
10.3. 表单处理
formProcessing.jsp
将获取通过getParameter()
发送给它的数据,数据可以附加在URL上(GET
方法),或包含在请求的正文中(POST
方法)。
// 获取参数 'userName' 值
String userName = request.getParameter("userName");
// 获取参数 'address' 值列表
String[] addresses = request.getParameterValues("address");
用户输入多个地址信息,并单击提交后得到以下结果:
11. Cookie处理
Cookies是存储在客户端计算机上的文本文件,保留它们用于各种信息跟踪目的。 JSP使用基础的servlet技术透明地支持HTTP cookie。
为了方便演示,下面创建两个文件:CookieUtils.java 和 demo/cookie.jsp。
文件:CookieUtils.java
package com.xntutor.utils;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspWriter;
public class CookieUtils {
public static void demoUserCookie(HttpServletRequest request, HttpServletResponse response, JspWriter out)
throws IOException {
boolean found = false;
// Get an array of Cookies associated with this domain
Cookie[] cookies = request.getCookies();
if (cookies != null && cookies.length > 0) {
String userName = null;
String lastLoginDatetime = null;
out.println("Cookies:
");
for (int i = 0; i < cookies.length; i++) {
out.println(cookies[i].getName() + " : " + cookies[i].getValue() + "
");
if (cookies[i].getName().equals("userName")) {
userName = cookies[i].getValue();
} else if (cookies[i].getName().equals("lastLoginDatetime")) {
lastLoginDatetime = cookies[i].getValue();
}
}
if (userName != null) {
found = true;
out.println("Last login info:
");
out.println("User Name: " + userName + "
");
out.println("Last Login Datetime: " + lastLoginDatetime + "
");
}
}
if (!found) {
out.println("No cookies founds!, write some cookies into client computer
");
// Storing user information in cookies
// for example userName.
// Simulation Cookie stored on a user's computer, as soon as the user login is
// successful
String userName = "Xntutor.com";
Cookie cookieUserName = new Cookie("userName", userName);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String lastLoginDatetime=df.format(new Date());
//String lastLoginDatetime = df.format(now);
out.println(lastLoginDatetime);
Cookie cookieLoginDatetime = new Cookie("lastLoginDatetime", lastLoginDatetime);
// Sets the maximum age in seconds for this Cookie. (24h)
cookieUserName.setMaxAge(24 * 60 * 60);
// Sets the maximum age in seconds for this Cookie. (24h)
cookieLoginDatetime.setMaxAge(24 * 60 * 60);
// Store in the user's computer.
response.addCookie(cookieUserName);
// Store in the user's computer.
response.addCookie(cookieLoginDatetime);
}
}
}
文件:cookie.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="com.xntutor.utils.CookieUtils" %>
Cookie示例(xntutor.com)
<%
CookieUtils.demoUserCookie(request,response, out);
%>
重试一下
运行上面示例代码,得到以下结果: