JavaWeb-JSP基础


一、JSP简介

JSP(JavaServer Pages) 是与 PHPASPASP.NET 等类似的脚本语言,JSP是为了简化Servlet的处理流程而出现的替代品,早期的Java EE因为只能使用Servlet来处理客户端请求而显得非常的繁琐和不便,使用JSP可以快速的完成后端逻辑请求。

正因为在JSP中可以直接调用Java代码来实现后端逻辑的这一特性,黑客通常会编写带有恶意攻击的JSP文件(俗称WebShell)来实现对服务器资源的恶意请求和控制。

现代的MVC框架(如:Spring MVC 5.x)已经完全抛弃了JSP技术,采用了模板引擎(如:Freemark)或者RESTful的方式来实现与客户端的交互工作,或许某一天JSP技术也将会随着产品研发的迭代而彻底消失。

1.1 JSP 语法基础

JSP (JavaServer Pages) 的基础语法主要是在 HTML (或 XML) 页面中嵌入 Java 代码片段和特定的 JSP 标签,以实现动态内容生成。

  • 一、JSP 指令 (<%@ ... %>)

作用:为整个 JSP 页面提供全局信息和设置,影响页面的整体结构和行为。它们在 JSP 被编译成 Servlet 时生效。

常用指令:

1)page:定义页面属性。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.Date, com.example.MyClass" %> <!-- 导入Java包 -->
<%@ page session="true" %> <!-- 是否启用session对象 -->
<%@ page errorPage="error.jsp" %> <!-- 指定错误处理页面 -->
<%@ page isErrorPage="true" %> <!-- 声明当前页为错误处理页 -->

2)include:在 JSP 页面被编译时(编译时包含),静态地包含另一个文件(如另一个 JSP、HTML 或文本文件)的内容。

<%@ include file="header.jsp" %>

3)taglib:声明页面中使用的标签库(如 JSTL)。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  • 二、JSP 声明 (<%! ... %>)**

作用:在 JSP 页面中声明成员变量方法。这些变量和方法会成为生成的 Servlet 类的成员变量和方法。

<%!
    // 成员变量
    private int counter = 0;

    // 成员方法
    public String greetUser(String name) {
        return "Hello, " + name + "!";
    }
%>
  • 三、JSP 脚本片段 (<% ... %>)

作用:包含一段 Java 代码片段。这段代码会被插入到生成的 Servlet 的 _jspService() 方法中(相当于 Servlet 的 service() 方法)。这是处理请求逻辑的主要地方。

<%
    // Java 代码
    String username = request.getParameter("username");
    if (username != null && !username.isEmpty()) {
        out.println("Welcome, " + username);
    } else {
        out.println("Please enter your name.");
    }
%>
  • 四、JSP 表达式 (<%= ... %>)

作用:计算一个 Java 表达式,并将结果转换为字符串后直接输出到页面上。表达式结尾**不需要分号 (;)**。

<p>The current time is: <%= new java.util.Date() %></p>
<p>Your username is: <%= request.getParameter("username") %></p>
<p>Counter value: <%= counter %></p> <!-- 使用声明中定义的counter -->
  • 五、JSP 注释 (<%-- ... --%>)

作用:添加注释,这些注释不会出现在最终发送给浏览器的 HTML 源代码中。

<%-- This is a JSP comment. It won't be visible in the browser. --%>
<!-- This is an HTML comment. It WILL be visible in the browser source. -->
  • 六、隐含对象 (Implicit Objects)

作用:JSP 容器(如 Tomcat)在将 JSP 转换为 Servlet 时,会自动声明和初始化一些对象,供你在脚本片段和表达式中直接使用。这些对象代表与请求、响应、会话等相关的信息。

常用隐含对象:

request:HttpServletRequest 对象,代表客户端的 HTTP 请求。
response:HttpServletResponse 对象,代表发送给客户端的 HTTP 响应。
out:JspWriter 对象,用于向客户端输出内容(类似于 PrintWriter,但有缓冲区)。
session:HttpSession 对象,代表与用户关联的会话(如果 page 指令的 session="true")。
application:ServletContext 对象,代表整个 Web 应用程序。
pageContext:PageContext 对象,提供对页面所有作用域(page, request, session, application)和隐含对象的访问。
config:ServletConfig 对象,包含 Servlet 初始化参数。
page:相当于 Java 中的 this,指当前 JSP 页面实例(很少直接使用)。
exception:Throwable 对象,仅在错误处理页面(isErrorPage="true")中可用,代表抛出的异常。
  • 七、EL (Expression Language)

