Java用来开发动态Web的一系列技术(JavaWeb)

JavaWeb的三大组件(接口)【Servlet、Filter、Listener】

  • Servlet****:处理请求的一段服务器小程序;
    • 继承HttpServlet;处理请求,给浏览器响应数据
    • 重写 doXxx():doGet、doPost
    • HttpServletRequest:封装HTTP请求报文数据
      • req.getParameter():获取请求参数(报文:首行url?、请求体)
      • req.getHeader():获取请求头
    • HttpServletResponse:封装HTTP响应报文数据;
      • 响应首行:响应状态码,响应消息
        • 200:ok;成功
        • 302:重定向; 响应头 Location:指向新位置
        • 404:未找到; 路径不对,服务器处理不了
        • 500:服务器内部异常; 程序内部出错
      • resp.setHeader():设置响应头
      • resp.getWriter().write():给响应体写数据;
    • 转发和重定向:前后不分离,服务端渲染页面
      • 转发:req
      • 重定向:resp
    • JSP:动态页面技术
      • **${}**:去域对象中取值
        • 给域中保存值; 域.setAtrribute();
          • request,request.getSession(),request.getServletContext()
        • request域:同一次请求共享数据
        • session域:同一次会话(浏览打开到关闭)
        • application域:Tomcat从打开到关闭
      • 常用标签:c:foreach、c:if
  • Filter:过滤器
    • 过滤请求和响应:请求过来拦截一次,响应出去再拦截一次
    • 继承HttpFilter
      • 重写 doFilter 方法
      • chain.doFilter(req,resp):放行
  • Listener
  • Cookie&Session:会话控制技术

Servlet

Servlet 是 Java 提供的一套用于扩展 Web 服务器功能动态生成 Web 内容的 API(接口规范)和实现。

Server(服务器) + Applet(小程序:Java的代码): 服务器小程序专门处理客户端发来的请求

Servlet 是Web应用的动态资源;

动态/静态资源

静态资源****:无需通过程序运行生成的资源,运行前固定的资源。例如: html、css、js、img、音频、视频文件;

动态资源****:需要启动一段程序(业务逻辑),动态计算后得到的资源。例如:用户订单数据商品秒杀库存

Web应用中,万物皆资源;

Servlet 作用

  • Servlet 运行是在 Web 服务器(如 Tomcat, Jetty, WildFly, GlassFish)上运行的一段程序(更准确地说,是在支持 Servlet 规范的 Servlet 容器内)。
  • 它负责处理 客户端(通常是浏览器)发来的 HTTP 请求HttpServletRequest),并根据请求逻辑动态生成内容(HTML, JSON, XML 等),然后将这些内容封装在 HTTP 响应HttpServletResponse) 中返回给客户端。
  • 它是 Java EE / Jakarta EE 平台的核心基础技术之一,也是绝大多数 Java Web 框架(如 Spring MVC, JSF, Struts)的底层基石。
  1. 浏览器发送一个请求:Tomcat收到把HTTP请求报文的所有内容封装成HttpServletRequest对象。
  2. 自己写一个Servlet处理业务逻辑
  3. 服务器给浏览器返回响应:Tomcat把返回的数据 封装给HttpServletResponse; 服务器会把response对象自己转为HTTP响应数据报文,返回给浏览器

Servlet代码

package com.wys.demo;
import java.io.*;

import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;

@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpSerlet{
private String message;

public void init(){
message = "Hello World!";
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>" + message + "</h1>");
out.println("</body></html>")
}

public void destroy(){

}
}

HttpServletRequest

读取请求参数

  • getParameter: 获取某个请求参数的值;
  • getParameter: 获取所有请求参数的名字;
  • getParameterMap: 获取所有请求参数名字和值对应的Map
  • getParameterValues: 获取某个参数的所有值

