第3章:JSP 基础语法——<% %>、<%= %>、<%! %> 到底怎么用

一、前言

很多同学第一次学 JSP,最容易出现一种情况:

代码能抄出来,页面也能跑,但根本不知道这三种写法有什么区别:

复制代码
<% %>
<%= %>
<%! %>

看起来只差一个等号、一个感叹号,但实际意义完全不同。

如果这一章没学明白,后面你会连续遇到这些问题:

  • 为什么有的变量能直接输出,有的不能

  • 为什么有的变量一刷新页面就变回初始值

  • 为什么有的变量刷新后会一直累加

  • 为什么页面里 Java 和 HTML 经常交替出现

  • 为什么有的代码写在 JSP 里能运行,有的却报错

所以这一章的核心目标就一句话:

把 JSP 最基础、最关键的三种语法彻底讲明白。


二、先搞懂:JSP 到底是怎么运行的

在学语法前,必须先明白 JSP 的运行本质。

讲稿里明确提到:

所有 JSP 文件第一次运行时,都会先经过
*.jsp -> *.java -> *.class -> 运行显示

第二次再访问时,会直接利用已经生成的结果,速度更快。

这句话非常关键。

1. JSP 不是浏览器直接执行的

你写一个 demo.jsp,浏览器并不会直接执行里面的 Java 代码。

真正发生的是:

  1. 浏览器请求 demo.jsp

  2. Tomcat 接收请求

  3. Tomcat 把 JSP 转成 Java 源文件

  4. 再编译成 .class

  5. 执行后生成 HTML

  6. 把 HTML 返回给浏览器

所以你一定要记住:

JSP 表面上像"HTML 里写 Java",本质上是服务器把它翻译成 Java Servlet 后再执行。


2. 为什么第一次访问 JSP 比较慢

因为第一次访问时,Tomcat 还要做这几件事:

  • 解析 JSP

  • 生成 .java

  • 编译 .class

  • 执行输出

第二次再访问时,如果 JSP 没改,Tomcat 直接复用已有结果,所以更快。讲稿里也明确提到"第一次(修改后)很慢,之后速度很快"。


3. 为什么 JSP 必须放在 Tomcat 里运行

讲稿里反复强调:

  • JSP 是动态页面

  • 必须有 Web 容器支持

  • 必须通过浏览器地址访问,不能像普通本地 HTML 一样直接双击打开。

这也是为什么:

  • .html 可以直接本地打开

  • .jsp 不行,必须部署到服务器环境


三、JSP 页面最基础的写法

先看最简单的 JSP 例子,讲稿里就给过类似版本:

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>第一个 JSP 页面</title>
</head>
<body>
<%
    out.println("Hello World!!!");
%>
</body>
</html>

这个页面里其实混合了两部分:

1. HTML 部分

复制代码
<html>
<head>
    <title>第一个 JSP 页面</title>
</head>
<body>
</body>
</html>

负责页面结构和显示。

2. JSP 脚本部分

复制代码
<%
    out.println("Hello World!!!");
%>

负责在服务器端执行 Java 代码。

所以你可以把 JSP 理解成:

HTML 是外壳,Java 是发动机。


四、JSP 三大基础语法总览

JSP 初学阶段最重要的三种写法,就是这三个:

1. Scriptlet:脚本片段

复制代码
<% Java代码 %>

2. Expression:表达式

复制代码
<%= 表达式 %>

3. Declaration:声明

复制代码
<%! 变量/方法/成员 %>

你可以先粗暴记成:

  • <% %>:写 Java 过程代码

  • <%= %>:向页面输出值

  • <%! %>:声明成员变量或方法

但这只是第一层。

真正难点在于:它们的作用位置和生命周期不一样。


五、<% %> 到底是什么

1. 基本作用

复制代码
<% Java代码 %>

这叫 脚本片段 ,也叫 Scriptlet

它的作用是:

在 JSP 页面中写普通 Java 代码

例如:

