欢迎光临
我们一直在努力

【Day35】JSP 技术:语法、指令与内置对象(隐式对象)

本文收录于「Java 学习日记:从入门到架构师」专栏,聚焦 Java Web 经典技术 JSP,从核心语法到内置对象实战,帮你搞懂 “前端页面 + 后端逻辑” 如何融合~

一、为什么要学 JSP?

在上一篇的会话管理中,我们用 Servlet 向客户端返回的是纯文本 / HTML 字符串,写起来又繁琐又不直观 —— 比如要拼接大量 HTML 标签,维护性极差。

而JSP(Java Server Pages) 就是为解决这个问题而生的:

  • JSP 本质上是 “特殊的 Servlet”(Tomcat 会自动将 JSP 编译成 Servlet 类);
  • 允许在 HTML 页面中嵌入 Java 代码,实现 “前端页面 + 后端逻辑” 的一体化开发;
  • 虽然现在主流是 “前后端分离”,但 JSP 是 Java Web 的基础,很多老项目 / 传统项目仍在使用,理解 JSP 能帮你更好地掌握 Servlet 容器的工作原理。

今天这篇日记,我们从 JSP 的核心语法、指令、内置对象入手,手把手写第一个 JSP 程序。

二、JSP 核心认知:什么是 JSP?

