JSP
一、JSP
1. 简介
JSP(全称Java Server Pages)是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。
JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。
JSP文件后缀名为 *.jsp 。
JSP开发的WEB应用可以跨平台使用,既可以运行在 Linux 上也能运行在 Windows 上。
2. 执行原理
jsp是一种后端技术,它的原理是:
第一次发送请求访问jsp资源时,Tomcat服务器中的JSP加载引擎会将该jsp资源转换成 .java文件。这个java文件其实就是一个Servlet,其中html的代码通过响应流writer.print()的方式响应回浏览器。
3. 执行过程
JSP的执行过程大致可以分为三个时期:转换、编译、执行。
转换/翻译(trranslation)
Tomcat中的JSP引擎将JSP网页转换成一个 .java文件,即一个servlet
编译(compile)
通过javac命令将转换得到的 .java文件编译成 .class文件
运行
运行 .class字节码文件,处理请求。
具体流程:
①浏览器发起请求访问jsp
②Tomcat服务器收到请求,调用对应的Servlet处理请求,调用的是JSPServlet
③JspServlet将请求的jsp文件 翻译成 .java文件并完成编译得到字节码文件
④将编译后的class文件加载到内存并执行,即运行了一个servlet
⑤servlet执行service()方法将结果响应回浏览器。
注意:当JSP页面在执行时,JSP 引擎会做检查工作,
如果没有更新,就直接执行之前转换好的Servlet;
如果发现JSP页面中有更新修改时,JSP引擎会再次转换JSP为Servlet。
4. JSP性能问题
JSP和HTML相比的话肯定是要慢些的,他们的机制就不一样,JSP本质上是Servlet,在请求jsp时,要经过执行,其内部是通过大量的IO流形式将内容发送给页面的,IO流就是一种比较耗费资源的操作。而HTML本身资源是已经存在的,不需要服务器执行什么操作。
5. JSP加载引擎
在Tomcat的 conf/web.xml文件中配置了JSP的加载引擎 JspServlet
<servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>fork</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>xpoweredBy</param-name> <param-value>false</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspx</url-pattern> </servlet-mapping>
可以发现所有 xxx.jsp的请求都会调用jsp加载引擎JspServlet。
JspServlet作用:
转换JSP页面
将Jsp页面转换成一个Servlet
编译Jsp对应的java文件
JSP引擎调用Java编译器对这个Servlet进行编译,得到.class文件
请求处理
JSP引擎调用java虚拟机来执行class文件,即执行servlet,将结果响应回浏览器
6. JSP继承结构
JSP文件转换成JAVA代码之后,它默认继承了HttpJspBase,实现了JspSourceDependent,和JspSourceImports两个接口,
其中HttpJspBase又继承了HttpServlet ,也就是说,JSP本质上就是一个Servlet。
-
-
并且自定义了 jspInit, jspService, jspDestory。
-
然后在重写的init方法中调用了 JSPInit,在重写的service方法中调用了 jspService,在重写的destory方法中调用了 jspDestory。
-