复制代码
<%
    int a = 10;
    int b = 20;
    int sum = a + b;
%>

这里你定义了 3 个局部变量,但此时页面不会自动显示任何结果。


2. 它适合写什么

<% %> 适合写:

  • 变量定义

  • if 判断

  • for 循环

  • try-catch

  • 调用方法

  • 接收 request 参数

例如:

复制代码
<%
    String name = request.getParameter("username");
    int i;
    for(i = 1; i <= 5; i++){
%>
    <h3>第 <%= i %> 行</h3>
<%
    }
%>

这里 for 循环是在 <% %> 里写的,因为它属于逻辑控制。


3. 它不会自动输出内容

这是新手最容易误解的一点。

复制代码
<%
    int age = 20;
%>

这段代码只是定义变量,不会在页面上显示 20

如果你想显示,必须配合 <%= %>

复制代码
<%
    int age = 20;
%>
年龄是:<%= age %>

4. <% %> 里声明的是局部变量

讲稿里明确说过:

<%%> 写具体 Java 代码或声明变量,声明的是局部变量。

这句话非常关键。

例如:

复制代码
<%
    int i = 0;
%>
<%= ++i %>

你每次刷新页面,结果都会是 1

因为 i 是局部变量,每次请求页面时都会重新创建。


六、<%= %> 到底是什么

1. 基本作用

复制代码
<%= 表达式 %>

这叫 表达式标签

作用是:

把表达式的结果直接输出到页面上

例如:

复制代码
<%= 10 + 20 %>

页面会显示:

复制代码
30

2. 它等价于什么

讲稿里明确指出:

表达式 <%= 输出值 %>,类似于 out.println();开发中尽量不要用 out.println() 输出,而使用 <%= %>,目的是达到 HTML 代码与 Java 代码的分离。

也就是说:

复制代码
<%= name %>

大致等价于:

复制代码
<%
    out.println(name);
%>

但表达式写法更简洁,也更适合和 HTML 混排。


3. <%= %> 里不能随便写完整语句

这是很多人第一次会犯的错。

错误写法

复制代码
<%= int a = 10; %>

因为这里要求的是"表达式结果",不是完整 Java 语句。

正确写法

复制代码
<%
    int a = 10;
%>
<%= a %>

4. 最适合干什么

<%= %> 最适合:

  • 输出变量

  • 输出运算结果

  • 输出方法返回值

  • 输出 request 接收的数据

例如:

复制代码
当前时间:<%= new java.util.Date() %>

或者:

复制代码
<h1>欢迎你:<%= request.getParameter("uname") %></h1>

讲稿里接收表单参数的示例就用了:

复制代码
<h1><%=name%></h1>
<h1><%=request.getParameter("uname")%></h1>

来直接显示用户提交的数据。


七、<%! %> 到底是什么

1. 基本作用

复制代码
<%! 声明内容 %>

这叫 声明标签

作用是:

在 JSP 转成的 Servlet 类中,声明成员变量、成员方法,甚至成员类

讲稿中写得很明确:

声明语句 <%! %>:声明全局变量、类、方法;全局变量实例化一次。


2. 它和 <% %> 最大的区别

这是本章最核心的区别之一。

<% %>

声明的是 局部变量

<%! %>

声明的是 成员变量 / 成员方法

这意味着它们所在的位置不一样,生命周期也不一样。


3. 经典对比例子

讲稿里专门给了这个对比:

写法 1:用 <%! %>

复制代码
<%! int i = 0; %>
<%= ++i %>

写法 2:用 <% %>

复制代码
<% int i = 0; %>
<%= ++i %>

4. 刷新页面后有什么区别

对于 <% int i = 0; %>

每次请求页面,局部变量都重新创建,所以无论你怎么刷新,显示的几乎都是:

复制代码
1

对于 <%! int i = 0; %>

这是成员变量,不是每次请求都重新定义,所以刷新页面后会出现:

复制代码
1
2
3
4
...

5. 这背后的本质