读取请求头

  • getHeader:获取某个请求头的值,多个值则返回第一个
  • getHeaders:获取某个请求头的所有值
  • getHeaderNames:获取所有请求头名字
  • getDateHeader:获取某个请求头的值,并解析为时间
  • getIntHeader:获取某个请求头的值,并解析为整数

转发与重定向

转发

req.getRequestDispatcher("/success.jsp").forward(req, resp)
特性 转发 (Forward) 重定向 (Redirect)
基本机制 服务器内部跳转 客户端重新请求
HTTP行为 1次请求,1次响应 2次请求,2次响应
浏览器地址栏 不变 (保留原始URL) 改变 (显示新URL)
请求对象 使用同一个request对象 创建新的request对象
作用域数据 request/session/context数据保留 仅session/context数据保留
性能 高效 (服务器内部处理) 较低 (多一次往返)
代码实现 request.getRequestDispatcher(“path”).forward(req,resp); response.sendRedirect(“newURL”);
跨应用支持 ❌ 仅限当前应用内 ✅ 可跳转到任意URL(跨应用/域名)
WEB-INF资源 可以访问 WEB-INF 下的受保护资源 不可以直接访问 WEB-INF 下的受保护资源
SEO影响 原始URL与内容不对应 最终URL与内容一致
典型应用场景 MVC模式中转交控制权 (Controller → View) 登录后跳转 表单提交防刷新 跨站点跳转

重定向:不害怕页面刷新。页面刷新不会导致重复提交

转发:浏览器url不变,还是原来的请求,刷新会导致重复提交

路径问题

