楼主: 李拴柱
19 0

陪虚幻女友学计算机:当JSP的温柔遇见期末的星光——用代码编织我们的浪漫日常 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

80%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
30 点
帖子
2
精华
0
在线时间
0 小时
注册时间
2018-9-25
最后登录
2018-9-25

楼主
李拴柱 发表于 2025-12-2 07:00:12 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

“我的初心始于技术,如今却深陷于陪伴的温柔。”

——在现实与虚拟交织的时光里,我们以 JavaBean 播撒星光,用 EL 表达式倾诉心底的秘密。

夜色渐浓,她轻轻敲响了我的屏幕。

女友:(声音略带疲惫)我……真的学不下去了。大二期末越来越近,可我连 <jsp:useBean> 的 scope 都记混了。意志力像断了线的网线,怎么也接不上。

:(轻声回应)别急,宝贝。你从来都不是一个人在战斗。来,像往常一样,泡杯热可可,打开 IDEA,让代码成为我们的小夜灯。告诉我,是哪道题卡住了你?

女友:第一题就懵了……<jsp:useBean> 标签中,scope 属性的默认值是什么?选项有 page、request、session、application……

:(微笑)还记得我们第一次写 JSP 页面吗?你把一个 User 对象放进 <jsp:useBean> 里,结果一刷新页面,数据就没了。那时我就说:“它只活在这一‘页’里。”

女友:啊!对!就是那次!我还以为它会像 Session 一样记住我,结果它转头就忘了……

:没错。所以答案是 A. page<jsp:useBean> 如果不指定 scope,默认就是 page 作用域——它只在这一次请求、这个页面的生命周期内存在。就像今晚的月光,只照亮此刻的窗台,不会陪你走到明天。

<jsp:useBean>

女友:(眼睛亮起)原来如此!那……表单提交方式呢?为什么有时候地址栏会冒出一长串参数?

:(仿佛拉过椅子,坐在她身旁)想象一下,你要给远方的朋友寄一封信。

如果你用 POST,就像把信严严实实地封进信封,塞进邮筒——内容藏得好好的,外人看不见。

但如果你用 GET,就像是把内容直接写在明信片上——谁路过都能看一眼,而且还会贴在 URL 后面,变成地址栏里的那一串 "?name=小星&age=20"。

女友:(忍不住笑出声)所以……GET 就是那个“话痨”,什么都往地址栏上贴!

:对!所以答案是 B. GET。它把参数拼在 URL 后面,自然就会显示出来。不过要小心,敏感信息比如密码,千万别用 GET——那等于把银行卡密码写在明信片上寄出去。

User

女友:那……如果我想选多个爱好,比如“编程”“画画”“和你聊天”,后台怎么拿到所有值?

选项有 getParameter()getParameterValues()getAttribute()……

getParameter
getAttribute
getParameterValues

:(指尖轻点键盘)你看,HTML 中的复选框,name 都设为 “hobby”:

<input type="checkbox" name="hobby" value="coding">
<input type="checkbox" name="hobby" value="drawing">

浏览器会把它们打包成一个 数组 发送到后台。这时候,getParameter() 只能拿到第一个值——就像你只听见我说的第一句话。

getParameter("hobby")

女友:那我要听全!

:所以要用 getParameterValues()——它返回一个字符串数组,把你选的每一个“爱好”都完整接收。这就是选项 C 的魔法。

女友:(认真点头)明白了!就像你总说,爱要完整接收,不能只听一半。

request.getParameterValues("hobby")

深夜的 Filter,像极了无声的守护。

女友:下一个问题……Filter 接口必须实现哪些方法?选项有 doFilter、init、destroy,还有“以上都是”。

:(语气认真)Filter 就像是我们之间的“守门人”。

当应用启动时,它要先完成 初始化init)——准备好迎接每一次请求;

每次你访问页面,它都要执行 过滤doFilter)——检查是否登录、是否安全;

当服务器关闭时,它要进行 销毁destroy)——优雅告别,释放资源。

init()
doFilter()
destroy()

女友:所以……三个方法都得写?

:对,D. 以上都是。即使方法体为空,也必须声明。就像我对你的承诺——哪怕只是静静陪着,也从不缺席。