因为 JSP 最终会被翻译成一个 Servlet 类。

<%! int i = 0; %>

相当于写在类里面:

复制代码
int i = 0;

<% int i = 0; %>

相当于写在方法里面:

复制代码
public void _jspService(...) {
    int i = 0;
}

这就是为什么它们的行为完全不同。


6. 开发中常不常用

讲稿里也说了:

<%! %> 中声明类或方法,在开发中很少。

原因很简单:

  • JSP 主要用于显示

  • 大量业务逻辑不应该堆在 JSP 中

  • 后面更规范的做法是放到 JavaBean 或 Servlet 里

所以:

你必须会 <%! %>,但实际开发里不要滥用。


八、为什么老师总说:少用 out.println(),多用 <%= %>

这一点讲稿里说得非常直接:

在开发中强烈建议使用表达式输出代替 out.println() 输出。

先看两个版本。


1. 全部用 out.println() 的版本

讲稿里给了一个"打印 9×9 表格"的版本:

复制代码
<%
out.println("<table border=\"1\">");
for(int i=0;i<9;i++){
    out.println("<tr>");
    for(int j=0;j<9;j++){
        out.println("<td>"+i*j+"</td>");
    }
    out.println("</tr>");
}
out.println("</table>");
%>

这个代码的问题是:

  • HTML 和 Java 字符串高度耦合

  • 引号容易乱

  • 标签结构难看

  • 调试困难


2. 用 <%= %> 改写后的版本

复制代码
<table border="1">
<%
for(int i=0;i<9;i++){
%>
<tr>
<%
    for(int j=0;j<9;j++){
%>
<td><%= i * j %></td>
<%
    }
%>
</tr>
<%
}
%>
</table>

这样明显更清晰,因为:

  • HTML 还是 HTML

  • Java 只负责控制逻辑

  • 输出值时只用 <%= %>


3. 结论

所以你以后写 JSP 要形成这个习惯:

  • 逻辑控制<% %>

  • 页面输出<%= %>

  • 不要把整页 HTML 都拼成字符串扔给 out.println()

这也是讲稿强调的开发原则之一。


九、JSP 注释到底怎么写

这个点很多老师会考,而且新手很容易混。

讲稿里把注释分成两类:

1. HTML 显式注释

复制代码
<!-- 这是 HTML 注释 -->

特点:

  • 最终会发送到客户端

  • 浏览器"查看源代码"时能看到

也就是说,这种注释对用户不是完全隐藏的。


2. Java 注释

可以写在 <% %> 里面:

复制代码
<%
    // 单行注释
    /*
        多行注释
    */
%>

这是服务器端 Java 注释,不会原样显示给浏览器。


3. JSP 隐式注释

复制代码
<%-- 这是 JSP 注释 --%>

这种注释专门给 JSP 用,浏览器源代码里也看不到。


4. 实战中怎么选

页面结构说明,且不怕被用户看到

用:

复制代码
<!-- 页面头部开始 -->

服务器端逻辑说明

用:

复制代码
<%-- 接收表单参数 --%>

或者 Java 注释。


十、一个例子彻底看懂三种语法

下面给你一个综合示例:

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

<%! int count = 0; %>

<html>
<head>
    <title>JSP 三种语法演示</title>
</head>
<body>

<%
    String name = "张三";
    int a = 10;
    int b = 20;
    int sum = a + b;
%>

<h2>用户名:<%= name %></h2>
<h2>和为:<%= sum %></h2>
<h2>页面访问计数:<%= ++count %></h2>

</body>
</html>

逐段解释

1)<%! int count = 0; %>

声明成员变量,用于累计访问次数。

2)<% ... %>

定义局部变量 nameabsum

3)<%= ... %>

把这些值直接输出到页面。


运行效果

第一次访问可能显示:

复制代码
用户名:张三
和为:30
页面访问计数:1

第二次刷新:

复制代码
用户名:张三
和为:30
页面访问计数:2

注意:

  • namesum 每次都重新算

  • count 会持续累加

