第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 尽量分离

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

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

相关推荐
流光332 小时前
一行命令加密 Spring Boot 项目,零代码侵入
java
程序员鱼皮2 小时前
【后端必看】什么是 Elasticsearch?都要学什么?
java·数据库·程序员·编程·后端开发
Full Stack Developme2 小时前
Java 反射原理及应用
java·开发语言·数据库
myloveasuka2 小时前
权限修饰符&代码块
java
柒.梧.2 小时前
Java集合核心知识点深度解析:数组与集合区别、ArrayList原理及线程安全问题
java·开发语言·python
0 0 02 小时前
洛谷P4427 [BJOI2018] 求和 【考点】:树上前缀和
开发语言·c++·算法·前缀和
web3.08889992 小时前
使用PHP采集数据的完整技术文章,涵盖多种场景和最佳实践
开发语言·php
柒.梧.2 小时前
Java基础高频面试题(含详细解析+易错点,面试必看)
java·开发语言·面试
佩奇大王2 小时前
P593 既约分数
java·开发语言·算法