目录
- 8. JSP
-
- 8.1 什么是JSP
- 8.2 JSP原理
- 8.3 JSP基础语法
- 8.4 JSP指令
- 8.5 九大内置对象
- 8.6 JSP标签、JSTL标签、EL表达式
-
- 8.6.1 JSP标签(JSP Actions)
-
- 定义:
- 常见标签:
- 示例代码:
- 注意事项:
- 8.6.2 EL 表达式(Expression Language)
-
- 定义:
- 语法格式:
- EL 访问对象范围:
- 示例:
- EL 运算符:
- 8.6.3 JSTL 标签库(JSP Standard Tag Library)
-
- 定义:
- 引入方式(在 JSP 页面顶部添加):
- 常用 JSTL 标签分类:
-
- 核心标签库(Core Tags)
- 格式化标签库(Fmt Tags)
- 函数标签库(Fn Tags)
- 8.6.4 面试高频问题(附参考答案)
- 8.6.5 总结
8. JSP
8.1 什么是JSP
Java Server Pages:Java服务端页面,和servlet一样,用于动态web技术
最大的特点:
- 写JSP就像在写html
- 区别:
- html只给用户提供静态的数据
- JSP页面中可以嵌入Java代码,为用户提供动态数据
8.2 JSP原理
思路:JSP是怎样执行的?
- 代码层面没有任何问题
- 服务器内部工作
- tomcat中有一个work目录;IDEA中使用tomcat的会在IDEA的tomcat中生产一个work目录
- 目录地址
我电脑上的地址:
C:\Users\Administrator\AppData\Local\JetBrains\IntelliJIdea2021.2
发现页面会被转换成为一个Java类!
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
JSP最终也会被转换成为一个Java类!
JSP本质上就是一个Servlet
// 初始化
public void _JSPInit() {
}
// 销毁
public void _JSPDestroy() {
}
// JSPservice
public void _JSPService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
- 判断请求的方式
- 内置一些对象(9个)
final javax.servlet.JSP.PageContext pageContext; // 页面上下文
javax.servlet.http.HttpSession session = null; // session
final javax.servlet.ServletContext application; // applicationContext
final javax.servlet.ServletConfig config; // config
javax.servlet.JSP.JSPWriter out = null; // out
final java.lang.Object page = this; // page:当前
HttpServletRequest request; // 请求
HttpServletResponse response; // 响应
- 输出页面前增加的代码
response.setContentType("text/html;charset=UTF-8");// 设置响应的页面类型
pageContext = _JSPxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_JSPx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_JSPx_out = out;
- 以上的内置对象可以在JSP页面中直接使用
- 原理图
在JSP页面中;
只要是 JAVA
代码就会原封不动的输出;
如果是 HTML
代码,就会被转换为:
out.write("<html>\r\n");
out.write("<head>\r\n");
这样的格式,输出到前端!
8.3 JSP基础语法
JSP作为java技术的一种应用,它拥有一些自己扩充的语法,Java所有语法它都支持!
- JSP 表达式
<%--JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或表达式%>
--%>
<%= new java.util.Date() %>
- JSP 脚本
<%--JSP脚本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
out.print("<h1>sum="+sum+"</h1>");
%>
//--------------------------
<%--EL表达式:${变量} --%>
<%
for (int i = 0; i < 3; i++) {
%>
<h1>Hello World! ${i}</h1>
<%
}
%>
- JSP声明
<%!
static {
System.out.println("loading Servlet!");
}
private int globalVar =0;
public void kuang(){
System.out.println("进入了该方法!");
}
%>
JSP
声明会被编译到JSP生成java的类中,其他的会被生成到 _JSPService
方法中
8.4 JSP指令
- 定制错误页面
<%--定制错误页面--%>
<%@ page errorPage="error/500.JSP" %>
或者在web.xml定制全局的错误页面
- 包含头部和尾部
8.5 九大内置对象
- PageContext
存东西
- Request
存东西
- Response
- Session
存东西
- Application(ServletContext)
存东西
- Config(ServletConfig)
- out
- page
- exception
存东西的区别
pageContext.setAttribute("name1","张三1"); // 保存的数据只在一个页面中有效
request.setAttribute("name2","张三2"); // 保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","张三3"); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","张三4"); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器
request
:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!
session
:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;
application
:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;
8.6 JSP标签、JSTL标签、EL表达式
8.6.1 JSP标签(JSP Actions)
定义:
JSP 标准动作标签是 JSP 内置的一组 XML 风格的标签,用于控制页面行为、操作 JavaBean、引入资源等。
常见标签:
标签 | 功能说明 |
---|---|
<JSP:include> |
包含另一个资源(相当于动态 include) |
<JSP:forward> |
请求转发到另一个资源 |
<JSP:useBean> |
创建或查找一个 JavaBean 实例 |
<JSP:setProperty> |
设置 JavaBean 属性 |
<JSP:getProperty> |
获取 JavaBean 属性值 |
示例代码:
<JSP:useBean id="user" class="com.example.User" scope="request"/>
<JSP:setProperty name="user" property="name" value="张三"/>
<JSP:getProperty name="user" property="name"/>
注意事项:
scope
可选值:page / request / session / application- 推荐与 EL 表达式配合使用,避免直接写 Java 脚本
8.6.2 EL 表达式(Expression Language)
定义:
EL 表达式是一种简化版的表达式语言,用来替代 JSP 中的 <% ... %>
和 <JSP:getProperty>
,使页面更简洁、易读。
语法格式:
${expression}
EL 访问对象范围:
EL 对象 | 作用域 |
---|---|
${pageScope} |
page 作用域 |
${requestScope} |
request 作用域 |
${sessionScope} |
session 作用域 |
${applicationScope} |
application 作用域 |
示例:
欢迎用户:${user.name} <br>
当前访问路径:${pageContext.request.requestURI} <br>
请求方法:${pageContext.request.method}
EL 运算符:
类型 | 示例 |
---|---|
算术运算 | ${5 + 3} |
比较运算 | ${age > 18} |
逻辑运算 | ${user != null && user.age > 20} |
条件判断 | ${score >= 60 ? '及格' : '不及格'} |
8.6.3 JSTL 标签库(JSP Standard Tag Library)
定义:
JSTL 是一组标准的自定义标签库,提供通用功能如条件判断、循环、URL 处理、国际化等。
引入方式(在 JSP 页面顶部添加):
<%@ taglib prefix="c" uri="http://java.sun.com/JSP/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/JSP/jstl/fmt" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/JSP/jstl/functions" %>
常用 JSTL 标签分类:
核心标签库(Core Tags)
标签 | 功能 |
---|---|
<c:set> |
设置变量 |
<c:out> |
输出内容(可转义 HTML) |
<c:if> |
条件判断 |
<c:choose>/<c:when>/<c:otherwise> |
多条件分支 |
<c:forEach> |
循环遍历 |
<c:forTokens> |
拆分字符串循环 |
<c:url> |
构造 URL |
<c:redirect> |
重定向 |
<c:import> |
导入外部 URL 内容 |
示例:
<c:set var="name" value="李四" />
<c:out value="${name}" escapeXml="true"/>
<c:if test="${age > 18}">
成年人
</c:if>
<c:forEach items="${users}" var="user">
${user.name} - ${user.age}<br>
</c:forEach>
格式化标签库(Fmt Tags)
标签 | 功能 |
---|---|
<fmt:formatDate> |
格式化日期时间 |
<fmt:parseDate> |
解析日期时间 |
<fmt:formatNumber> |
格式化数字、货币 |
<fmt:message> |
国际化消息显示 |
示例:
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss" />
<fmt:formatNumber value="12345.6789" type="currency" currencySymbol="¥"/>
函数标签库(Fn Tags)
函数 | 功能 |
---|---|
fn:length() |
获取集合/字符串长度 |
fn:contains() |
判断是否包含某子串 |
fn:split() |
分割字符串 |
fn:join() |
合并数组为字符串 |
示例:
<c:if test="${fn:contains(name, 'Tom')}">
名字中包含 Tom
</c:if>
长度:${fn:length("Hello World")}
使用场景 | 推荐做法 |
---|---|
页面展示数据 | 使用 EL 表达式 |
控制流程 | 使用 JSTL 标签 |
避免 Java 脚本 | 尽量不用 <% ... %> |
MVC 分离 | JSP 只做展示,业务逻辑交给 Servlet 或 Controller |
国际化支持 | 使用 <fmt:message> 结合 properties 文件 |
安全输出 | 使用 <c:out> 防止 XSS 攻击 |
8.6.4 面试高频问题(附参考答案)
Q1:EL 表达式中的 .
和 []
有什么区别?
A:.
用于访问属性名固定的对象字段;[]
可以动态传 key,也支持带特殊字符的属性名,例如:${map['user-name']}
。
Q2:JSTL 标签为什么比 Java 脚本更好?
A:因为 JSTL 是标签形式,更易于维护、阅读,且更适合美工或前端人员参与开发,同时避免了大量 Java 代码混杂在 HTML 中的问题。
Q3:如何防止 EL 表达式被忽略?
A:在 web.xml
中设置 JSP 默认启用 EL:
<JSP-config>
<JSP-property-group>
<url-pattern>*.JSP</url-pattern>
<el-ignored>false</el-ignored>
</JSP-property-group>
</JSP-config>
Q4:JSTL 的 <c:forEach>
和 Java 的 for 循环有什么不同?
A:<c:forEach>
是标签库实现的循环,底层由 Java 代码处理,但它是声明式的,适合嵌入 HTML 页面中使用,而 Java 的 for 是命令式的,用于后端逻辑。
8.6.5 总结
在现代 JSP 开发中,应尽量避免使用
<% ... %>
脚本,而是使用 EL 表达式 + JSTL 标签库 来完成页面逻辑,这样不仅结构清晰,而且更符合 MVC 设计模式。