JSP、HTML和Tomcat

article/2025/7/15 7:33:01

9x9上三角乘法表

 乘法表的实现

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head><title>9×9 上三角乘法表</title><style>body {font-family: monospace;padding: 20px;}.row {white-space: nowrap;}.cell {display: inline-block;width: 80px;}</style>
</head>
<body>
<h2>9×9 上三角乘法表</h2>
<%for (int i = 1; i <= 9; i++) {
%>
<div class="row"><% for (int j = 1; j < i; j++) { %><span class="cell">&nbsp;</span><% }for (int j = i; j <= 9; j++) { %><span class="cell"><%= i %>×<%= j %>=<%= i * j %></span><% } %>
</div>
<%}
%>
</body>
</html>

分清楚哪些是可以自定义名字的,哪些是规定的语法

<div class="lalala-row"><% for (int j = 1; j < i; j++) { %><span class="lalala-cell">&nbsp;</span><% }for (int j = i; j <= 9; j++) { %><span class="lalala-cell"><%= i %>×<%= j %>=<%= i * j %></span><% } %>
</div>

这里进行循环lalala是自己定义的名字

但head里的style里的设置也因此要修改符合了

<style>body {font-family: monospace;padding: 20px;}.lalala-row {white-space: nowrap;}.lalala-cell {display: inline-block;width: 80px;}
</style>

body { font-family: monospace; padding: 20px; }

属性含义
font-family: monospace;设置字体为等宽字体,确保每个字符宽度一样(比如数字、乘号、等号对齐)
padding: 20px;给页面四周加内边距,让内容不贴边,视觉更舒服

.row { white-space: nowrap; }

这个是用在:

<div class="row"> ... </div>

属性含义
white-space: nowrap;告诉浏览器:不要自动换行,所有乘法项都显示在一行内

🚫 否则每个 <span> 到边界时会自动换行,排版会乱

.cell { display: inline-block; width: 80px; }

这是每个乘法项的样式:

属性含义
display: inline-block;<span> 像文字一样横向排列,但也能设置宽度(不像普通的 inline 元素那样不能设置宽度)
width: 80px;给每个乘法项 固定宽度,这样不论 1×1=1 还是 9×9=81,都在统一宽度块内显示,整齐对齐

&nbsp; 是 HTML 中的不换行空格字符

  • 全称是:non-breaking space
  • 表示一个真正可见的空格不会被浏览器忽略

<body>
<h2>9×9 上三角乘法表</h2>
<%for (int i = 1; i <= 9; i++) {
%>
<div class="row"><% for (int j = 1; j < i; j++) { %><spanforthecellWith class="cell">&nbsp;</spanforthecellWith><% }for (int j = i; j <= 9; j++) { %><spanWwwhateverIcanName class="cell"><%= i %>×<%= j %>=<%= i * j %></spanWwwhateverIcanName><% } %>
</div>
<%}
%>
</body>

class前可以任意命名(但一般不要这样做,还是不太允许的)

  • 浏览器看到 spanWwwhateverIcanName,虽然它不是标准 HTML 标签,但因为它是内联标签(inline element),不会影响整体布局
  • 它仍然像 <span> 一样显示,所以不会影响页面的结构

