JSP、HTML和Tomcat

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.pswp.cn/diannao/86051.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

常用枚举技巧:基础(一)

文章目录 常用枚举技巧&#xff1a;基础&#xff08;一&#xff09;LeetCode 1. 两数之和思路Golang 代码 LeetCode 2441. 与对应负数同时存在的最大正整数思路Golang 代码 LeetCode 1512. 好数对的数目思路Golang 代码 LeetCode 2001. 可互换矩形的对数思路Golang 代码 LeetCo…

从混乱到秩序:探索管理系统如何彻底改变工作流程

内容摘要 在许多企业与组织中&#xff0c;工作流程混乱是阻碍发展的“绊脚石”。员工们常常被繁琐的步骤、模糊的职责和沟通不畅等问题搞得焦头烂额&#xff0c;工作效率低下&#xff0c;错误频发。而与之形成鲜明对比的是&#xff0c;一些引入了先进管理系统的团队&#xff0…

使用SSE解决获取状态不一致问题

使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件&#xff0c;这个上传文件是整体功能的一部分&#xff0c;文件在上传的过程中…

华为×小鹏战略合作:破局智能驾驶深水区的商业逻辑深度解析

当中国智能电动车竞争进入下半场&#xff0c;头部玩家的合纵连横正在重构产业格局。华为与小鹏汽车近日官宣的“战略合作”&#xff0c;表面看是技术互补的常规操作&#xff0c;实则暗藏改写行业游戏规则的深层商业逻辑。 一、技术破壁&#xff1a;从“单点突破”到“全栈协同”…

Tailwind CSS 实战:基于 Kooboo 构建 AI 对话框页面(六):图片上传交互功能

在 《Tailwind CSS 实战&#xff1a;基于 Kooboo 构建 AI 对话框页面&#xff08;五&#xff09;》 中&#xff0c;完成了语音交互功能的优化。本文作为该系列教程的第六篇&#xff0c;将聚焦于图片上传功能的开发。通过集成图片上传与预览能力&#xff0c;我们将进一步完善 AI…

40. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(类写法)

40. 自动化异步测试开发之编写异步业务函数、测试函数和测试类&#xff08;类写法&#xff09; 一、类结构设计解析 1.1 基类设计 class Base:async_driver None # &#x1f697; 存储浏览器驱动实例async def get(self, url: str http://secure.smartbearsoftware.com/.…

面向开发者的提示词工程④——文本推断(Inferring)

文章目录 前言一、情感&#xff08;正向/负向&#xff09;二、识别情感类型三、识别愤怒四、从客户评论中提取产品和公司名称五、一次完成多项任务 前言 面向开发者的提示词工程——导读 在这节课中&#xff0c;你将从产品评论和新闻文章中推断情感和主题。 举了个商品评论的例…

java day15 (数据库)

进入数据库的学习 DB 因为数据太多了&#xff0c;方便统一管理的软件 操作就不用改代码了&#xff0c;直接改数据库则可&#xff1b; 命令就是sql语句 这些都是关系型数据库&#xff0c;sql可以控制全部&#xff0c;至于具体的环境我以前就有安装过了&#xff1b; 理解&am…

国标GB28181设备管理软件EasyGBS远程视频监控方案助力高效安全运营

一、方案背景​ 在商业快速扩张的背景下&#xff0c;连锁店门店数量激增&#xff0c;分布范围广。但传统人工巡检、电话汇报等管理方式效率低下&#xff0c;存在信息滞后、管理盲区&#xff0c;难以掌握店铺运营情况&#xff0c;影响企业效率与安全。网络远程视频监控系统可有…

Python 字典(dict)的高级用法与技巧

今天我们继续深入讲解 Python 字典的 高级用法与技巧&#xff0c;包括&#xff1a; defaultdict&#xff1a;带默认值的字典Counter&#xff1a;快速统计工具字典排序&#xff1a;按键或值排序合并字典&#xff08;传统方式和 Python 3.9 新语法&#xff09;嵌套字典的安全访问…

动静态库的使用(Linux)

1.库 通俗来说&#xff0c;库就是现有的&#xff0c;可复用的代码&#xff0c;例如&#xff1a;在C/C语言编译时&#xff0c;就需要依赖相关的C/C标准库。本质上来说库是一种可执行代码的二进制形式&#xff0c;可以被操作系统载入内存执行。通常我们可以在windows下看到一些后…

R²ec: 构建具有推理能力的大型推荐模型,显著提示推荐系统性能!!

摘要&#xff1a;大型推荐模型通过编码或项目生成将大型语言模型&#xff08;LLMs&#xff09;扩展为强大的推荐工具&#xff0c;而近期在LLM推理方面的突破也同步激发了在推荐领域探索推理的动机。目前的研究通常将LLMs定位为外部推理模块&#xff0c;以提供辅助性思考来增强传…

【Java后端基础 005】ThreadLocal-线程数据共享和安全

&#x1f4da;博客主页&#xff1a;代码探秘者 ✨专栏&#xff1a;文章正在持续更新ing… ✅C语言/C&#xff1a;C&#xff08;详细版&#xff09; 数据结构&#xff09; 十大排序算法 ✅Java基础&#xff1a;JavaSE基础 面向对象大合集 JavaSE进阶 Java版数据结构JDK新特性…

Tesseract配置参数详解及适用场景(PyTesseract进行OCR)

在使用 PyTesseract 进行 OCR 时&#xff0c;合理配置参数是提高识别准确率的关键。以下是 Tesseract 常用参数的详细解释和适用场景。 一、关键参数 &#xff08;1&#xff09;页面分割模式&#xff08;Page Segmentation Mode, --psm&#xff09; 控制 Tesseract 如何分析…

【Zephyr 系列 12】BLE + NVS + 低功耗融合实战:打造可配置蓝牙信标系统

🧠关键词:Zephyr、BLE 广播、信标、NVS 参数、低功耗、状态机、周期唤醒 📌适合人群:希望实现 BLE 信标类产品(定位标签、资产管理)的开发者 📊预计篇幅:约 5200+ 字 🎯 项目目标 构建一个可广泛应用于资产标签、定位信标、设备标识等场景的蓝牙广播模块,具备:…

图解浏览器多进程渲染:从DNS到GPU合成的完整旅程

目录 浏览器进程架构的演化 进程和线程关系图示 进程&#xff08;Process&#xff09; 线程&#xff08;Thread&#xff09; 协程&#xff08;Coroutine&#xff09; 进程&线程&协程核心对比 单进程和多进程浏览器 单进程浏览器​编辑 单进程浏览器存在的问题…

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…

C# 类和继承(抽象成员)

抽象成员 抽象成员是指设计为被覆写的函数成员。抽象成员有以下特征。 必须是一个函数成员。也就是说&#xff0c;字段和常量不能为抽象成员。必须用abstract修饰符标记。不能有实现代码块。抽象成员的代码用分号表示。 例如&#xff0c;下面取自一个类定义的代码声明了两个抽…

基于JWT+SpringSecurity整合一个单点认证授权机制

基于 JWT Spring Security 的授权认证机制&#xff0c;在整体架构设计上体现了高度的安全性与灵活性。其在整合框架中的应用&#xff0c;充分展示了模块化、可扩展性和高效鉴权的设计理念&#xff0c;为开发者提供了一种值得借鉴的安全架构模式。 1.SpringSecurity概念理解 …

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…