作用:虽然严格来说不是原始 JSP 语法的一部分,但它是现代 JSP 开发中极其重要且推荐的补充,用于简化对隐含对象、JavaBean 属性、集合等的访问。语法:${expression}

<p>Welcome, ${param.username}</p> <!-- 相当于 <%= request.getParameter("username") %> -->
<p>User Agent: ${header['User-Agent']}</p>
<p>Session ID: ${sessionScope.sessionId}</p>
<p>Customer Name: ${customer.name}</p> <!-- 访问JavaBean属性 -->
  • 八、JSTL (JSP Standard Tag Library)

作用:同样不是基础语法,但强烈推荐使用。它提供了一组标准标签(如循环、条件判断、格式化、数据库访问等),用于替换 JSP 脚本片段 (<% ... %>),使页面更易读、易维护。需要先使用 taglib 指令引入。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${not empty param.username}">
    <p>Welcome, <c:out value="${param.username}"/></p>
</c:if>
<c:forEach var="item" items="${shoppingCart.items}">
    <li><c:out value="${item.name}"/> - $<c:out value="${item.price}"/></li>
</c:forEach>

1.2 JSP 表达式(EL)

EL表达式(Expression Language)语言,常用于在jsp页面中获取请求中的值,如获取在Servlet中设置的Attribute:${名称}。使用EL表达式可以实现命令执行,我们将会在后续EL表达式章节中详细讲解。

1.3 JSP 标准标签库(JSTL)

JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。

JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。 除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。

1.4 JSP 九大对象

从本质上说 JSP 就是一个Servlet,JSP 引擎在调用 JSP 对应的 jspServlet 时,会传递或创建 9 个与 web 开发相关的对象供 jspServlet 使用。 JSP 技术的设计者为便于开发人员在编写 JSP 页面时获得这些 web 对象的引用,特意定义了 9 个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这 9 大对象的引用。

如下:

变量名 类型 作用
pageContext PageContext 当前页面共享数据,还可以获取其他8个内置对象
request HttpServletRequest 客户端请求对象,包含了所有客户端请求信息
session HttpSession 请求会话
application ServletContext 全局对象,所有用户间共享数据
response HttpServletResponse 响应对象,主要用于服务器端设置响应信息
page Object 当前Servlet对象,this
out JspWriter 输出对象,数据输出到页面上
config ServletConfig Servlet的配置对象
exception Throwable 异常对象

总结

  • 基础核心: <%@ %> (指令), <%! %> (声明), <% %> (脚本片段), <%= %> (表达式), <%-- --%> (注释) 以及隐含对象构成了 JSP 最原始的基础。
  • 现代开发: 强烈建议优先使用 EL (${})JSTL 标签 来访问数据和实现逻辑控制。它们使 JSP 页面更清晰、更接近纯 HTML/XML,更易于维护,并有助于分离表示层逻辑(视图)和业务逻辑(通常在 Servlet 或 JavaBean 中)。
  • 避免过度使用脚本片段: 直接在 JSP 中嵌入大量 Java 代码 (<% %>) 会使页面难以阅读和维护(通常称为“Spaghetti Code”)。应遵循 MVC 模式,将业务逻辑放在 Servlet 或 JavaBean 中,JSP 主要负责显示。
  • JSP 生命周期: 理解 JSP 页面会被容器(如 Tomcat)翻译成一个 Servlet 类(.java 文件),然后编译成 .class文件并加载执行,有助于理解其工作原理。

二、JSP和Servlet之间的关系

JSP、JSPX 文件是可以直接被 Java 容器直接解析的动态脚本, jsp 和其他脚本语言无异,不但可以用于页面数据展示,也可以用来处理后端业务逻辑。

从本质上说 JSP 就是一个Servlet ,因为 jsp 文件最终会被编译成 class 文件,而这个 class 文件实际上就是一个特殊的Servlet

JSP文件会被编译成一个java类文件,如index.jsp在Tomcat中Jasper编译后会生成index_jsp.javaindex_jsp.class两个文件。而index_jsp.java 继承于HttpJspBase类,HttpJspBase是一个实现了HttpJspPage接口并继承了HttpServlet的标准的Servlet__jspService方法其实是HttpJspPage接口方法,类似于Servlet中的service方法,这里的__jspService方法其实就是HttpJspBaseservice方法调用。

参考


文章作者: KajimiYa
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 KajimiYa !
  目录