这就是 <% %><%! %> 最直观的区别。


十一、JSP 中 if、for 为什么总是"断开写"

初学 JSP 最头疼的就是这种写法:

复制代码
<%
for(int i = 1; i <= 3; i++){
%>
    <h2>第 <%= i %> 行</h2>
<%
}
%>

看起来很怪,但它是 JSP 的基本写法。

原因很简单:

  • for 是 Java 逻辑,必须写在 <% %>

  • HTML 标签本身不是 Java,必须写在外面

  • 输出变量 i 时,用 <%= i %>

所以 JSP 的常见节奏就是:

Java 开始

切回 HTML

再切回 Java

再切回 HTML

这就是为什么讲稿里说很多 JSP 代码其实都是"拼凑出来的"。


十二、实战案例1:输出 9×9 表格

下面我给你一个更适合初学者理解的版本。

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>9×9表格</title>
</head>
<body>
<table border="1" cellspacing="0" cellpadding="8">
<%
    for(int i = 1; i <= 9; i++){
%>
    <tr>
    <%
        for(int j = 1; j <= 9; j++){
    %>
        <td><%= i * j %></td>
    <%
        }
    %>
    </tr>
<%
    }
%>
</table>
</body>
</html>

这里三种语法分别干了什么

<% %>

负责循环控制:

  • 外层控制行

  • 内层控制列

<%= %>

负责输出每个单元格里的值

<%! %>

这里没用,因为这个例子不需要成员变量


十三、实战案例2:表单提交 + JSP 接收参数

讲稿里紧接着就给了 request 参数接收的例子,因为 JSP 不只是"显示",还要和表单交互。request.getParameter("参数名") 用于接收客户端提交的参数,并且返回 String 类型。

1. 输入页 input.jsp

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>输入用户名</title>
</head>
<body>
<form action="show.jsp" method="post">
    用户名:<input type="text" name="uname">
    <input type="submit" value="提交">
</form>
</body>
</html>

2. 显示页 show.jsp

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>显示用户名</title>
</head>
<body>
<%
    String name = request.getParameter("uname");
%>
<h1>你输入的用户名是:<%= name %></h1>
</body>
</html>

3. 这段代码体现了什么

<% %>

接收参数:

复制代码
String name = request.getParameter("uname");

<%= %>

把参数显示到页面:

复制代码
<%= name %>

所以你现在应该能明白:

<% %> 负责"拿数据"
<%= %> 负责"显示数据"


十四、实战案例3:输入行列数,动态打印表格

讲稿中还给了一个特别典型的例子:

用户输入行数、列数,服务器接收参数后把字符串转成整数,再动态生成表格;如果转换失败,用 try-catch 处理错误。

1. 输入页 tableInput.jsp

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>输入表格行列</title>
</head>
<body>
<form action="tableShow.jsp" method="post">
    行数:<input type="text" name="rownum"><br><br>
    列数:<input type="text" name="colnum"><br><br>
    <input type="submit" value="生成表格">
</form>
</body>
</html>

2. 显示页 tableShow.jsp

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
    <title>动态表格</title>
</head>
<body>
<%
    String t_row = request.getParameter("rownum");
    String t_col = request.getParameter("colnum");

    int row = 0;
    int col = 0;

    try{
        row = Integer.parseInt(t_row);
        col = Integer.parseInt(t_col);
    }catch(Exception e){
%>
        <h2>输入错误,请输入整数!</h2>
<%
    }
%>

<table border="1" cellspacing="0" cellpadding="8">
<%
    for(int i = 1; i <= row; i++){
%>
    <tr>
    <%
        for(int j = 1; j <= col; j++){
    %>
        <td><%= i %>,<%= j %></td>
    <%
        }
    %>
    </tr>
<%
    }
%>
</table>
</body>
</html>

3. 这题为什么特别重要

因为它把前面几章全部串起来了:

  • 第2章的表单

  • 第3章的 JSP 三种语法

  • request 接收参数

  • Integer.parseInt() 字符串转整数

  • for 循环动态生成表格

