Servlet+Jsp(1.21)
一、Java Web 项目中浏览器可直接访问的两类核心资源 ——web 包下 WEB-INF 目录外的静态资源、web.xml 中通过 <url-pattern> 配置的动态资源(Servlet)
二、Servlet单例,在service方法外边属性是公共的,不安全,而在方法定义的局部变量是安全的
三、Servlet生命周期

1.当浏览器访问Servlet的时候,httpd会在Tomcat容器中检查之前是否缓存过该Servlet对象
2.没有---->表示第一次访问,就会新建一个Servlet对象,调用init方法进行初始化,然后将这个对象放入到Tomcat容器中
3.继续执行service方法,响应数据返回浏览器
4.有---->直接调用缓存中对象的service方法,响应数据返回浏览器
5.如果长时间没有访问Servlet,垃圾回收时,会调用destroy方法进行回收
四、Servlet编写:
(1)1.继承关系
【顶层接口】Servlet (javax.servlet.Servlet)
↓ 实现
【抽象类】GenericServlet (javax.servlet.GenericServlet)
↓ 继承
【抽象类】HttpServlet (javax.servlet.http.HttpServlet)
↓ 继承
【自定义类】YourMenuServlet (cn.wolfcode.servlet.MenuServlet)
2.类的编写
①创建一个类实现 Servlet 接口---->重写接口中所有的方法(init、getServletConfig、service、getServletInfo、destroy)
②继承 HttpServlet 抽象类---->重写service方法
(2)路径配置:
①web.xml文件中配置
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>cn.wolfcode.servlet.HelloServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet</servlet-name>
<servlet-class>cn.wolfcode.servlet.Servlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet</servlet-name>
<url-pattern>/servlet1</url-pattern>
</servlet-mapping>
多个路径可以对应同一个类
②注解配置:
@WebServlet("/servlet2")
@WebServlet(value = {"/servlet2","/servlet22","/servlet222"})
五、
get-->查询 post-->插入 put-->更新 delete-->删除
六、 Servlet 的初始化时机
web.xml:
值为负数:第一次访问时才创建(默认) 懒加载
值为正数:容器启动就加载按数值从小到大加载 勤快加载
七、请求路径优先级

八、ParameteMap、AttributeMap和url地址

