1 JSP注释
1.1 显示注释
显示注释会出现在生成的HTML文档中,对用户可见。
<!-- 这是一个HTML显示注释 -->
1.2 隐式注释
隐式注释不会出现在生成的HTML文档中,对用户不可见。
<%-- 这是一个JSP隐式注释 --%>
2 JSP脚本元素
2.1 局部变量和语句
使用<% %>
编写局部变量和语句。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP脚本元素</title>
</head>
<body>
<%
String message = "欢迎来到JSP世界!";
%>
<h1><%= message %></h1>
</body>
</html>
2.2 全局变量、方法和类
使用<%! %>
声明全局变量、方法和类。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP脚本元素</title>
</head>
<body>
<%!
public String getMessage() {
return "欢迎来到JSP世界!";
}
%>
<h1><%= getMessage() %></h1>
</body>
</html>
2.3 表达式
使用<%= %>
输出表达式的值。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP脚本元素</title>
</head>
<body>
<h1>当前时间:<%= new java.util.Date() %></h1>
</body>
</html>
2.4 JSP Include
<jsp:include>
动作用于动态包含另一个JSP页面的内容。这对于避免重复代码非常有用,例如在多个页面中包含相同的头部和尾部内容。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP Include</title>
</head>
<body>
<jsp:include page="header.jsp" />
<p>这是主页面的内容。</p>
<jsp:include page="footer.jsp" />
</body>
</html>
3 动态包含
动态包含是指在一个JSP页面中动态地包含另一个JSP页面的内容。这种包含方式是动态的,因为被包含的页面只有在请求到来时才会被加载。
3.1 特点
-
包含与被包含的页面是独立的,它们各自有自己的生命周期和作用域。
-
可以出现同名变量。由于每个页面都有自己的作用域,因此即使变量名相同,也不会发生冲突。
-
动态包含可以传递参数,这使得被包含的页面可以根据传递的参数动态地生成内容。
3.2 示例
假设我们有两个JSP页面:main.jsp
和 included.jsp
。
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Dynamic Include Example</title>
</head>
<body>
<h1>Main Page</h1>
<jsp:include page="included.jsp" />
</body>
</html>
included.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<h2>Included Page</h2>
在这个例子中,当用户访问 main.jsp
时,服务器会动态地包含 included.jsp
的内容。
4 四大作用域
在JSP中,有四种不同类型的作用域,它们决定了变量的生命周期和可见性。
4.1 Page作用域
-
生命周期:仅限于当前页面。
-
可见性:只在当前页面内可见。
-
当页面跳转时,Page作用域内的变量将失效。
4.2 Request作用域
-
生命周期:一次HTTP请求。
-
可见性:在整个请求处理过程中可见,包括转发和包含操作。
-
超链接跳转后,Request作用域内的变量仍然有效。
4.3 Session作用域
-
生命周期:一次用户会话。
-
可见性:在整个用户会话期间可见。
-
当用户关闭浏览器或会话超时后,Session作用域内的变量将失效。
4.4 Application作用域
-
生命周期:整个Web应用程序的生命周期。
-
可见性:在整个Web应用程序中可见。
-
只有在应用程序重启后,Application作用域内的变量才会失效。
4.5 示例代码
使用不同作用域的变量
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Scope Example</title>
</head>
<body>
<% // Page作用域的变量
String pageVar = "This is a page scope variable.";
// Request作用域的变量
request.setAttribute("requestVar", "This is a request scope variable.");
// Session作用域的变量
session.setAttribute("sessionVar", "This is a session scope variable.");
// Application作用域的变量
application.setAttribute("applicationVar", "This is an application scope variable.");
%>
<h1>Page Scope Variable:</h1>
<%= pageVar %>
<h1>Request Scope Variable:</h1>
<%= request.getAttribute("requestVar") %>
<h1>Session Scope Variable:</h1>
<%= session.getAttribute("sessionVar") %>
<h1>Application Scope Variable:</h1>
<%= application.getAttribute("applicationVar") %>
</body>
</html>
5 案例代码
5.1 编写代码
5.1.1 后端验证
创建一个简单的用户类User.java
:
public class User {
private String username;
private String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
创建一个ServletLoginServlet.java
来处理登录请求:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
private User user = new User("admin", "password"); // 模拟用户数据
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
HttpSession session = request.getSession();
session.setAttribute("user", username);
response.sendRedirect("index.jsp");
} else {
response.sendRedirect("login.jsp?error=true");
}
}
}
5.1.2 前端登录页面
创建一个HTML文件login.html
作为登录页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="LoginServlet" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username" required>
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
<br>
<input type="submit" value="Login">
</form>
<% if (request.getParameter("error") != null) { %>
<p style="color: red;">Invalid username or password.</p>
<% } %>
</body>
</html>
5.1.3 首页显示用户名
创建一个JSP文件index.jsp
作为首页:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Index</title>
</head>
<body>
<h1>Welcome to the Index Page</h1>
<% if (session.getAttribute("user") != null) { %>
<p>Hello, <%= session.getAttribute("user") %>!</p>
<% } else { %>
<p>Please login first.</p>
<% } %>
<a href="login.html">Login</a>
</body>
</html>
5.1.4 配置Web应用程序
- 在
web.xml
文件中配置LoginServlet
:
<web-app>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
</web-app>
- 将
login.html
、index.jsp
、User.java
和LoginServlet.java
文件放置在正确的目录下。
6 EL表达式(Expression Language)
EL表达式是JSP的一部分,用于简化数据访问和操作。它允许开发者在JSP页面中直接访问JavaBean属性、集合元素以及请求作用域属性。
6.1 EL表达式的基本用法
-
使用
${}
来包裹要访问的变量或属性。 -
EL表达式默认从
pageScope
开始查找属性,如果没有找到,会继续查找requestScope
、sessionScope
和applicationScope
。 -
如果找不到对应的属性,EL表达式会返回空字符串(而不是抛出异常)。
6.2 EL表达式获取值
-
List :通过索引访问列表元素,如
${list[0]}
。也可以使用${list.size()}
来获取列表的大小(但注意这不是EL标准用法,应使用JSTL的<c:forEach>
配合varStatus
属性)。 -
Map :通过键访问映射元素,如
${map.key}
。 -
JavaBean :通过属性名访问JavaBean属性,如
${bean.propertyName}
。
7 JSTL(JavaServer Pages Standard Tag Library)
JSTL是一组标准的JSP标签库,用于简化JSP页面的开发。
7.1 核心标签库
-
条件判断 :
<c:if>
标签用于条件判断,但没有else
部分。 -
循环 :
<c:forEach>
标签用于遍历集合。
7.2 格式化标签库
- 格式化日期 :
<fmt:formatDate>
标签用于格式化日期。
7.3 使用taglib引入标签库
- 使用
<%@ taglib %>
指令引入标签库,并通过prefix
属性指定前缀。
7.4 案例代码
7.4.1 EL表达式示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head>
<title>EL Expression Example</title>
</head>
<body>
<%
// 设置作用域属性
pageContext.setAttribute("name", "Alice");
request.setAttribute("city", "New York");
session.setAttribute("country", "USA");
application.setAttribute("hobby", "Reading");
%>
<p>Name: ${name}</p>
<p>City: ${city}</p>
<p>Country: ${country}</p>
<p>Hobby: ${hobby}</p>
</body>
</html>
7.4.2 JSTL核心标签库示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<title>JSTL Core Tags Example</title>
</head>
<body>
<%
// 设置作用域属性
request.setAttribute("numbers", Arrays.asList(1, 2, 3, 4, 5));
%>
<c:if test="${not empty numbers}">
<ul>
<c:forEach items="${numbers}" var="num">
<li>${num}</li>
</c:forEach>
</ul>
</c:if>
</body>
</html>
7.4.3 JSTL格式化标签库示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<title>JSTL Format Tags Example</title>
</head>
<body>
<%
Date now = new Date();
pageContext.setAttribute("now", now);
%>
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss" />
</body>
</html>