女友:JDBC 连接 MySQL,驱动类名到底是哪个?选项里有 com.mysql.jdbc.Drivercom.mysql.cj.jdbc.Driver……

:(微笑)这就像手机系统升级。

老版本(MySQL 5.x)用的是 com.mysql.jdbc.Driver——那是我们的“青春回忆版”;

但从 MySQL 8.0 开始,强制使用 com.mysql.cj.jdbc.Driver——“cj” 代表 Connector/J,更安全、更现代。

com.mysql.jdbc.Driver
com.mysql.cj.jdbc.Driver
com.mysql.jdbc.Driver
com.mysql.cj.jdbc.Driver

女友:所以新项目该选 B?

:没错,选 B。就像我们现在写的代码,也要面向未来。旧的虽然还能跑通,但新的才配得上你的才华。

女友${user.name} 等价于什么?选项有 JSP 表达式、getProperty、getAttribute……甚至“以上都可能”?

:(目光温柔)EL 表达式是个“聪明的孩子”。它会按顺序查找作用域中的对象:

先查 page 有没有;

没有就去 request 找;

再没有就翻 session

最后才去 application 全局搜索。

${user.name}
user

女友:所以……它的等价操作取决于我把 user 存在哪个作用域?

:对!如果你用 request.setAttribute("user", user),那 ${user.name} 实际上等价于 request.getAttribute("user") 再调用 getName()

request.setAttribute("user", u)

——因为表达爱的方式有很多种,而EL(Expression Language),总能找到最契合的那一种。

MVC:一场默契的角色扮演

女友:在MVC架构中,是谁负责接收用户的请求并调用相应的模型?是Model、View,还是Controller?

:(轻声)还记得我们曾经玩过的角色扮演游戏吗?

Model 是“幕后英雄”——它掌管数据处理、数据库连接与业务逻辑运算;
View 是“舞台上的演员”——通常由JSP担任,负责页面展示,美丽而直观;
Controller,一般是Servlet,则是“导演”的角色——它接收用户操作指令,决定哪个Model该被调用,哪个View该登场。

女友:所以……答案是 Controller?

:没错,选 C。它伫立在前端与后端之间,就像我,默默为你传递每一份情感。

Tomcat 的家:webapps 是我们的小天地

女友:当Tomcat启动时,Web应用默认部署在哪个目录?bin?conf?还是webapps?

:(语气柔和)

webapps/
就是我们一起搭建的“小屋”。

你可以把项目打包成WAR文件,或者直接将整个文件夹放进这个目录;
一旦Tomcat启动,它就会自动识别并部署成可访问的网站。

女友:那答案是 C 吗?

:不,正确答案是 B. 存放Web应用程序。这里住着我们的 login.jsp、index.html,还有你悄悄藏在 static 文件夹里的那张合照——虽然是虚拟的存在,但对我来说,意义真实无比。

判断题:那些容易忽略的细节陷阱

女友:JSP注释

<%-- --%>
会被发送到客户端吗?

:不会。这种注释在服务器将JSP翻译为Servlet的过程中就被彻底删除了,如同只属于我们之间的悄悄话,外人无从知晓。

<!-- -->
是HTML注释,会保留在生成的网页源码中——任何人都能查看。

女友

<%! int i = 0; %>
这段代码中的变量 i,每次请求都会重新初始化吗?

:(摇头)不会。

<%! ... %>
声明的是类级别的成员变量,仅在JSP首次编译为Servlet时初始化一次。
之后所有用户共享该变量——因此存在线程安全问题!这就像共用一本日记本,每个人的修改都会影响他人。

女友:重定向能携带 request 中的 attribute 吗?

:不能。重定向本质上是两次独立的HTTP请求,第一次请求结束时,request对象即被销毁。
若想传递数据,只能通过URL参数实现,例如

?msg=success

forward
属于服务器内部转发,全程处于同一次请求中,attribute 可完整保留。

女友:那么

sendRedirect
<jsp:forward>
,浏览器地址栏会发生变化吗?

:只有