request可以拿到前端的url和parameteMap,以及后端的url和attributeMap,可以读写临时文件,传给后续同一请求链的filter、servlet、jsp
前端通过超链接、form表单、js传递数据给后端servlet,通过req.getParameter("uname")获取,链接或表单数据。
AttributeMap 里的数据从哪来?
一句话:所有数据都是后端代码自己存进去的,和前端无关。
- 它不是前端传的(前端传的是
ParameterMap),而是后端在处理请求的过程中,通过request.setAttribute("key", value)主动存入的临时数据。 - 存入的时机可以是:
- Filter 中:比如权限校验 Filter 拿到用户信息后,存入 AttributeMap 供后续组件使用。
- Servlet 中:比如查询数据库得到用户列表后,存入 AttributeMap 准备转发给 JSP 渲染。
- JSP 中:比如页面渲染时生成的临时数据,存入 AttributeMap 供其他片段复用。
Servlet的理解:
当你用前端 form 表单提交数据时:
- 前端把数据通过 HTTP 协议发送到服务器;
- Web 容器(如 Tomcat)会把这个请求交给对应的 Servlet 处理(这个 Servlet 就是你写的后端代码);
- 你在 Servlet 里用
req.getParameter()获取前端传来的参数,这一步是「接单员拿到顾客的点单内容」; - 接下来,Servlet 会把这些参数传给后端的其他模块(比如业务逻辑层
Service、数据访问层DAO),就像「接单员把订单交给厨师去做菜」; - 最后,Servlet 生成响应返回给前端,就像「接单员把做好的菜送给顾客」。
关键区分:后端 ≠ Servlet
后端是一个完整的服务体系,包含很多部分:
- Servlet:仅负责「接收 HTTP 请求 → 调用业务逻辑 → 返回 HTTP 响应」,是请求进入后端的入口。
- 业务逻辑层(Service):处理具体的业务规则(比如用户注册时校验手机号是否已存在)。
- 数据访问层(DAO):负责和数据库交互(比如把用户信息存入数据库)。
- 工具类、配置文件:提供通用功能支持。
九、HttpServletRequest req 的常用API:
一、核心前提:两个 Map 的定位区分
| 特性 | ParameterMap(参数 Map) | AttributeMap(属性 Map) |
|---|---|---|
| 数据来源 | 前端传入(URL/form 表单) | 后端代码存入(setAttribute) |
| 可读写性 | 只读(仅能获取,无法修改) | 可读写(增删改查) |
| 数据类型 | 键:String,值:String [] | 键:String,值:Object(任意对象) |
| 核心用途 | 获取前端传递的请求参数 | 后端内部共享请求级临时数据 |
二、ParameterMap 相关 API(只读)
//设置编码集
req.setCharacterEncoding("UTF-8");
String getParameter(String name)
// 读取前端传入的 uname 参数
String uname = req.getParameter("uname");
String[] getParameterValues(String name)
// 读取前端传入的 hobby 多选参数
String[] hobbies = req.getParameterValues("hobby");
AttributeMap 相关 API(可读写)
void setAttribute(String name, Object value)
// 1. 存入字符串类型属性
req.setAttribute ("tipMsg", "数据查询成功");
// 2. 存入自定义对象(如用户实体)
User loginUser = new User("admin", "123456");
req.setAttribute("loginUser", loginUser);
// 3. 覆盖已有属性(同名自动替换)
req.setAttribute ("tipMsg", "数据更新成功");
Object getAttribute(String name)
// 1. 读取字符串属性(需强制类型转换)
String tipMsg = (String) req.getAttribute("tipMsg");
// 2. 读取自定义对象属性(需强转)
User loginUser = (User) req.getAttribute("loginUser");
// 3. 兜底处理(避免空指针)
if (loginUser == null) {
loginUser = new User (); // 初始化空对象
}
void removeAttribute(String name)
// 移除不再使用的属性
req.removeAttribute("tipMsg");
// 移除后获取该属性返回 null
String msg = (String) req.getAttribute ("tipMsg"); // 结果:null
十、页面转向和重定向
页面转向:通过前端传入数据,在后端写入AttributeMap数据(供后续请求链使用),通过以下方法跳转页面
page.html--->/servlet2--->/servlet3
req.setAttribute("uname","dong");
req.setAttribute("age",18);
//页面转向
req.getRequestDispatcher("/servlet2").forward(req,res);
重定向:不能用req,因为重定向不能传数据
重定向(response.sendRedirect("新URL"))的完整流程是:
- 第一次请求:浏览器访问 ServletA → 服务器返回
302 Found状态码 + 新 URL(如/newPage)。 - 第二次请求:浏览器收到响应后,自动发起新请求到
/newPage→ 服务器处理新请求并返回最终页面。
这是两次完全独立的 HTTP 请求,对应的 request 对象也是两个不同的实例:
- 第一次请求的
req(ServletA 中的req)在响应返回后就被容器销毁了。 - 第二次请求的
req(新 URL 对应的 Servlet 中的req)是全新创建的,和第一次的req没有任何关联。
//重定向
((HttpServletResponse)res).sendRedirect("http://www.baidu.com");

第一次请求,Servlet返回状态码302 + 新 URL( http://www.baidu.com )响应给前端后,req销毁
第二次请求,前端根据URL向百度服务器发起请求,百度服务器响应结果给前端,req销毁
转向和重定向区别
转向:
1.不能访问外网
- 请求不安全,地址栏是第一个请求的地址
- request数据可以传递
重定向:
1.能访问外网
2.请求安全,地址栏是最后一个请求的地址
3.请求范围的数据不传递
十一、Jsp
标签核心对应关系:
<%! %>→ Servlet 类的成员区(成员变量 / 方法,类级别,仅加载一次);<% %>→ Servlet 类_jspService方法内部(局部代码,每次请求执行);<%= %>→_jspService内的out.print()(快速输出动态数据)。
方法定义的核心区别:
<%! %>定义的是成员方法(共享、有线程安全风险);<% %>定义的是局部方法(单次请求有效、无线程安全问题、作用域受限)。
开发规范:JSP 中尽量少定义方法(尤其是 <%! %>),复杂逻辑交给 Servlet/Service 层处理,JSP 仅负责页面渲染。
注释:
<!-- html 注释 前端可以看到-->
<%-- jsp 注释 前端不能看到--%>
浙公网安备 33010602011771号