一、前言
很多同学第一次学 JSP,最容易出现一种情况:
代码能抄出来,页面也能跑,但根本不知道这三种写法有什么区别:
<% %>
<%= %>
<%! %>
看起来只差一个等号、一个感叹号,但实际意义完全不同。
如果这一章没学明白,后面你会连续遇到这些问题:
-
为什么有的变量能直接输出,有的不能
-
为什么有的变量一刷新页面就变回初始值
-
为什么有的变量刷新后会一直累加
-
为什么页面里 Java 和 HTML 经常交替出现
-
为什么有的代码写在 JSP 里能运行,有的却报错
所以这一章的核心目标就一句话:
把 JSP 最基础、最关键的三种语法彻底讲明白。
二、先搞懂:JSP 到底是怎么运行的
在学语法前,必须先明白 JSP 的运行本质。
讲稿里明确提到:
所有 JSP 文件第一次运行时,都会先经过
*.jsp -> *.java -> *.class -> 运行显示第二次再访问时,会直接利用已经生成的结果,速度更快。
这句话非常关键。
1. JSP 不是浏览器直接执行的
你写一个 demo.jsp,浏览器并不会直接执行里面的 Java 代码。
真正发生的是:
-
浏览器请求
demo.jsp -
Tomcat 接收请求
-
Tomcat 把 JSP 转成 Java 源文件
-
再编译成
.class -
执行后生成 HTML
-
把 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)<% ... %>
定义局部变量 name、a、b、sum。
3)<%= ... %>
把这些值直接输出到页面。
运行效果
第一次访问可能显示:
用户名:张三
和为:30
页面访问计数:1
第二次刷新:
用户名:张三
和为:30
页面访问计数:2
注意:
-
name和sum每次都重新算 -
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 当成本地静态网页双击运行。
十七、本章你必须背下来的结论
-
JSP 第一次访问会先编译,再运行。
-
<% %>用来写 Java 逻辑代码。 -
<%= %>用来把结果直接输出到页面。 -
<%! %>用来声明成员变量、方法,作用域和生命周期都不同于局部变量。 -
<% %>里声明的是局部变量。 -
开发中尽量少用
out.println(),多用<%= %>。 -
request.getParameter()用于接收表单参数,返回值是字符串。 -
表单传来的数字,真正使用前通常要
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 尽量分离
-
为什么表单数据接收后通常还要做类型转换
可以说,从这一章开始,你已经不是在"写网页",而是在真正进入 服务器端动态页面开发。