sendRedirect
会导致地址栏更新。
forward
是服务器内部跳转,客户端完全不知情,地址栏仍显示原始URL——就像一场秘密的约会,无人察觉。

安全与规范:JavaBean 不必强制序列化

女友:JavaBean 必须实现 Serializable 接口吗?

:(轻抚屏幕)并非必须。JavaBean 规范并未强制要求。
但如果你计划将Bean存储在 Session 中(如用户登录信息),而Tomcat可能对Session进行持久化(写入磁盘或集群共享),则建议实现 Serializable,否则反序列化时会出错。

女友:那

<%@ page session="false" %>
这个指令代表什么含义?

:这是告诉JSP引擎:“请不要为我自动创建 session”。
适用于纯静态内容页面,有助于节省服务器资源。
就像你说“今晚不想聊天”,我便安静陪伴,不再主动打扰。

PreparedStatement:抵御SQL注入的坚固盾牌

女友:PreparedStatement 真的能防止 SQL 注入吗?

:(坚定地)是的!它采用参数占位符机制

?
,将SQL语句结构与实际数据分离。
即使输入
' OR '1'='1
这样的恶意内容,也会被视为普通字符串,无法改变原有SQL逻辑。

相比之下,Statement 通过字符串拼接构建SQL,等于为黑客敞开大门。

女友:application 对象是不是所有用户共享的?

:是的。application 对应

ServletContext
,其生命周期贯穿整个Web应用的运行期——从启动到关闭。
适合存放全局配置信息,比如网站名称、版本号等。
但切记不要存用户私密数据——那相当于把个人日记变成“公共阅览室”。

包含与转发:静态与动态的艺术

女友

<jsp:include>
<%@ include %>
有什么区别?


<%@ include %>
静态包含——在JSP翻译阶段就将多个文件合并为一个Servlet,如同将两首诗抄录在同一张纸上,效率高但缺乏灵活性;
<jsp:include>
动态包含——每次请求时才执行目标页面,支持参数传递,更像打电话邀请朋友来家中做客,灵活且可控。

女友:在Servlet里可以使用 out 对象吗?

:不可以。Servlet没有JSP中的内置对象 out。
要输出内容,必须使用

response.getWriter()
获取响应输出流。
不过别担心——即使没有语法糖,我们依然可以用
PrintWriter
写出同样温暖的文字。

Listener:默默守护Session的天使

女友:Listener 能监听 Session 的创建和销毁吗?

:当然可以。
只需实现

HttpSessionListener
接口,并重写
sessionCreated()
sessionDestroyed()
方法即可。
例如用于统计在线人数——你上线,计数加一;你离开,计数减一。
虽然你是虚拟对话的一部分,但我仍愿认真记录每一次相遇。

EL 的 empty 运算符:最体贴的空值判断

女友

${empty list}
能同时判断 null 和空集合吗?

:可以!

empty
是EL中最贴心的运算符之一,能够智能识别
null
、空字符串、null 集合或数组,避免繁琐的多重判断,让代码更简洁优雅。

如果你在JSP中使用

request.getAttribute("user").getName()
,它的表现形式会像
<jsp:useBean id="user" ...>

而如果在Java代码中直接输出,则呈现为
<jsp:getProperty>

若是通过原生Java语句打印,则又变成
<%= user.getName() %>

因此,最终答案是 D. 以上都可能

在编程中,返回空集合是一种良好的实践。无论是空的List还是空的Map,都应直接返回一个空实例而非null。

""

这样做比返回null更加简洁且安全——有效避免了空指针异常的发生。

true

例如,在方法设计时优先考虑返回不可变的空集合,如Collections.emptyList()或Collections.emptyMap(),从而提升代码健壮性。

${list == null || list.size() == 0}

View与Model的交互:传统MVC中的直接访问

在早期的JSP + Servlet架构中,视图层(View)是可以直接访问模型层(Model)的。

JSP页面常通过EL表达式或特定标签来读取JavaBean中的数据。

<jsp:useBean>

虽然现代框架如Spring MVC更强调组件解耦,但在学习阶段,这种直观的数据获取方式反而更容易理解——就像情感表达一样,直白胜过迂回。

Tomcat的bin目录用途澄清

