JavaWeb

Tomcat

  • 官网下载 Core 内容,源文件的路径不要有中文或空格
  • 目录结构
    • bin 可执行文件目录
    • conf 配置文件目录
    • lib 存放各种依赖的jar包
    • logs 日志文件目录
    • webapps 项目部署目录
    • work tomcat的工作目录,存放 JSP 生成的 Servlet 源文件 和 字节码文件
    • temp 临时目录,存放Tomcat运行时产生的临时文件
  • Tomcat 启动方式
  • Tomcat 启动 与 启动命令行日志乱码 问题
  • 访问 Tomcat :http://localhost:8080/
    • 通过该地址,也可以访问 webapps/**/ 下的资源文件,如 http://localhost:8080/examples/index.html 实则访问的是webapps/examples/index.html
      在这里插入图片描述
  • service 部分负责每次接收到请求都通过 Socket 得到请求数据的输入流和返回响应的输出流,会根据请求的输入流和返回响应的输出流创建一个 request 对象、一个 response 对象,然后根据 请求内容+映射(Mapping)规则 将 request、response 对象传给被映射到对应的 applet 的对应方法
  • interface 部分用于作为一种规范,利用多态的特性,service 部分通过 Mapping 找到对应的 applet 后,通过接口调用实际映射到的 applet实例的方法,request、response对象作为方法的入参
  • applet 部分即为实际开发的 servlet 程序,applet 需要继承和实现 interface 部分

JAR和WAR的区别

  • SpringBoot时代之前,项目部署需要提前找到一台服务(Linux),并配置相应的环境如Tomcat、JDK等,然后再将web应用的WAR包放到Tomcat的特定目录,最后调整Tomcat的配置文件,Tomcat会自动解压
  • SpringBoot时代之后,项目部署需要提前找到一台服务(Linux),并配置相应的环境如JDK,然后直接在服务器上运行JAR包,因为SpringBoot项目的web应用已经内置Tomcat,所以也无需调整配置文件

创建一个JavaWeb项目

在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Http 协议

  • Http 称之为 超文本传输协议
  • Http是无状态的
  • Http请求响应包含两个部分:请求和响应
    • 请求包含三个部分: 1.请求行 ; 2.请求消息头 ; 3.请求主体
      • 请求行 包含是三个信息: 1. 请求的方式 ; 2.请求的URL ; 3.请求的协议(一般都是HTTP1.1)
      • 请求消息头 中包含了很多客户端需要告诉服务器的信息,比如:客户端的浏览器型号、版本、能接收的内容的类型、发的内容的类型、内容的长度等等
      • 请求体,三种情况
        • get 方式,没有请求体,但是有一个 queryString
        • post 方式,有请求体:form data
        • json 格式,有请求体:request payload
    • 响应也包含三本: 1. 响应行 ; 2.响应头 ; 3.响应体
      • 响应行包含三个信息:1.协议 2.响应状态码(200) 3.响应状态(ok)
      • 响应头:包含了服务器发送给浏览器的信息(内容的媒体类型、编码、内容长度等)
      • 响应体:响应的实际内容(比如请求 add.html 页面时,响应的内容就是 <form…)
  • 常见响应状态码
    • 200 : 正常响应
    • 404 : 找不到资源
    • 405 : 请求方式不支持
    • 500 : 服务器内部错误

Servlet

  • Servlet 中的核心方法: init() , service() , destroy()

继承关系

  • javax.servlet.Servlet接口
    • javax.servlet.GenericServlet抽象类
      • javax.servlet.http.HttpServlet抽象子类
        • 自定义 Serverlet
          继承关系:自定义 Serverlet -> HttpServlet -> GenericServlet -> Servlet

Servlet接口

void init(config) - 初始化方法
void service(request,response) - 服务方法
void destory() - 销毁方法

GenericServlet 抽象类

  • 对 void init(config) - 初始化方法、void destory() - 销毁方法 空实现
void service(request,response) - 仍然是抽象的

HttpServlet 抽象子类

void service(request,response) - 不是抽象的,具体有如下三步逻辑
1. String method = req.getMethod(); 获取请求的方式
2. 各种if判断,根据请求方式不同,决定去调用不同的do方法
    if (method.equals("GET")) {
        this.doGet(req,resp);
    } else if (method.equals("HEAD")) {
        this.doHead(req, resp);
    } else if (method.equals("POST")) {
        this.doPost(req, resp);
    } else if (method.equals("PUT")) {
         ......
    }
    ......