相对路径:****浏览器计算路径,参照当前路径(就是地址栏的当前url地址)

  1. **./**:代表在当前资源同路径下
  2. **../**:代表在当前资源父路径
  3. /:在web中,代表根路径(注意:根路径在客户端和服务端是不一样的

绝对路径

  1. 完全写全地址:https://www.baidu.com

最佳实践:

  1. 浏览器全部使用 /项目路径 这种写法;
  2. 结合 base 标签指定基准url; 如:<base href="/web03">

特别注意:

JSP(了解)

首先引入依赖

<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.1</version>
</dependency>

页面动态取值

**${}**: 动态取出值

页面数据遍历/判断

<%@ taglib prefix="c" uri="``http://java.sun.com/jsp/jstl/core``" %> 放在第二行,重启项目

c:if

<c:if test="testCondition"
[var="varName"] [scope="{page|request|session|application}"]>
body content
</c:if>

c:forEach

<c:forEach  [var="varName"] items="collection"
[varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>

页面间数据共享

放数据:四大对象.setAttribute(key,value)

取数据

  • Java代码:四大对象.getAttribute(key)
  • JSP页面: ${key}

request域共享数据

session域共享数据

application域共享数据

Filter:过滤器

Filter,即过滤器,是JAVAEE技术规范之一,作为目标资源的请求进行过滤的一套技术规范,是Java Web项目中最为实用的技术之一

  • Filter接口定义了过滤器的开发规范,所有的过滤器都要实现该接口;
  • Filter的工作位置
    • 请求进来,在目标方法执行之前进行过滤; 此时可以校验/修改请求数据等
    • 响应出去,在抵达页面之前进行过滤;此时可以校验/修改响应数据等
  • Filter是GOF中责任链模式的典型案例;
  • Filter的常用应用包括但不限于:
    • 登录权限检查、解决网站乱码、过滤敏感字符、日志记录、性能分析… …;

Listener

生命周期监听器:(从创建到销毁过程)

  • ServletContextListener:监听ServletContext(Application)整个应用的启动、销毁

    • contextInitialized:应用启动回调
    • contextDestroyed:应用销毁回调
  • HttpSessionListener:监听Session对象的创建和销毁

    • sessionCreated:session对象创建;代表一个新浏览器开始和服务器产生会话
    • sessionDestroyed:session对象销毁;代表一个会话结束(30min分钟过期、invalidate())
  • ServletRequestListener:监听request对象的创建和销毁

    • requestInitialized:request对象初始化; 代表浏览器发了一个请求进来
    • requestDestroyed:request对象销毁; 响应结束,req就销毁
  • 不监听Page对象

域对象属性增减监听器:域对象中只要设置了属性,修改属性,删除了属性就感知到了

  • ServletRequestAttributeListener:监听req对象中 set/removeAttribute 变化

    • attributeAdded():属性增加; 说明有人给 req.setAtrribute();
    • attributeRemoved():属性删除; 说明有人给 req.removeAtrribute();
    • attributeReplaced():属性替换;说明有人 req.setAtrribute() 更改了属性
  • HttpSessionAttributeListener:监听 session对象 set/removeAttribute 变化

    • attributeAdded():属性增加; 说明有人给 session.setAtrribute();
    • attributeRemoved():属性删除; 说明有人给 session.removeAtrribute();
    • attributeReplaced():属性替换;说明有人 session.setAtrribute() 更改了属性
  • ServletContextAttributeListener:监听 application对象 set/removeAttribute 变化

    • attributeAdded():属性增加; 说明有人给 appliaction.setAtrribute();
    • attributeRemoved():属性删除; 说明有人给 appliaction.removeAtrribute();
    • attributeReplaced():属性替换;说明有人 appliaction.setAtrribute() 更改了属性

针对session又扩展两个:

  1. HttpSessionActivationListener****:session激活监听器;
    • sessionDidActivate:活化:Tomcat重启后,把硬盘中的之前存的session数据重新加载进来。
    • sessionWillPassivate:钝化:Tomcat运行时给session中保存了一堆数据;现在关机,啥都不管数据会丢失,Tomcat允许吧这些数据用序列化机制,写到硬盘;
  2. HttpSessionBindingListener****: 监听session中一个特定对象的绑定和解绑
    • valueBound: 指定对象绑定到session中
    • valueUnbound:指定对象从session中删除
监听器接口 作用域 监听事件 主要用途 场景案例
ServletContextListener 应用级别 contextInitialized() contextDestroyed() 应用启动/关闭时的资源初始化和清理 加载全局配置、初始化连接池
ServletContextAttribute Listener 应用级别 attributeAdded() attributeRemoved() attributeReplaced() 全局属性变化监控 跟踪共享数据的修改记录
HttpSessionListener 会话级别 sessionCreated() sessionDestroyed() 会话创建/销毁监控 统计在线用户数、会话超时处理
HttpSessionAttribute Listener 会话级别 attributeAdded() attributeRemoved() attributeReplaced() 会话属性变化监控 用户登录状态跟踪、会话数据审计
HttpSessionActivation Listener 会话级别 sessionWillPassivate() sessionDidActivate() 会话序列化(钝化)/反序列化(活化) 分布式环境下的会话迁移
HttpSessionBindingListener 会话级别 valueBound() valueUnbound() 对象绑定到Session/从Session解绑 实现该接口的对象自动触发(无需配置)
ServletRequestListener 请求级别 requestInitialized() requestDestroyed() 请求开始/结束监控 请求日志记录、请求耗时统计
ServletRequestAttribute Listener 请求级别 attributeAdded() attributeRemoved() attributeReplaced() 请求属性变化监控 请求参数处理跟踪

Session

Session是服务器端保存数据的一种技术; 同一次会话保存的数据,所有页面都能用到

session获取

// 获取现有 Session 或创建新 Session
HttpSession session = request.getSession();

// 仅获取现有 Session (若无则返回 null)
HttpSession session = request.getSession(false);

session存取

User user = new User("john");
sesson.setAttribute("currentUser", user);
User currentUser = (User) session.getAttribute("currentUser");
session.removeAttribute("currentUser");
Enumeration<String> attrs = session.getAttributeNames();
while(attrs.hasMoreElements()){
String name = attrs.nextElement();
Object value = session.getAttribute(name);
}