JSP 是运行在服务器端的页面技术,核心特点:

  • 本质是 Servlet:第一次访问 JSP 时,Tomcat 会将 JSP 文件编译成.java(Servlet)文件,再编译成.class文件执行;
  • 混合编写:HTML 标签负责页面展示,Java 代码负责业务逻辑,无需手动拼接字符串;
  • 内置对象:提供 9 个隐式对象(如 request、response、session),无需创建即可直接使用,简化开发。
  • JSP 的执行流程:

    三、JSP 核心语法:嵌入 Java 代码的 3 种方式

    JSP 中嵌入 Java 代码主要有 3 种形式,是入门的核心,必须掌握:

    1. 脚本片段(Scriptlet):<% 代码 %>

    • 作用:编写多行 Java 代码(变量定义、逻辑判断、循环等);
    • 特点:代码会被编译到 Servlet 的_jspService()方法中(对应 Servlet 的 doGet/doPost);
    • 注意:不能定义方法(只能定义局部变量和逻辑代码)。

    示例:

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>JSP脚本片段</title>
    </head>
    <body>
    <h1>JSP脚本片段示例</h1>
    <%
    // 定义局部变量
    String username = "Java日记";
    int age = 18;

    // 逻辑判断
    if (age >= 18) {
    // 输出到页面(等价于out.write())
    out.write("你好," + username + "!你是成年人<br>");
    } else {
    out.write("你好," + username + "!你是未成年人<br>");
    }

    // 循环输出
    for (int i = 1; i <= 3; i++) {
    out.write("循环次数:" + i + "<br>");
    }
    %>
    </body>
    </html>

    2. 表达式(Expression):<%= 变量/表达式 %>

    • 作用:直接输出变量或表达式的结果到页面,无需写out.write();
    • 特点:末尾不能加分号,是简化输出的语法糖。

    示例:

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>JSP表达式</title>
    </head>
    <body>
    <h1>JSP表达式示例</h1>
    <%
    String nickname = "Java学习日记";
    int num = 100;
    %>
    <!– 表达式输出,无需分号 –>
    昵称:<%= nickname %><br>
    数字+10:<%= num + 10 %><br>
    当前时间:<%= new java.util.Date() %><br>
    </body>
    </html>

    3. 声明(Declaration):<%! 代码 %>

    • 作用:定义 JSP 对应的 Servlet 类的成员变量 / 成员方法;
    • 特点:代码会被编译到 Servlet 类的成员位置,而非_jspService()方法中;
    • 注意:声明的成员变量是线程不安全的(Servlet 单例),慎用!

    示例:

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>JSP声明</title>
    </head>
    <body>
    <h1>JSP声明示例</h1>
    <%!
    // 声明成员变量(线程不安全!)
    private int count = 0;

    // 声明成员方法
    public String getHello() {
    return "Hello JSP!";
    }
    %>

    <%
    // 每次访问,count自增(多线程下会出错)
    count++;
    %>

    访问次数:<%= count %><br>
    方法调用:<%= getHello() %><br>
    </body>
    </html>

    四、JSP 指令:配置 JSP 的核心规则

    JSP 指令用于告诉 Tomcat 如何编译 JSP,格式:<%@ 指令名 属性="值" %>,核心有 3 个指令:

    1. page 指令(最常用)

    用于配置 JSP 页面的核心属性,如编码、语言、导入包、会话支持等。

    高频属性:

    属性作用示例
    language 指定页面使用的语言(默认 java) language="java"
    contentType 设置响应编码和数据格式 contentType="text/html;charset=UTF-8"
    pageEncoding 设置 JSP 文件本身的编码(推荐 UTF-8) pageEncoding="UTF-8"
    import 导入 Java 包(可多个,用逗号分隔) import="java.util.List,java.util.Map"
    session 是否支持 Session(默认 true) session="false"
    errorPage 指定错误页面(当前页面出错时跳转) errorPage="error.jsp"

    示例:

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java"
    pageEncoding="UTF-8"
    import="java.util.List,java.util.ArrayList"
    session="true" %>
    <html>
    <head>
    <title>page指令示例</title>
    </head>
    <body>
    <%
    List<String> list = new ArrayList<>();
    list.add("Java");
    list.add("JSP");
    list.add("Servlet");
    %>
    集合内容:<%= list %><br>
    SessionID:<%= session.getId() %><br>
    </body>
    </html>

    2. include 指令:静态包含

    用于将另一个 JSP/HTML 文件静态包含到当前页面(编译时合并),格式:<%@ include file="文件路径" %>。

    特点:

    • 静态包含:Tomcat 编译时,会将包含的文件内容直接合并到当前 JSP 中,生成一个 Servlet;
    • 路径:推荐使用相对路径,如header.jsp、/common/footer.jsp;
    • 注意:包含的文件和当前页面不能有同名变量(会冲突)。

    示例:header.jsp(公共头部):

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <div style="background: #eee; padding: 20px;">
    <h2>Java学习日记 – 公共头部</h2>
    </div>

    index.jsp(主页面):

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>静态包含示例</title>
    </head>
    <body>
    <%– 包含公共头部 –%>
    <%@ include file="header.jsp" %>

    <div style="padding: 20px;">
    <h3>主页面内容</h3>
    <p>这是通过include指令包含的公共头部</p>
    </div>
    </body>
    </html>

    3. taglib 指令:引入标签库

    用于引入自定义标签库或 JSTL 标签库(后续进阶篇讲),格式:<%@ taglib prefix="前缀" uri="标签库URI" %>。

    示例(引入 JSTL 核心标签库):

    jsp

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

    五、JSP 内置对象(隐式对象):9 个 “免创建” 的核心对象

    JSP 提供了 9 个内置对象,无需new即可直接使用,本质是 Tomcat 在编译 JSP 时,自动在_jspService()方法中创建并传入的对象。

    1. 核心内置对象(必掌握)

    对象名类型核心作用对应 Servlet 中的对象
    request HttpServletRequest 获取请求参数、请求头、域数据 完全一致
    response HttpServletResponse 发送响应、重定向、设置响应头 完全一致
    session HttpSession 存储会话数据、保持登录状态 完全一致
    out JspWriter 向页面输出内容(等价于 response.getWriter ()) 类似 PrintWriter
    pageContext PageContext 页面上下文,获取其他内置对象、域数据 独有
    application ServletContext 全局应用对象,存储整个应用的共享数据 getServletContext()

    2. 内置对象实战:登录状态展示

    login.jsp(登录页面):

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>JSP登录</title>
    </head>
    <body>
    <h1>用户登录</h1>
    <form action="loginHandle.jsp" method="post">
    用户名:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    <input type="submit" value="登录">
    </form>
    </body>
    </html>

    loginHandle.jsp(登录处理):

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
    // 1. 解决POST中文乱码
    request.setCharacterEncoding("UTF-8");

    // 2. 获取请求参数(request内置对象)
    String username = request.getParameter("username");
    String password = request.getParameter("password");

    // 3. 模拟登录校验
    if ("admin".equals(username) && "123456".equals(password)) {
    // 4. 存储用户信息到Session(session内置对象)
    session.setAttribute("loginUser", username);
    // 5. 重定向(response内置对象)
    response.sendRedirect("userCenter.jsp");
    } else {
    out.write("用户名或密码错误!<a href='login.jsp'>返回登录</a>");
    }
    %>

    userCenter.jsp(个人中心):

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    <title>个人中心</title>
    </head>
    <body>
    <%
    // 1. 从Session获取登录用户
    String loginUser = (String) session.getAttribute("loginUser");
    if (loginUser == null) {
    // 未登录,重定向到登录页
    response.sendRedirect("login.jsp");
    return; // 终止页面执行
    }
    %>
    <h1>欢迎你,<%= loginUser %>!</h1>
    <p>SessionID:<%= session.getId() %></p>
    <p>应用名:<%= application.getContextPath() %></p>
    <a href="logout.jsp">退出登录</a>
    </body>
    </html>

    logout.jsp(退出登录):

    jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
    // 销毁Session
    session.invalidate();
    response.sendRedirect("login.jsp");
    %>

    3. 测试步骤

  • 将上述 4 个 JSP 文件放到 Tomcat 的webapps/demo目录;
  • 启动 Tomcat,访问 http://localhost:8080/demo/login.jsp;
  • 输入admin/123456登录,跳转到个人中心;
  • 点击 “退出登录”,回到登录页,验证 Session 失效。
  • 六、避坑指南:JSP 常见问题

  • 中文乱码:
    • 页面乱码:确保page指令中contentType和pageEncoding都设为UTF-8;
    • 请求参数乱码:POST 请求需加request.setCharacterEncoding("UTF-8"),GET 请求需修改 Tomcat 的server.xml添加URIEncoding="UTF-8";
  • 内置对象使用错误:
    • session对象使用前无需创建,直接调用session.getAttribute()即可;
    • out.write()和<%= %>等价,推荐用表达式简化输出;
  • 静态包含冲突:包含的文件和当前页面有同名变量,会编译报错,需避免变量名重复;
  • JSP 编译失败:Java 代码语法错误(如少分号、变量未定义),查看 Tomcat 的work目录下的编译后的 Servlet 类,定位错误。
  • 七、今日实战小任务

  • 编写 JSP 页面,使用脚本片段、表达式输出 1-100 的偶数;
  • 实现 JSP 版的 “登录 – 个人中心 – 退出登录” 流程,使用 request/session 内置对象;
  • 编写公共的footer.jsp,通过 include 指令包含到主页面中。

  • 总结

  • JSP 本质是特殊的 Servlet,允许在 HTML 中嵌入 Java 代码,核心语法有脚本片段(<% %>)、表达式(<%= %>)、声明(<%! %>);
  • JSP 指令中page用于配置页面属性,include用于静态包含文件,taglib用于引入标签库;
  • JSP 提供 9 个内置对象,核心的 request/response/session/out 无需创建即可使用,是 JSP 开发的核心简化手段。
  • 下一篇【Day36】预告:JSTL 标签库与 EL 表达式(告别 JSP 脚本片段,简化页面逻辑),关注专栏持续解锁 Java Web 核心知识点~若本文对你有帮助,欢迎点赞 + 收藏 + 关注,你的支持是我更新的最大动力💖!

    赞(0)
    未经允许不得转载:171主机测评 » 【Day35】JSP 技术:语法、指令与内置对象(隐式对象)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址