public abstract class HttpJSPBase extends HttpServlet implements HttpJSPPage { private static final long serialVersionUID = 1L; protected HttpJSPBase() { } @Override public final void init(ServletConfig config) throws ServletException { super.init(config); JSPInit(); _JSPInit(); } @Override public String getServletInfo() { return Localizer.getMessage("JSP.engine.info", Constants.SPEC_VERSION); } @Override public final void destroy() { JSPDestroy(); _JSPDestroy(); } @Override public final void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { _JSPService(request, response); } @Override public void JSPInit() { } public void _JSPInit() { } @Override public void JSPDestroy() { } protected void _JSPDestroy() { } @Override public abstract void _JSPService(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException; }
二、JSP的使用
1. 在JSP中写Java代码
在jsp中可以通过 <%%> 、 <%!%>和<%= %> 三种方式来书写代码
这两种方式中写的Java代码在转换后生成的代码在Servlet中位置是不一样的,
<%%> 在_jspService方法中(局部变量);
<%!%>在Servlet中作为类的成员。JSP本质上是Servlet,在Servlet中我们是不推荐定义一些成员变量的。
<%= %>也是在_jspService方法中,但会直接将其中的内容响应给浏览器
2. 注释
JSP的注释格式是:<%--注释内容--%>
注释类型 | 进入转译文件 | 响应给浏览器 |
---|---|---|
JSP注释 | no | no |
JAVA注释 | yes | no |
HTML,css,js注释 | yes |
<%@ directive attribute="value" %>
指令 | 描述 |
---|---|
<%@ page %> | 定义网页依赖属性,如脚本语言、error页面、缓存需求等等 |
<%@ include %> | 包含其他文件 |
<%@ taglib %> |
2. page指令标签
属性 | 描述 |
---|---|
buffer | 指定out对象使用缓冲区的大小 |
autoFlush | 控制out对象的 缓存区 |
contentType | 指定当前JSP页面的MIME类型和字符编码 |
errorPage | 指定当JSP页面发生异常时需要转向的错误处理页面 |
isErrorPage | 指定当前页面是否可以作为另一个JSP页面的错误处理页 |
extends | 指定servlet从哪一个类继承 |
import | 导入要使用的Java类 |
info | 定义JSP页面的描述信息 |
isThreadSafe | 指定对JSP页面的访问是否为线程安全 |
language | 定义JSP页面所用的脚本语言,默认是Java |
session | 指定JSP页面是否使用session,默认是使用 |
isELIgnored | 指定是否执行EL表达式 |
isScriptingEnabled |
errorPage配置错误页面
<error-page> <error-code>500</error-code> <location>/error500.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page>
出现错误后,服务器会根据对应的响应码来匹配对应的错误页面
3. include指令标签
-
-
包含的文件就像是jsp文件的一部分,会被同时编译执行。
-
<%-- 静态引入,被引入的jsp页面不会单独生成java代码文件,当前页和被引入页会生成一个java文件 --%> <%@ include file="hello2.jsp"%> <%-- 动态引入:被引入的页面会生成独立的java代码,在当前页生成的java代码中使用 org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "hello3.jsp", out, false); 引入其他页面 --%> <jsp:include page="hello3.jsp"></jsp:include>
4. taglib指令标签
taglib就是标签库的意思,我们可以在jsp页面中引入其他的标签库,帮我们去快速简单的做一些事情。
语法
<%@ taglib uri="uri" prefix="prefixOfTag" %>
四、JSP内置对象
1. 内置对象简介
内置对象 | 类型 | 描述 |
---|---|---|
config | javax.servlet.ServletConfig | 由于JSP本身也是一个Servlet,所以容器也会给我们准备一个ServletConfig。 |
page | javax.servlet.jsp.JspPage | 就是JSP转换的Servlet的对象,也就是当前JSP对象本身 。 |
exception | javax.servlet.jsp.JspException | 异常对象,在错误提示页上使用,当isErrorpage=true 才具有该对象。 |
request | javax.servlet.http.HttpServletRequest | reqeust域。一次请求有效。 |
response | javax.servlet.http.HttpServletResponse | 响应对象。 |
session | javax.servlet.http.HttpSession | session域。一次会话中多次请求有效。 |
application | javax.servlet.ServletContext | application域。整个项目运行期间 多次请求、多次会话都有效。 |
out | javax.servlet.JspWriter | 打印流对象。 |
pageContext | javax.servlet.jsp.PageContext |
out对象
是 JspWriter 类的实例,不是PrinterWriter的实例;用来在response对象中写入内容。JspWriter类包含了大部分java.io.PrintWriter类中的方法。不过,JspWriter增了一些专为处理缓存而设计的方法。另外JspWriter类会抛出IOExceptions异常。 最初的JspWriter类对象根据页面是否有缓存来进行不同的实例化操作。可以在page指令中使用。buffered='false'属性来轻松关闭缓存。
pageContext对象
2. Servlet与JSP的联系与区别
联系:
-
-
基于Servlet开发页面的繁琐性,推出JSP来简化页面开发。
-
区别:
-
-
JSP是在HTML代码里写JAVA代码,框架是HTML;而Servlet是在JAVA代码中写HTML代码,本身是个JAVA类。
-
Servlet需要在web.xml中配置,而JSP无需配置。
-
五、EL表达式
1. EL表达式的作用
el表达式就是简化了数据的获取
2. 特点
①可以获取作用域对象中的数据
②底层使用的是反射,所以直接通过键名就能获取对应值
③简化了jsp中获取域对象数据的方式
3. 使用
3.1 基本语法
① ${ 键名 },键名是域对象中存储数据的键
② ${ 键名.属性名.属性名... },获取域对象中的级联属性的值。
③ ${ 键名[角标] },获取域对象中存储的list集合(底层数组)或数组中指定角标的数据
3.2 作用域数据查找顺序
-
${pageScope.键名} 获取page域对象中的数据
-
${requestScope.键名} 获取request域对象中的数据
-
${sessionScope.键名} 获取session域对象中的数据
-
${applicationScope.键名}
${requestScope.req}
${sessionScope.session}
${applicationScope.app}
${param.键名},可以获取request中携带的请求参数的数据
3.5 获取request对象中Cookie的key value
${cookie.JSESSIONID.name}
${cookie.JSESSIONID.value}
${cookie.c}指获取name值为c的cookie对象,可以根据该cookie对象获取name和value
${cookie.c} <br> <%-- 获取cookie对象 --%> ${cookie.c.name} ${cookie.c.value} <br>
3.6 EL表达式可以使用比较运算和算术运算
${键名 逻辑运算符 键名} ${键名 算术运算符 键名}
六、JSTL标签库
JSTL是一种第三方的自定义标签
每个标签都有自己特定的含义表示一个具体的java逻辑。我们要在JSP中使用JSTL必须使用taglib标签引入第三方的标签库资源。
-
核心标签库
-
SQL标签库
-
函数标签库
-
格式化标签库
-
1. 使用
-
在项目中导入JSTL的jar包。
-
在jsp页面中通过taglib指令引入jstl标签库。
-
使用jstl标签完成开发。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> </head> <body> <% request.setAttribute("gender", "0"); %> <%-- c:if 标签的作用就相当于Java中的if判断 格式是: <c:if test="${EL 比较运算符 值}">条件成立输出的内容</c:if> --%> <c:if test="${gender == '0'}"> 性别是男。 </c:if> </body> </html>
c:forEach标签案例
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>Title</title> </head> <body> <c:forEach items="${list}" var="emp"> ${emp.id}---${emp.name}---${emp.position} <br> </c:forEach> <c:forEach begin="0" end="10" var="i" step="1" varStatus="status"> ${i} --- ${status.index} </c:forEach> </body> </html>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异