3.HttpServlet这个抽象类中,doXXX方法都差不多:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String protocol = req.getProtocol();
    String msg = lStrings.getString("http.method_get_not_supported");
    if (protocol.endsWith("1.1")) {
        resp.sendError(405, msg);
    } else {
        resp.sendError(400, msg);
    }
}

Servlet的生命周期

  • 生命周期:从出生到死亡的过程就是生命周期,对应 Servlet 中的三个方法:init(),service(),destroy(),由 Tomcat 负责维护
  • Servlet 在 Tomcat 容器中是:单例的、线程不安全的
    • 对于每个 Servlet 的子类, Tomcat 只会创建一个 实例(通过反射),后续所有匹配到该 实例 的请求都是这个 实例 去服务(调用 service())
    • 默认情况下,只有在接收到第一次请求时,Tomcat 才会去实例化 Servlet 子类 (调用构造方法、初始化(调用 init()),然后再服务(调用 service())
      • 好处是提高系统的启动速度
      • 缺点是第一次请求时,耗时较长
  • 当容器关闭时,其中的所有的 servlet 子类 实例 会被销毁(调用 destroy())
  • 如果需要提高系统的启动速度,按照默认情况 (没有接收到请求时,Tomcat 启动 不需要实例化各种 servlet 子类,所以启动速度快)
  • 如果需要提高响应速度,我们应该设置 Servlet 子类 的实例化时机
    • 通过 在 web.xml 中 来设置 servlet 子类 实例化 的先后顺序,数字越小,启动越靠前,最小值0
    • 当数字比较小时,servlet 子类 实例化 会直接放在 Tomcat 启动阶段,而非接收到 第一个请求后

乱码问题

  • tomcat8 及之后,只需关注 post 请求的乱码
 request.setCharacterEncoding("utf-8"); //防止中文乱码,需要注意的是,设置编码这一句代码必须在所有的获取参数动作之前
  • tomcat8之前,如果是 get 请求接收到的中文数据,转码稍微有点麻烦,需要将请求中的每一个参数都经过如下步骤,post 请求乱码处理 同 tomcat8 及之后
String fname = request.getParameter("fname");
1.将字符串打散成字节数组
byte[] bytes = fname.getBytes("ISO-8859-1");
2.将字节数组按照设定的编码重新组装成字符串
fname = new String(bytes,"UTF-8");
......
  • 还可以通过 Filter ,在doFilter() 前后设置编码

会话 Session

  • 使用会话的原因
    • HTTP 无状态 :服务器无法判断这两次请求是同一个客户端发过来的,还是不同的客户端发过来的
    • 无状态带来的现实问题:第一次请求是添加商品到购物车,第二次请求是结账;如果这两次请求服务器无法区分是同一个用户的,那么就会导致混乱
    • 通过会话跟踪技术来解决无状态的问题
  • 会话跟踪技术
    1. 客户端第一次发请求给服务器,服务器从请求中获取 sessionID,获取不到,则创建新的 session,然后将 sessionID 附带到响应中 给客户端
    2. 客户端 会在其本地保存 sessionID 下次客户端给服务器发请求时,会把 sessionID 带给服务器,那么服务器就能够区分开不同客户端的请求
常用的API:
  request.getSession() -> 获取当前的会话,没有则创建一个新的会话
  request.getSession(true) -> 效果和不带参数相同
  request.getSession(false) -> 获取当前会话,没有则返回null,不会创建新的
  session.getId() -> 获取 sessionID
  session.isNew() -> 判断当前 session 是否是新的
  session.getMaxInactiveInterval() -> session 的非激活间隔时长,默认1800秒
  session.setMaxInactiveInterval()
  session.invalidate() -> 强制性让会话立即失效
  ....
  • session 保存作用域
    • session 保存作用域 就是 专为当前 session 创建的一个 内存空间,可以往里面 存放 键值对 数据 或根据 键值 取出 数据
    • session 保存作用域 是和具体的某一个 session 对应的,一个 sessionID 唯一标识 一个 session 保存作用域,为不同的客户端请求做了一个数据隔离和存储
常用的API:
    void session.setAttribute(k,v)
    Object session.getAttribute(k)
    void removeAttribute(k)
  • sessionID
    • 区分不同的客户端,仅仅是通过 客户端的请求中是否包含相同的 sessionID
    • 即,就算是 同一 用户,如果两次请求的 sessionID 不同,也会认为是 不同的客户端的请求

服务器端内部转发以及客户端重定向

  • 服务器端内部转发以及客户端重定向 即 转发 与 重定向
  • 服务器内部转发
    • 对于客户端而言只有一次的请求、响应的过程,,服务器内部经过了多少次转发,客户端是不知道的
    • 地址栏没有变化
request.getRequestDispatcher("...").forward(request,response);
  • 客户端重定向
    • 对于客户端而言,重定向了多少次,就有多少次 请求、响应 的过程 ,可以被 客户端感知
    • 地址栏有变化
response.sendRedirect("....");

保存作用域

  • 原始情况下,保存作用域我们可以认为有四个: page(页面级别,现在几乎不用) , request(一次请求响应范围) , session(一次会话范围) , application(整个应用程序范围)
    • request:一次请求响应范围
    • session:一次会话范围有效
    • application: 一次应用程序范围有效

Filter 过滤器

  • Filter 也属于 Servlet 规范
  • Filter 开发步骤:新建类实现 Filter 接口,然后实现其中的三个方法:init()、doFilter()、destroy()
    • doFilter() 方法中 filterChain.doFilter(servletRequest,servletResponse) 必须要有,否则 不会执行后续的 servlet
  • 配置 Filter,可以用注解 @WebFilter,也可以使用 web.xml 文件 <filter> <filter-mapping> 类比 servlet
  • 过滤器链
    • 如果采取的是注解的方式进行配置,那么过滤器链的拦截顺序是按照全类名的先后顺序排序的
    • 如果采取的是 web.xml 的方式进行配置,那么按照配置的先后顺序进行排序

监听器 XxxListener

  • Tomcat 启动时,监听器的 实例化

  • ServletContextListener - 监听ServletContext对象的创建和销毁的过程

  • HttpSessionListener - 监听HttpSession对象的创建和销毁的过程

  • ServletRequestListener - 监听ServletRequest对象的创建和销毁的过程

  • ServletContextAttributeListener - 监听ServletContext的保存作用域的改动(add,remove,replace)

  • HttpSessionAttributeListener - 监听HttpSession的保存作用域的改动(add,remove,replace)

  • ServletRequestAttributeListener - 监听ServletRequest的保存作用域的改动(add,remove,replace)

  • HttpSessionBindingListener - 监听某个对象在Session域中的创建与移除

  • HttpSessionActivationListener - 监听某个对象在Session域中的序列化和反序列化

MVC

  • Model(模型)
    • 模型层:模型分为很多种,有比较简单的pojo/vo(value object),有业务模型组件,有数据访问层组件
      • pojo/vo : 值对象 — 直接和数据库中的表对应
      • DAO : 数据访问对象 — 各种dao接口及其实现类
      • BO : 业务对象 — 各种 service 类
      • 区分业务对象和数据访问对象:
        • DAO中的方法都是单精度方法或者称之为细粒度方法。什么叫单精度?一个方法只考虑一个操作,比如添加,那就是insert操作、查询那就是select操作…
        • 一个BO中的方法可能调用了多个DAO中的方法
  • View(视图)
    • 视图层:用于做数据展示以及和用户交互的一个界面
  • Controller(控制器)
    • 控制层:能够接受客户端的请求,具体的业务功能还是需要借助于模型组件来完成

Tomcat 项目部署

热部署

  • idea 设置热部署
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 引入devtools,这种方式不算是热部署,每次修改保存以后都会自动重启项目
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-devtools</artifactId>
</dependency>
  • 通过jrebel,如果是直接下载的破解版,需要如图所示修改启动的配置configuration
    在这里插入图片描述

修改 部署到 Tomcat 的 项目 起始页面

  • 当项目部署到 Tomcat 时,Tomcat 会自动根据 Tomcat 的配置文件 中的 欢迎页面列表 去找对应的 文件作为 项目启动后 起始的默认页面
    • 找到 Tomcat 的配置文件:Tomcat 安装目录 下 conf 目录 的 web.xml
    • 修改如下内容为项目实际的起始页(新增或替换),比如 welcome.html、loginUp.html 等
<welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
  • 修改自己 web 项目的 web.xml 配置文件,新增如上配置,并修改 welcome-file 列表为项目实际起始页面,比如 welcome.html、loginUp.html 等
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值