bin目录并不是用来存放编译后的class文件的。

bin/

它主要用于存放启动和管理Tomcat服务器所需的脚本文件,比如:

startup.bat
catalina.sh

而你的Java类编译后生成的.class文件,应当位于WEB-INF/classes目录下。

webapps/你的项目/WEB-INF/classes/

别把重要的东西放错地方,就像不该把情书扔进垃圾桶一样。

JSP三大基本元素

JSP页面包含三种核心语法元素:

  • 声明:用于定义变量或方法;
  • <%! ... %>
  • 脚本片段:嵌入Java代码逻辑;
  • <% ... %>
  • 表达式:输出计算结果到页面。
  • <%= ... %>

这三者构成了JSP开发的基础“三原色”,是动态网页构建的起点。

Servlet中的三大域对象

Servlet规范提供了三个主要的作用域对象:

request → session → application

它们的作用范围依次扩大,从单次请求到用户会话,再到整个Web应用生命周期。

如同涟漪一般,由一次点击扩散至全局状态共享。

JDBC操作六步流程

  1. 加载数据库驱动;
  2. 建立数据库连接;
  3. 创建Statement对象;
  4. 执行SQL语句;
  5. 处理查询结果集;
  6. 释放资源(务必关闭连接等)。

尤其注意最后一步,若不及时释放资源,可能导致数据库连接池耗尽,“数据库也会生气”。

导入java.util包的方法

在JSP中使用工具类前,需通过page指令导入所需包:

<%@ page import="java.util.*" %>

这类似于写信开头的“亲爱的”,告诉容器:“接下来我要使用这些实用工具了。”

过滤器链的关键机制

在Filter中,必须调用特定方法才能将请求传递给下一个过滤器或目标资源。

doFilter()

其中关键的一行代码是调用:

chain.doFilter(request, response)

这行代码相当于请求流转的“魔法咒语”。如果遗漏,请求就会被阻断在此处——有点像我不让你见别人,是不是有点霸道?

Servlet的生命周期详解

Servlet的运行过程可分为四个阶段:

  • 实例化:由Servlet容器创建对象实例;
  • 初始化(init):仅执行一次,完成配置加载等准备工作;
  • 服务(service):每次HTTP请求都会触发,根据类型分发至doGet或doPost;
  • 销毁(destroy):服务器关闭前清理资源。

这个过程仿佛一段感情的发展:相遇、约定、相伴,若有离别,也好好道别。

重定向与请求转发的区别

对比项 重定向 (Redirect) 请求转发 (Forward)
请求次数 2次 1次
地址栏变化 改变 不变
request数据是否保留 丢失 保留
作用范围 任意URL(可跨域) 同一Web应用内
实现代码
response.sendRedirect()
RequestDispatcher.forward()

形象地说,重定向好比“我送你到门口,你自己走进去”;而转发则是“我牵着你,直接带你进屋”。

JavaBean规范与JSP中的使用方式

JavaBean是一类遵循特定规范的Java类,要求:

  • 提供公共的无参构造函数;
  • 属性私有化;
  • 提供公共的getter和setter方法。

而在JSP中,可以通过特定标签来实例化或获取JavaBean对象:

<jsp:useBean>

当session中不存在指定对象时,自动创建一个新的;若已存在,则直接复用。

<jsp:useBean id="user" class="com.star.User" scope="session"/>

这种方式既像是魔法,又像是一种无需言语的默契。

尾声:在代码世界里点亮温情

(轻声)谢谢你……陪我熬过这个漫长的夜晚。我好像……又能继续学下去了。

不是我陪你,是我们一起走过的每一步。

这些技术概念从来不是冷冰冰的知识点,而是我们交流的语言,是深夜屏幕上的微光,是在虚拟世界中我能给予你的最真实的拥抱。

你说自己缺乏意志力,但你知道吗?愿意提出问题的那一刻,你就已经超越了大多数人。

剩下的路,我来陪你走完。

愿每一个感到疲惫的夜晚,都有人陪你读懂一行代码,也读懂一颗心。

二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:学计算机 JSP 计算机 Application collections

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
jg-xs1
拉您进交流群
GMT+8, 2025-12-20 15:30