浏览器不认识 div__lalala 这个标签,所以它会:

  • 直接忽略 div__lalala,导致其内部的元素可能失去结构化
  • 或者以未知的块级元素解析,导致 CSS(如 white-space: nowrap失效
  • 浏览器对内联元素的解析更宽松(即使是未知标签,也不会影响排版)。
  • 浏览器对块级元素的解析更严格,未知块级标签会影响 CSS 结构,导致排版错误。

标签包含

<%@page contentType="text/html;charset=gb2312"%>
<html>
<head><title>include demo</title>
</head>
<body><%@include file="incl.jsp"%><%@include file="incl.txt"%> <%@include file="incl.inc"%>   
</body>
</html>

<%@page contentType="text/html;charset=gb2312"%>

  • 设置页面的内容类型为 HTML

  • 设置字符编码为 GB2312(早期用于中文页面的编码)

  • 这会影响 HTTP 响应头和 HTML <meta charset> 默认值

<%@include file="incl.jsp"%>
<%@include file="incl.txt"%> 
<%@include file="incl.inc"%>   

用的是 JSP 的“静态包含指令”(directive include)

含义:在 JSP 被编译成 Java 代码之前,直接把指定文件的内容“粘贴”到这行位置上。

JSP 是一个“预处理器”

  • incl.jsp → 一个包含 <h1>欢迎访问</h1> 的 HTML

  • incl.txt → 一个纯文本,比如 这是文本部分

  • incl.inc → 一个 HTML 片段,比如 <footer>版权所有</footer>

只要你把这三个文件放在和 includeDemo01.jsp 同一目录下,就可以了

只要它们是合法的文本片段(HTML 或 JSP 语法中可插入的内容),就能被静态包含进去。

  • 不一定非是 JSP 文件

  • 只要在语法上能“插得进去”,都没问题

<%-- 使用此语句处理显示中的乱码 --%>
<%@page contentType="text/html;charset=gb2312"%>
<html>
<head><title>include demo</title>
</head>
<body>
<%--<jsp:include page="incl.jsp"><jsp:param name="ref1" value="ZTE"/><jsp:param name="ref2" value="tom"/></jsp:include>  
--%><jsp:include page="incl.txt"><jsp:param name="ref1" value="ZTE"/><jsp:param name="ref2" value="ls"/>
</jsp:include><%--<jsp:include page="incl.inc"/> --%>
</body>
</html>
  • 告诉 JSP 引擎输出 HTML 页面时使用 GB2312 编码(中文)

  • 防止中文乱码问题

  • 这对输出的参数(如“ZTE”、“tom”)中含中文时尤其关键

<html>
<head>
  <title>include demo</title>
</head>
<body>

标准 HTML 页面结构,主体都在 <body>

<%--<jsp:include page="incl.jsp"><jsp:param name="ref1" value="ZTE"/><jsp:param name="ref2" value="tom"/></jsp:include>  
--%>

它是标签式动态包含,特点如下:

特性含义
<jsp:include ... />运行时包含(和 @include 不同)
<jsp:param />向被包含的 JSP 页面传递参数(类似 URL 参数)
被包含页面incl.jsp:可以使用 request.getParameter("ref1") 获取值

如果取消注释,运行时会:

  • 加载 incl.jsp

  • 向其中传递两个参数:ref1=ZTEref2=tom

<jsp:include page="incl.txt"><jsp:param name="ref1" value="ZTE"/><jsp:param name="ref2" value="ls"/>
</jsp:include>

包含的是 .txt 文件,Tomcat 默认不会把 .txt 当作 JSP 来解析,而是:

把它当成纯文本文件 → 直接输出内容,不处理其中的 JSP 语法(<%= ... %>)

这就是你看到它原样打印出来的原因。

正常获取参数的两种前提方式:

✅ 方式 1:通过 HTML 表单提交(推荐)

你需要一个表单页面(比如 demo01.html),向 demo02.jsp 发起 POST 请求并带上 uname 参数:

<!-- demo01.html -->
<form action="demo02.jsp" method="post"><label>请输入姓名:</label><input type="text" name="uname"><input type="submit" value="提交">
</form>

需要新建一个 HTML 文件,比如命名为 demo01.html,内容如下: 

放在和 demo02.jsp 同一个 Web 应用项目目录下(比如你的 webapp/WebContent/src/main/webapp/ 中)

方式 2:通过 GET 参数访问

你也可以直接在地址栏里输入 URL,带上 uname 参数:

http://localhost:8080/你的项目/demo02.jsp?uname=张三

所谓“静态编码 vs 动态编码”指的就是:

编码处理方式指的是 后端 JSP 页面中对中文参数的“读取方式”,与 HTML 是否是静态页面无直接关系

类别实现方式特点
静态编码(手动转码)获取参数后再用 getBytes() + new String(...) 手动转换繁琐但对控制力高,适用于不支持动态设置编码的环境
动态编码(统一设置)request.setCharacterEncoding("编码") 预先设定推荐方式,简洁稳定

理解并对比:

客户端跳转sendRedirect
服务端跳转forward<jsp:forward>

各自的执行顺序、显示效果、地址栏变化、数据是否能传递

<%@page contentType="text/html;charset=gb2312"%>
<h1>欢迎光临:responseDemo03.jsp</h1>
<!-- http://127.0.0.1:8080/test/base/05/responseDemo03.jsp?upass=123 -->
<%System.out.println("** 跳转之前...") ;
%>
<%// 进行跳转response.sendRedirect("responseDemo04.jsp?uname=ZTE");//response.setHeader("refresh","0;URL=responseDemo04.jsp?uname=ZTE") ;
%><%--<jsp:forward page="responseDemo04.jsp"/>--%><%          //request.getRequestDispatcher("responseDemo04.jsp").forward(request, response);System.out.println("** 跳转之后...");%>

<%@page contentType="text/html;charset=gb2312"%>

  • 设置当前页面的内容类型为 HTML,字符编码是 gb2312(简体中文)

  • 作用:防止中文乱码

<h1>欢迎光临:responseDemo03.jsp</h1>

  • 页面显示的静态内容,表示这是 03.jsp 页面

  • 只有在没有跳转成功时才可能看到这个内容(实际上会被跳走)

<% ... %>JSP 的脚本标记(scriptlet),它的作用是:

✳️ 把其中的 Java 代码嵌入到 HTML 页面中,并由服务器(Tomcat)在运行时翻译成 Java Servlet 来执行

JSP(Java Server Pages)是 服务器端动态网页技术,它的本质是:

✳️ 一种“模板语言”,页面中可以写 HTML + Java 代码

它不是浏览器能直接识别的,而是被 Tomcat 服务器在第一次访问时

JSP → 翻译成 Java Servlet → 编译为 class → 运行 → 返回 HTML

假设你访问一个 JSP 页面:

http://localhost:8080/demo/responseDemo03.jsp

Tomcat 后台执行的完整流程如下

  1. 解析 JSP 文件

    • Tomcat 找到 .jsp 文件

    • 把页面中的 HTML 保留,把 <% %> 中的 Java 代码提取出来

  2. 翻译成 Java Servlet 文件

    • 每个 JSP 都会被转成一个 Servlet 类(比如叫 responseDemo03_jsp.java

  3. 编译成 .class 字节码

    • Servlet 类被编译成 .class 文件,交给 JVM 执行

  4. 运行 Servlet,输出 HTML

    • Servlet 执行时,把 HTML 输出给浏览器

    • <% System.out.println(...) %> 会打印到服务器控制台(Tomcat 终端)

    • <%= ... %> 的内容会输出到浏览器页面

你访问的 responseDemo03.jsp 页面能正常运行

里面的跳转目标 responseDemo04.jsp 根本不存在或路径不对

跳转后地址栏变成了 responseDemo04.jsp?uname=ZTE,并成功显示了页面内容

客户端跳转(Client-side Redirect)成功

测试服务端跳转(Server-side Forward)

客户端跳转的时机非常早,JSP 在遇到这句代码时:

response.sendRedirect("responseDemo04.jsp?uname=ZTE");
会立刻:

终止后续 JSP 执行(包括页面还没输出的 HTML)

把响应状态设置成 302(重定向)

让浏览器主动发起新请求访问目标地址

如果你想要先显示一部分页面再跳转,那就不是 sendRedirect 的用途,而需要用 JavaScript 来实现:

<h1>欢迎光临</h1>
<script>
    setTimeout(() => {
        window.location.href = "responseDemo04.jsp?uname=ZTE";
    }, 2000); // 2秒后跳转
</script>
 

response.setHeader("refresh",...) 也是客户端跳转 ,类似 sendRedirect,通过 HTTP 响应头控制刷新跳转

<%--<jsp:forward page="responseDemo04.jsp"/>--%>

它是另一种服务端跳转写法,和 request.getRequestDispatcher(...).forward(...) 是等价的,写法更简洁

http://localhost:8080/Web_exploded/responseDemo03.jsp

Cookie 的创建与客户端行为机制

<!--http://127.0.0.1:8080/test/base/05/cookieDemo01.jsp?name=tom&password=123-->
<%String uname=request.getParameter("name");String upass=request.getParameter("password");Cookie c1 =null;Cookie c2 =null;if("tom".equals(uname)&&"123".equals(upass)){c1 = new Cookie("name",uname) ;c2 = new Cookie("password",upass) ;// 保存时间为60秒//c1.setMaxAge(60) ;//c2.setMaxAge(60) ;}// 通过response对象将Cookie设置到客户端response.addCookie(c1) ;response.addCookie(c2) ;
%>

<!-- 访问示例:http://127.0.0.1:8080/test/base/05/cookieDemo01.jsp?name=tom&password=123 -->
你需要用浏览器访问这个地址,带上参数 name=tom&password=123

默认浏览器关闭时 Cookie 消失;设置了 setMaxAge() 后可以保留固定时间

系统 Cookie:浏览器自动携带,例如 JSESSIONID(Session ID)

用户 Cookie:程序员手动通过 new Cookie(...) 创建的,比如你这里的 name 和 password

使用 Session 实现用户身份验证

<%@page contentType="text/html;charset=gb2312"%>
<form action="login.jsp" method="post">用户名:<input type="text" name="uname"><br>密码:<input type="text" name="upass"><br><input type="submit" value="登陆">
</form><%// 判断是否有请求内容// 在自提交的页面中,必须对程序第一次运行做出处理if(request.getParameter("uname")!=null&&request.getParameter("upass")!=null){// 第一次的时候,并不能取得请求的参数String name = request.getParameter("uname") ;String password = request.getParameter("upass") ;System.out.println("name:"+name) ;System.out.println("password:"+password) ;if(name.equals("admin")&&password.equals("admin")){// 表示登陆成功// 通过flag属性判断用户是否已经登陆session.setAttribute("flag","ok") ;// 跳转到sucess.jsp//response.sendRedirect("sucess.jsp") ;%><jsp:forward page="sucess.jsp"/><%}else{response.sendRedirect("error.jsp");}} 
%>

<form action="login.jsp" method="post">
这句话的意思是:

当你在输入框里填完用户名和密码

然后点击“登录”按钮

浏览器会自动把你填写的内容通过 HTTP 的 POST 方法发回给 login.jsp 页面本身

这个提交过程是 浏览器自己完成的,你无需手动在地址栏输入任何参数

response.setHeader("refresh", "2;URL=login.jsp");
其中的数字 2 表示:

✅ 在页面显示当前内容 2 秒后,自动跳转到 login.jsp 页面。

Refresh: 秒数;URL=跳转地址
所以这句的意思就是:

当前页面停留 2 秒

然后自动跳转回 login.jsp

你在浏览器看到的是:“登录失败”显示 2 秒 → 页面自动返回登录界面

在 JSP 或 Web 开发中,URL=login.jsp 这样的写法是相对路径

它并不一定非要写完整的 http://localhost:8080/xxx/login.jsp

session.setAttribute("flag", "ok");
它的作用是:
在服务器端为当前访问用户的 Session 中,保存一条数据:键是 "flag",值是 "ok"。

这就像是贴了一个标签,告诉服务器:“这个用户已经登录了”。

<jsp:forward page="sucess.jsp"/>
确实,这句是页面跳转语句,但跳转本身并不判断用户是否登录,它只是跳页面。

而:

session.setAttribute() 是用来标记身份的,跳转之后别的页面可以判断是否有这个标记。


http://www.hkcw.cn/article/uwvEkOvBkx.shtml

相关文章

概率统计:AI大模型的数学支柱

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…

打造极致计算器:HTML+Tailwind+DaisyUI实战

一、计算器总体描述 创建一个在线计算器来实现基础数学运算功能&#xff0c;通过单一页面集成数字按钮、运算符按钮和显示结果区域&#xff0c;界面采用简洁直观的布局设计&#xff0c;按钮排列合理且提供即时运算反馈&#xff0c;确保计算逻辑准确和良好的按键响应体验&#x…

使用 HTML + JavaScript 实现图片裁剪上传功能

本文将详细介绍一个基于 HTML 和 JavaScript 实现的图片裁剪上传功能。该功能支持文件选择、拖放上传、图片预览、区域选择、裁剪操作以及图片下载等功能&#xff0c;适用于需要进行图片处理的 Web 应用场景。 效果演示 项目概述 本项目主要包含以下核心功能&#xff1a; 文…

【存储基础】存储设备和服务器的关系和区别

文章目录 1. 存储设备和服务器的区别2. 客户端访问数据路径场景1&#xff1a;经过服务器处理场景2&#xff1a;客户端直连 3. 服务器作为"中转站"的作用 刚开始接触存储的时候&#xff0c;以为数据都是存放在服务器上的&#xff0c;服务器和存储设备是一个东西&#…

SwinTransformer改进(13):融合CPCA注意力

1.创新点介绍 引言 本文将深入解析一个创新的CNN模型架构,它巧妙地将Swin Transformer与自定义的通道-位置交叉注意力(CPCA) 模块相结合。这种设计在保持Transformer强大特征提取能力的同时,通过注意力机制增强了模型对关键特征的聚焦能力。 1. CPCA注意力模块 class CP…

乌方提议6月底前俄乌进行下一轮谈判 等待俄方回应

6月2日,俄乌第二轮谈判在伊斯坦布尔的契拉昂宫举行。乌克兰国防部长乌梅罗夫表示,乌克兰提议在6月底之前再次与俄方会面,但俄方尚未对此做出回应。此次谈判由土耳其外长费丹主持。俄方代表团团长是俄总统助理梅金斯基,成员包括俄副外长加卢津、俄武装力量总参谋部总局局长科…

韩大选热度或打破纪录 政坛洗牌在即

韩国政坛即将迎来新一轮洗牌。6月3日,韩国将提前举行第21届总统选举。原定于2027年的大选因前总统尹锡悦在去年12月初发动戒严并于今年4月4日被弹劾而提前两年多举行。根据韩国宪法规定,总统被罢免后必须在6个月内举行总统选举。此次大选吸引了朝野两党的多位候选人参与,最终…

【LLM 指令遵循】论文分享:ULTRAIF

论文名称&#xff1a;UltraIF: Advancing Instruction Following from the Wild 论文链接&#xff1a;https://arxiv.org/abs/2502.04153 机构&#xff1a;上海AI Lab 北大 清华 Github代码链接&#xff1a;https://github.com/kkk-an/UltraIF 数据集链接&#xff1a;https:/…

Ruoyi AI 部署指南:从环境搭建到项目运行

目录 一、项目概述 二、环境准备 1. Java 开发环境 2. 数据库 3. 缓存系统 4. 构建工具 5. 前端工具 三、后端项目部署 1. 下载项目 2. 导入项目 安装jdk17后没有jre ​编辑 3. 配置 Maven 4. 初始化数据库 5. 启动 Redis 6. 启动项目 四、前端项目部署 1. 管…

凹凸工坊_AI手写模拟器|可打印的手写稿|免抄写的工具,抄写罚抄神器,一键生成手写文稿,模仿手写软件,在线手写字体转换器,手写模拟器APP下载,打印出以假乱真的模拟手写文档,模拟抄写软件

推荐这个非常好用的免费 ai 手写模拟器网站&#x1f50d;「凹凸工坊-手写转换」 地址&#xff1a;凹凸工坊_凹凸工坊-手写转换官网入口_一键生成手写文稿_手写模拟器_手写字体在线转换_在线字体制作_手写APP下载_模仿手写软件_AI手写字体生成_手写字体生成器_字体下载https://…

芝士ai系统,宝藏的论文查重降重经验!

完成一篇论文的辛苦工作后&#xff0c;面对高查重率无疑是令人沮丧的。但不必担忧&#xff0c;芝士AI降重工具可以助你一臂之力。本文将探讨芝士AI如何帮助学者们有效降低查重率&#xff0c;确保论文的原创性和学术价值。让我们一起看看芝士AI如何让学术写作变得更轻松。 芝士…

IDEA + DeepSeek 实现 AI辅助编程,提升效率10倍(全网超详细的终极图文实战指南)

前言 在软件开发的世界里&#xff0c;每个开发者都经历过这样的困境——在重复的CRUD代码中机械劳动&#xff0c;为复杂的业务逻辑调试数小时&#xff0c;或是在海量文档中寻找某个API的正确用法。传统的IDE工具虽能提供基础支持&#xff0c;却难以突破效率的“玻璃天花板”。而…

开启智慧之旅,AI与机器学习驱动的微服务设计模式探索

​🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自热榜文章🔥:探索设计模式的魅力:开启智慧之旅,AI与机器学习驱动的微服务设计模式探索(2024年04月21日 22:26:05目前全站综合热榜第三) ✨欢迎加入探索A…

探索GpuGeek:AI开发者与中小企业的算力宝藏平台

摘要&#xff1a;GpuGeek 作为面向 AI 开发者和中小企业的 AI 赋能平台&#xff0c;在 AI 时代具有重要意义。它提供丰富算力资源、多元框架工具等&#xff0c;涵盖深度学习项目、大模型研究等多方面&#xff0c;助力用户应对算力挑战&#xff0c;推动 AI 技术普及应用&#xf…

迁移学习:解锁AI高效学习与泛化能力的密钥

前言 在人工智能&#xff08;AI&#xff09;技术日新月异的今天&#xff0c;迁移学习&#xff08;Transfer Learning&#xff09;作为一项革命性技术&#xff0c;正深刻改变着机器学习领域的格局。 它不仅让模型能够像人类一样“举一反三”&#xff0c;更在加速模型开发、提升性…

王者归来!谷歌Gemini 2.5 Pro横扫全球AI榜单,国内用户终于可直接体验“最强大脑“

&#x1f31f; 嗨&#xff0c;我是Lethehong&#xff01;&#x1f31f; &#x1f30d; 立志在坚不欲说&#xff0c;成功在久不在速&#x1f30d; &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞⬆️留言收藏&#x1f680; &#x1f340;欢迎使用&#xff1a;小智初学计…

AI图像编辑器 Luminar Neo 便携版 Win1.24.0.14794

如果你对图像编辑有兴趣&#xff0c;但又不想花费太多时间学习复杂的软件操作&#xff0c;那么 Luminar Neo 可能就是你要找的完美工具。作为一款基于AI技术的创意图像编辑器&#xff0c;Luminar Neo简化了复杂的编辑流程&#xff0c;即使是没有任何图像处理经验的新手&#xf…

win11系统安装踩坑笔记 u盘安装 2025

目录 试验1 系统之家下载的ghost&#xff0c;安装ok&#xff0c;不知道用户名密码 试验2 u盘安装 ok 试验3 硬盘安装 第1步&#xff0c;还在刚才网址上选择下载iso&#xff0c; 第2步&#xff0c;然后选择简体中文&#xff0c;然后会开始下载iso。 第3步&#xff0c;下载…

郑钦文:会拼到最后一刻 再战萨巴伦卡备受关注

北京时间6月2日凌晨,法网女单第四轮上半区四场比赛结束后,部分八强赛对阵揭晓。中国选手郑钦文将与世界第一萨巴伦卡交手,这是两人时隔半月后的再次对决,备受瞩目。郑钦文职业生涯首次打进法网女单八强。今年在澳网、迈阿密站、马德里站和罗马站等比赛中,郑钦文多次与萨巴…

乌宣称命中41架俄军机 俄方怎么说 筹备一年半行动

6月1日,乌克兰对俄罗斯境内多处军事设施发动无人机袭击。乌克兰国家安全局网站于2日下午发表声明,确认策划了代号为“蛛网”的特别行动,并声称击中包括A-50预警机、图-95轰炸机、图-22M3轰炸机和图-160轰炸机在内的41架俄军飞机。乌克兰国家安全局局长瓦西里马柳克表示,摧毁…