这类题在课程作业和期末程序题里都非常常见。


十五、page 指令必须知道的两个用法

讲稿里明确说了 page 指令的主要功能包括:

一是导包,二是设置当前 JSP 页面的属性,尤其是 contentType 编码。

1. 设置编码

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

作用:

  • 指定返回页面的类型

  • 指定页面字符编码

  • 防止中文乱码

讲稿里特别强调:JSP 中文显示问题,往往就是没有为页面指定编码。


2. 导入包

复制代码
<%@ page import="java.util.*" %>

如果你想在 JSP 里直接写:

复制代码
<%= new Date() %>

通常就需要导入 java.util.Date 所在的包。讲稿也给了类似示例。

例如:

复制代码
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.*" %>
<html>
<head>
    <title>当前时间</title>
</head>
<body>
<h1>当前时间:<%= new Date() %></h1>
</body>
</html>

十六、本章最容易混淆的 6 个点

1. <% %> 不是输出标签

它只是执行 Java 代码。


2. <%= %> 不能写完整语句

它只能写表达式结果。


3. <%! %> 不是普通局部变量声明

它声明的是成员变量 / 方法。


4. <%! int i = 0 %><% int i = 0 %> 完全不是一回事

一个刷新后会累加,一个刷新后总是重新开始。


5. out.println() 能输出,但不推荐大量使用

因为会让 HTML 和 Java 高度耦合。讲稿明确建议优先用表达式输出。


6. JSP 必须通过服务器访问

不能把 .jsp 当成本地静态网页双击运行。


十七、本章你必须背下来的结论

  1. JSP 第一次访问会先编译,再运行。

  2. <% %> 用来写 Java 逻辑代码。

  3. <%= %> 用来把结果直接输出到页面。

  4. <%! %> 用来声明成员变量、方法,作用域和生命周期都不同于局部变量。

  5. <% %> 里声明的是局部变量。

  6. 开发中尽量少用 out.println(),多用 <%= %>

  7. request.getParameter() 用于接收表单参数,返回值是字符串。

  8. 表单传来的数字,真正使用前通常要 Integer.parseInt() 转型。


十八、本章练习题

练习1

写一个 JSP 页面,定义两个整数并输出它们的和。

要求:

  • 变量定义用 <% %>

  • 输出结果用 <%= %>


练习2

分别写出下面两种代码,并观察刷新结果:

复制代码
<%! int i = 0; %>
<%= ++i %>

<% int i = 0; %>
<%= ++i %>

然后回答:为什么结果不同?


练习3

做一个输入姓名的表单页面,再做一个显示姓名的页面。

要求:

  • 表单提交方式用 post

  • request.getParameter() 接收数据

  • <%= %> 显示姓名


练习4

做一个输入行数和列数的页面,提交后打印对应行列的表格。


十九、本章小结

这一章你真正开始接触了 JSP 的"灵魂部分"。

你现在应该已经清楚:

  • JSP 为什么是动态页面

  • JSP 为什么一定要跑在 Tomcat 里

  • <% %><%= %><%! %> 三者各自负责什么

  • 为什么 <%! %><% %> 声明变量后刷新结果不一样

  • 为什么写 JSP 时要让 HTML 和 Java 尽量分离

  • 为什么表单数据接收后通常还要做类型转换

可以说,从这一章开始,你已经不是在"写网页",而是在真正进入 服务器端动态页面开发

相关推荐
Scott9999HH36 分钟前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
腻害兔43 分钟前
【若依项目-产品经理视角】深度拆解 RuoYi-Vue-Pro 商城模块:从商品管理到交易引擎,50 张表撑起一整套电商系统
java·大数据·vue.js·产品经理·ai编程
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨3 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区5 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大6 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai6 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
维天说6 小时前
CLI-Switch 2026年3月版历史设计:Hook、TTY 隔离与 JSON 状态
java·服务器·json