JAVA web学习笔记

文章目录

  • 布置tomcat
    • 新建module
    • 配置config
  • tomcat布置好后。再导入jdbc的包时
  • 处理请求参数中中文乱码
  • 笔记1
  • 调试时,存在的html,不存在的html
  • web根目录
  • html中敲thymeleaf
  • 拷贝Module
  • 复习1笔记
  • 相对路径和绝对路径
  • 正常运行页面
  • xml
  • 反射,获取参数名称,需要file-setting设置
  • argument type mismatch 错误
  • p17readme笔记
  • P20readme
  • cookie readme
  • 网页右键检查,element
  • pro28 readme

布置tomcat

新建module

IDEA新建module的时候没有javaee的选项,这时候可以先选择普通的java项目进行创建。
JAVA web学习笔记_第1张图片
图片中的a就是新建的java module。
JAVA web学习笔记_第2张图片
右键a文件夹,选择Add Framework Support。
JAVA web学习笔记_第3张图片
然后选中Web Application,点击右下角的ok即可。

a文件夹下出现带小蓝的web就说明成功了。
JAVA web学习笔记_第4张图片

配置config

JAVA web学习笔记_第5张图片
JAVA web学习笔记_第6张图片
JAVA web学习笔记_第7张图片

JAVA web学习笔记_第8张图片
JAVA web学习笔记_第9张图片
JAVA web学习笔记_第10张图片

JAVA web学习笔记_第11张图片
关联相关包
将jar包拷到libs文件夹下,右键add as library
JAVA web学习笔记_第12张图片
JAVA web学习笔记_第13张图片

JAVA web学习笔记_第14张图片

JAVA web学习笔记_第15张图片

tomcat布置好后。再导入jdbc的包时

tomcat 学习中。tomcat布置好后。再导入jdbc的包时。需要如下操作一下。不然使用jdbc包会奔溃。
JAVA web学习笔记_第16张图片

处理请求参数中中文乱码

笔记1

  1. 设置编码
    tomcat8之前,设置编码:
    1)get请求方式:
    //get方式目前不需要设置编码(基于tomcat8)
    //如果是get请求发送的中文数据,转码稍微有点麻烦(tomcat8之前)
    String fname = request.getParameter(“fname”);
    //1.将字符串打散成字节数组
    byte[] bytes = fname.getBytes(“ISO-8859-1”);
    //2.将字节数组按照设定的编码重新组装成字符串
    fname = new String(bytes,“UTF-8”);
    2)post请求方式:
    request.setCharacterEncoding(“UTF-8”);
    tomcat8开始,设置编码,只需要针对post方式
    request.setCharacterEncoding(“UTF-8”);
    注意:
    需要注意的是,设置编码(post)这一句代码必须在所有的获取参数动作之前

  2. Servlet的继承关系 - 重点查看的是服务方法(service())

    1. 继承关系
      javax.servlet.Servlet接口
      javax.servlet.GenericServlet抽象类
      javax.servlet.http.HttpServlet抽象子类

    2. 相关方法
      javax.servlet.Servlet接口:
      void init(config) - 初始化方法
      void service(request,response) - 服务方法
      void destory() - 销毁方法

    javax.servlet.GenericServlet抽象类:
    void service(request,response) - 仍然是抽象的

    javax.servlet.http.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这个抽象类中,do方法都差不多:
    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);
    }
    }
    3.小结:

    1. 继承关系: HttpServlet -> GenericServlet -> Servlet
    2. Servlet中的核心方法: init() , service() , destroy()
    3. 服务方法: 当有请求过来时,service方法会自动响应(其实是tomcat容器调用的)
      在HttpServlet中我们会去分析请求的方式:到底是get、post、head还是delete等等
      然后再决定调用的是哪个do开头的方法
      那么在HttpServlet中这些do方法默认都是405的实现风格-要我们子类去实现对应的方法,否则默认会报405错误
    4. 因此,我们在新建Servlet时,我们才会去考虑请求方法,从而决定重写哪个do方法
  3. Servlet的生命周期
    1) 生命周期:从出生到死亡的过程就是生命周期。对应Servlet中的三个方法:init(),service(),destroy()
    2) 默认情况下:
    第一次接收请求时,这个Servlet会进行实例化(调用构造方法)、初始化(调用init())、然后服务(调用service())
    从第二次请求开始,每一次都是服务
    当容器关闭时,其中的所有的servlet实例会被销毁,调用销毁方法
    3) 通过案例我们发现:
    - Servlet实例tomcat只会创建一个,所有的请求都是这个实例去响应。
    - 默认情况下,第一次请求时,tomcat才会去实例化,初始化,然后再服务.这样的好处是什么? 提高系统的启动速度 。 这样的缺点是什么? 第一次请求时,耗时较长。
    - 因此得出结论: 如果需要提高系统的启动速度,当前默认情况就是这样。如果需要提高响应速度,我们应该设置Servlet的初始化时机。
    4) Servlet的初始化时机:
    - 默认是第一次接收请求时,实例化,初始化
    - 我们可以通过来设置servlet启动的先后顺序,数字越小,启动越靠前,最小值0
    5) Servlet在容器中是:单例的、线程不安全的
    - 单例:所有的请求都是同一个实例去响应
    - 线程不安全:一个线程需要根据这个实例中的某个成员变量值去做逻辑判断。但是在中间某个时机,另一个线程改变了这个成员变量的值,从而导致第一个线程的执行路径发生了变化
    - 我们已经知道了servlet是线程不安全的,给我们的启发是: 尽量的不要在servlet中定义成员变量。如果不得不定义成员变量,那么不要去:①不要去修改成员变量的值 ②不要去根据成员变量的值做一些逻辑判断

  4. Http协议
    1) Http 称之为 超文本传输协议
    2) Http是无状态的
    3) Http请求响应包含两个部分:请求和响应

    • 请求:
      请求包含三个部分: 1.请求行 ; 2.请求消息头 ; 3.请求主体
      1)请求行包含是三个信息: 1. 请求的方式 ; 2.请求的URL ; 3.请求的协议(一般都是HTTP1.1)
      2)请求消息头中包含了很多客户端需要告诉服务器的信息,比如:我的浏览器型号、版本、我能接收的内容的类型、我给你发的内容的类型、内容的长度等等
      3)请求体,三种情况
      get方式,没有请求体,但是有一个queryString
      post方式,有请求体,form data
      json格式,有请求体,request payload
    • 响应:
      响应也包含三本: 1. 响应行 ; 2.响应头 ; 3.响应体
      1)响应行包含三个信息:1.协议 2.响应状态码(200) 3.响应状态(ok)
      2)响应头:包含了服务器的信息;服务器发送给浏览器的信息(内容的媒体类型、编码、内容长度等)
      3)响应体:响应的实际内容(比如请求add.html页面时,响应的内容就是
  5. 会话
    1) Http是无状态的
    - HTTP 无状态 :服务器无法判断这两次请求是同一个客户端发过来的,还是不同的客户端发过来的
    - 无状态带来的现实问题:第一次请求是添加商品到购物车,第二次请求是结账;如果这两次请求服务器无法区分是同一个用户的,那么就会导致混乱
    - 通过会话跟踪技术来解决无状态的问题。

    2) 会话跟踪技术
    一个浏览器会是一个session,同一个浏览器的不同页面是同一个session。不同浏览器是不同session.
    - 客户端第一次发请求给服务器,服务器获取session,获取不到,则创建新的,然后响应给客户端
    - 下次客户端给服务器发请求时,会把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() -> 强制性让会话立即失效
       ....
    

    3) session保存作用域

    • session保存作用域是和具体的某一个session对应的
    • 常用的API:
      void session.setAttribute(k,v)
      Object session.getAttribute(k)
      void removeAttribute(k)
  6. 服务器内部转发以及客户端重定向
    1) 服务器内部转发 : request.getRequestDispatcher(“…”).forward(request,response);

    • 一次请求响应的过程,对于客户端而言,内部经过了多少次转发,客户端是不知道的
    • 地址栏没有变化
      2) 客户端重定向: response.sendRedirect(“…”);
    • 两次请求响应的过程。客户端肯定知道请求URL有变化
    • 地址栏有变化
  7. Thymeleaf - 视图模板技术
    1) 添加thymeleaf的jar包
    2) 新建一个Servlet类ViewBaseServlet
    3) 在web.xml文件中添加配置
    - 配置前缀 view-prefix
    - 配置后缀 view-suffix
    4) 使得我们的Servlet继承ViewBaseServlet

    5) 根据逻辑视图名称 得到 物理视图名称
    //此处的视图名称是 index
    //那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图 名称上去
    //逻辑视图名称 : index
    //物理视图名称 : view-prefix + 逻辑视图名称 + view-suffix
    //所以真实的视图名称是: / index .html
    super.processTemplate(“index”,request,response);
    6) 使用thymeleaf的标签
    th:if , th:unless , th:each , th:text

// 200 : 正常响应
// 404 : 找不到资源
// 405 : 请求方式不支持
// 500 : 服务器内部错误

调试时,存在的html,不存在的html

存在的html用http://localhost:8080/pro08/add2.html访问,不存在的html用http://localhost:8080/pro08/add2访问(结尾不带.html),这样可进行调试

web根目录

JAVA web学习笔记_第17张图片

html中敲thymeleaf

添加lib,记得在file-project Structure-module中添加关联,和problem点fix
JAVA web学习笔记_第18张图片
JAVA web学习笔记_第19张图片

JAVA web学习笔记_第20张图片
alt+enter后多了这一行
JAVA web学习笔记_第21张图片
将这一行改为,改完后,敲代码就有提示了
JAVA web学习笔记_第22张图片
JAVA web学习笔记_第23张图片

拷贝Module

ctrl +c,ctr+ v
JAVA web学习笔记_第24张图片
右键重命名iml文件

JAVA web学习笔记_第25张图片
JAVA web学习笔记_第26张图片
这样操作以后,新的module各种依赖都有
JAVA web学习笔记_第27张图片

,WEB也是蓝色的,
mudule文件夹有蓝色的方框代表以及成功加入项目了。
JAVA web学习笔记_第28张图片
添加Artifacts
JAVA web学习笔记_第29张图片
JAVA web学习笔记_第30张图片

配置一下config
JAVA web学习笔记_第31张图片
删掉旧的
JAVA web学习笔记_第32张图片
添加新的
JAVA web学习笔记_第33张图片
JAVA web学习笔记_第34张图片
设置server
JAVA web学习笔记_第35张图片

复习1笔记

review:

  1. post提交方式下的设置编码,防止中文乱码
    request.setCharacterEncoding(“utf-8”);
    get提交方式,tomcat8开始,编码不需要设置
    tomcat8之前,get方式设置比较麻烦:
    String fname = request.getParameter(“fname”);
    byte[] bytes = fname.getBytes(“iso-8859-1”);
    fname = new String(bytes,“UTF-8”);

  2. Servlet继承关系以及生命周期
    1) Servlet接口 : init() , service() , destroy()
    GenericServlet抽象子类: abstract service();
    HttpServlet抽象子类:实现了service方法,在service方法内部通过request.getMethod()来判断请求的方式,
    然后根据请求的方式去调用内部的do方法。每一个do方法进行了简单实现,主要是如果请求方式不符合,则报405错误。
    目的是让我们的Servlet子类去重写对应的方法(如果重写的不对,则使用父类的405错误实现)
    2) 生命周期:实例化、初始化、服务、销毁
    - Tomcat负责维护Servlet实例的生命周期
    - 每个Servlet在Tomcat容器中只有一个实例,它是线程不安全的
    - Servlet的启动时机:
    - Servlet3.0开始支持注解: @WebServlet

  3. HTTP协议:
    1) 由 Request 和 Response 两部分组成
    2) 请求包含了三部分:请求行、请求消息头、请求主体: 普通的get方式请求-query string;post方式- form data ; json格式 - request payload
    3) 响应包含了三部分:响应行、响应消息头、响应主体

  4. HttpSession
    1) HttpSession :表示 会话
    2) 为什么需要HttpSession , 原因是因为 Http协议是无状态的
    3) Session保存作用域 :一次会话范围都有效 ; void session.setAttribute(k,v) ,Object session.getAttribute(k)
    4) 其他的API: session.getId() , session.isNew() , session.getCreationTime() , session.invalidate() 等等

  5. 服务器端转发和客户端重定向

    1. 服务器端转发 : request.getRequestDispatcher(“index.html”).forward(request,response);
    2. 客户端重定向: response.sendRedirect(“index.html”);
  6. thymeleaf的部分标签
    1) 使用步骤: 添加jar , 新建ViewBaseServlet(有两个方法) , 配置两个 : view-prefix , view-suffix
    2) 部分标签: th:if , th:unless , th:each , th:text

今日内容:

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

  2. 路径问题
    1) 相对路径
    2) 绝对路径

  3. 实现库存系统的功能

相对路径和绝对路径

JAVA web学习笔记_第36张图片
JAVA web学习笔记_第37张图片

正常运行页面

JAVA web学习笔记_第38张图片
JAVA web学习笔记_第39张图片

xml



<beans>
    
    <bean id="fruit" class="com.atguigu.fruit.controllers.FruitController"/>
beans>






反射,获取参数名称,需要file-setting设置

JAVA web学习笔记_第40张图片
JAVA web学习笔记_第41张图片
JAVA web学习笔记_第42张图片
build完成后,out文件夹会多一个production文件夹
JAVA web学习笔记_第43张图片
JAVA web学习笔记_第44张图片
JAVA web学习笔记_第45张图片
完成后会多一个artifacts文件夹
JAVA web学习笔记_第46张图片
JAVA web学习笔记_第47张图片
JAVA web学习笔记_第48张图片

argument type mismatch 错误

此次是需要使用Integer类型的参数,但是直接获取到的是String类型,所以需要进行类型判断,然后转换成Integer
JAVA web学习笔记_第49张图片

JAVA web学习笔记_第50张图片

//从请求中获取参数值
                            String parameterValue = request.getParameter(parameterName);
                            String typeName = parameter.getType().getName();

                            Object parameterObj = parameterValue ;

                            if(parameterObj!=null) {
                                if ("java.lang.Integer".equals(typeName)) {
                                    parameterObj = Integer.parseInt(parameterValue);
                                }
                            }

                            parameterValues[i] = parameterObj ;

p17readme笔记

review:

  1. 最初的做法是: 一个请求对应一个Servlet,这样存在的问题是servlet太多了
  2. 把一些列的请求都对应一个Servlet, IndexServlet/AddServlet/EditServlet/DelServlet/UpdateServlet -> 合并成FruitServlet
    通过一个operate的值来决定调用FruitServlet中的哪一个方法
    使用的是switch-case
  3. 在上一个版本中,Servlet中充斥着大量的switch-case,试想一下,随着我们的项目的业务规模扩大,那么会有很多的Servlet,也就意味着会有很多的switch-case,这是一种代码冗余
    因此,我们在servlet中使用了反射技术,我们规定operate的值和方法名一致,那么接收到operate的值是什么就表明我们需要调用对应的方法进行响应,如果找不到对应的方法,则抛异常
  4. 在上一个版本中我们使用了反射技术,但是其实还是存在一定的问题:每一个servlet中都有类似的反射技术的代码。因此继续抽取,设计了中央控制器类:DispatcherServlet
    DispatcherServlet这个类的工作分为两大部分:
    1.根据url定位到能够处理这个请求的controller组件:
    1)从url中提取servletPath : /fruit.do -> fruit
    2)根据fruit找到对应的组件:FruitController , 这个对应的依据我们存储在applicationContext.xml中
  5. 在web.xml文件中配置Servlet

    Demo01Servlet
    com.atguigu.servlet.Demo01Servlet

    hello
    world


    uname
    jim



    Demo01Servlet
    /demo01
  6. 也可以通过注解的方式进行配置:
    @WebServlet(urlPatterns = {“/demo01”} ,
    initParams = {
    @WebInitParam(name=“hello”,value=“world”),
    @WebInitParam(name=“uname”,value=“jim”)
    })
  1. 学习Servlet中的ServletContext和

    1. 获取ServletContext,有很多方法
      在初始化方法中: ServletContxt servletContext = getServletContext();
      在服务方法中也可以通过request对象获取,也可以通过session获取:
      request.getServletContext(); session.getServletContext()
    2. 获取初始化值:
      servletContext.getInitParameter();
  2. 什么是业务层

    1. Model1和Model2
      MVC : Model(模型)、View(视图)、Controller(控制器)
      视图层:用于做数据展示以及和用户交互的一个界面
      控制层:能够接受客户端的请求,具体的业务功能还是需要借助于模型组件来完成
      模型层:模型分为很多种:有比较简单的pojo/vo(value object),有业务模型组件,有数据访问层组件

      1. pojo/vo : 值对象
      2. DAO : 数据访问对象
      3. BO : 业务对象
    2. 区分业务对象和数据访问对象:
      1) DAO中的方法都是单精度方法或者称之为细粒度方法。什么叫单精度?一个方法只考虑一个操作,比如添加,那就是insert操作、查询那就是select操作…
      2) BO中的方法属于业务方法,也实际的业务是比较复杂的,因此业务方法的粒度是比较粗的
      注册这个功能属于业务功能,也就是说注册这个方法属于业务方法。
      那么这个业务方法中包含了多个DAO方法。也就是说注册这个业务功能需要通过多个DAO方法的组合调用,从而完成注册功能的开发。
      注册:
      1. 检查用户名是否已经被注册 - DAO中的select操作
      2. 向用户表新增一条新用户记录 - DAO中的insert操作
      3. 向用户积分表新增一条记录(新用户默认初始化积分100分) - DAO中的insert操作
      4. 向系统消息表新增一条记录(某某某新用户注册了,需要根据通讯录信息向他的联系人推送消息) - DAO中的insert操作
      5. 向系统日志表新增一条记录(某用户在某IP在某年某月某日某时某分某秒某毫秒注册) - DAO中的insert操作
      6. …

    3. 在库存系统中添加业务层组件

  3. IOC

    1. 耦合/依赖
      依赖指的是某某某离不开某某某
      在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。
      我们系统架构或者是设计的一个原则是: 高内聚低耦合。
      层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)
    2. IOC - 控制反转 / DI - 依赖注入
  4. 过滤器Filter

  5. 事务管理

  6. TransActionManager、ThreadLocal、OpenSessionInViewFilter

P20readme

review:

  1. Servlet生命周期中的初始化方法: init() , init(config)
    public void init(ServletConfig config) throws ServletException {
    this.config = config ;
    init();
    }
    因此,如果我们需要在初始化时执行一些自定义的操作,那么我们可以重写无参的init方法。
    我们可以通过getConfig()获取ServletConfig对象
    可以通过config.getInitParameter()获取初始化参数

  2. 通过ServletContext获取配置的上下文参数

  3. MVC : V:view 视图 ; C:Controller 控制器 ; M:Model 模型
    模型有很多种类:数据访问模型(DAO);业务逻辑模型(BO);值对象模型(POJO);数据传输对象(DTO)

  4. IOC
    IOC - 控制反转 / DI - 依赖注入
    控制反转:

    1. 之前在Servlet中,我们创建service对象 , FruitService fruitService = new FruitServiceImpl();
      这句话如果出现在servlet中的某个方法内部,那么这个fruitService的作用域(生命周期)应该就是这个方法级别;
      如果这句话出现在servlet的类中,也就是说fruitService是一个成员变量,那么这个fruitService的作用域(生命周期)应该就是这个servlet实例级别
    2. 之后我们在applicationContext.xml中定义了这个fruitService。然后通过解析XML,产生fruitService实例,存放在beanMap中,这个beanMap在一个BeanFactory中
      因此,我们转移(改变)了之前的service实例、dao实例等等他们的生命周期。控制权从程序员转移到BeanFactory。这个现象我们称之为控制反转

    依赖注入:

    1. 之前我们在控制层出现代码:FruitService fruitService = new FruitServiceImpl();
      那么,控制层和service层存在耦合。
    2. 之后,我们将代码修改成FruitService fruitService = null ;
      然后,在配置文件中配置:


今日内容:
1. 过滤器Filter
2. 事务管理(TransactionManager、ThreadLocal、OpenSessionInViewFilter)
3. 监听器(Listener , ContextLoaderListener)

  1. 过滤器Filter
  1. Filter也属于Servlet规范
  2. Filter开发步骤:新建类实现Filter接口,然后实现其中的三个方法:init、doFilter、destroy
    配置Filter,可以用注解@WebFilter,也可以使用xml文件
  3. Filter在配置时,和servlet一样,也可以配置通配符,例如 @WebFilter(“*.do”)表示拦截所有以.do结尾的请求
  4. 过滤器链
    1)执行的顺序依次是: A B C demo03 C2 B2 A2
    2)如果采取的是注解的方式进行配置,那么过滤器链的拦截顺序是按照全类名的先后顺序排序的,即字母顺序。
    3)如果采取的是xml的方式进行配置,那么按照配置的先后顺序进行排序
  1. 事务管理

    1. 涉及到的组件:
    • OpenSessionInViewFilter
    • TransactionManager
    • ThreadLocal
    • ConnUtil
    • BaseDAO
    1. ThreadLocal
    • get() , set(obj)
    • ThreadLocal称之为本地线程 。 我们可以通过set方法在当前线程上存储数据、通过get方法在当前线程上获取数据
    • set方法源码分析:
      public void set(T value) {
      Thread t = Thread.currentThread(); //获取当前的线程
      ThreadLocalMap map = getMap(t); //每一个线程都维护各自的一个容器(ThreadLocalMap)
      if (map != null)
      map.set(this, value); //这里的key对应的是ThreadLocal,因为我们的组件中需要传输(共享)的对象可能会有多个(不止Connection)
      else
      createMap(t, value); //默认情况下map是没有初始化的,那么第一次往其中添加数据时,会去初始化
      }
      -get方法源码分析:
      public T get() {
      Thread t = Thread.currentThread(); //获取当前的线程
      ThreadLocalMap map = getMap(t); //获取和这个线程(企业)相关的ThreadLocalMap(也就是工作纽带的集合)
      if (map != null) {
      ThreadLocalMap.Entry e = map.getEntry(this); //this指的是ThreadLocal对象,通过它才能知道是哪一个工作纽带
      if (e != null) {
      @SuppressWarnings(“unchecked”)
      T result = (T)e.value; //entry.value就可以获取到工具箱了
      return result;
      }
      }
      return setInitialValue();
      }
  2. 监听器

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

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

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

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

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

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

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

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

  3. ServletContextListener的应用 - ContextLoaderListener

cookie readme

  1. Cookie

    1. 创建Cookie对象
    2. 在客户端保存Cookie
    3. 设置Cookie的有效时长
      cookie.setMaxAge(60) , 设置cookie的有效时长是60秒
      cookie.setDomain(pattern);
      cookie.setPath(uri);
    4. Cookie的应用:
      4-1: 记住用户名和密码十天 setMaxAge(60 * 60 * 24 * 10)
      4-2: 十天免登录
  2. Kaptcha

    1. 为什么需要验证码
    2. kaptcha如何使用:
      • 添加jar
      • 在web.xml文件中注册KaptchaServlet,并设置验证码图片的相关属性
      • 在html页面上编写一个img标签,然后设置src等于KaptchaServlet对应的url-pattern
    3. kaptcha验证码图片的各个属性在常量接口:Constants中
    4. KaptchaServlet在生成验证码图片时,会同时将验证码信息保存到session中
      因此,我们在注册请求时,首先将用户文本框中输入的验证码值和session中保存的值进行比较,相等,则进行注册
  3. JS - Exp
    1)正则表达式的使用三步骤:
    1. 定义正则表达式对象
    正则表达式定义有两个方式:
    1) 对象形式
    var reg = new RegExp(“abc”)
    2) 直接量形式
    var reg = /abc/;
    3) 匹配模式:
    - g 全局匹配
    - i 忽略大小写匹配
    - m 多行匹配
    - gim这三个可以组合使用,不区分先后顺序
    例如: var reg = /abc/gim , var reg = new RegExp(“abc”,“gim”);
    2. 定义待校验的字符串
    3. 校验
    2)元字符
    . , \w , \W , \s , \S , \d , \D , \b , ^ , $

    3)[]表示集合
    [abc] 表示 a或者b或者c
    [^abc] 表示取反,只要不是a不是b不是c就匹配
    [a-c] 表示a到c这个范围匹配

    1. 出现的次数
    • 表示多次 (0 ~ n )
    • 至少一次 ( >=1 )
      ? 最多一次 (0 ~ 1)
      {n} 出现n次
      {n,} 出现n次或者多次
      {n,m} 出现n到m次

网页右键检查,element

 ![在这里插入图片描述](https://img-blog.csdnimg.cn/7341e6bbd53c4267b393f34e9cbafb08.png)
 # 网页右键检查,network![在这里插入图片描述](https://img-blog.csdnimg.cn/91d0d4b30475452b95438f8650dd0e2d.png)

pro28 readme

 1. 回顾:
Ajax : 异步的JavaScript and XML
目的: 用来发送异步的请求,然后当服务器给我响应的时候再进行回调操作
好处: 提高用户体验;局部刷新:降低服务器负担、减轻浏览器压力、减轻网络带宽压力
开发步骤:
  1) 创建XMLHttpRequest
  2) 调用open进行设置:"GET" , URL , true
  3) 绑定状态改变时执行的回调函数 - onreadystatechange
  4) 发送请求 - send()
  5) 编写回调函数,在回调函数中,我们只对XMLHttpRequest的readystate为4的时候感兴趣
                            我们只对XMLHttpRequest的status为200的时候感兴趣

0: (Uninitialized) the send( ) method has not yet been invoked.
1: (Loading) the send( ) method has been invoked, request in progress.
2: (Loaded) the send( ) method has completed, entire response received.
3: (Interactive) the response is being parsed.
4: (Completed) the response has been parsed, is ready for harvesting.

0 - (未初始化)还没有调用send()方法
1 - (载入)已调用send()方法,正在发送请求
2 - (载入完成)send()方法执行完成,已经接收到全部响应内容
3 - (交互)正在解析响应内容
4 - (完成)响应内容解析完成,可以在客户端调用了

今天内容:

  1. Vue

    1. {{}} - 相当于innerText
    2. v-bind:attr 绑定属性值。例如,v-bind:value - 绑定value值
      简写: :value
    3. v-model 双向绑定
      v-model:value , 简写 v-model
    4. v-if , v-else , v-show
      v-if和v-else之间不能有其他的节点
      v-show是通过样式表display来控制节点是否显示
    5. v-for 迭代
      v-for={fruit in fruitList}
    6. v-on 绑定事件
    7. 其他:
      • trim:去除首尾空格 , split() , join()
      • watch表示侦听属性
      • 生命周期
  2. Axios
    Axios是Ajax的一个框架,简化Ajax操作
    Axios执行Ajax操作的步骤:

    1. 添加并引入axios的js文件

    2-1. 客户端向服务器端异步发送普通参数值

    • 基本格式: axios().then().catch()

    • 示例:
      axios({
      method:“POST”,
      url:“…”,
      params:{
      uname:“lina”,
      pwd:“ok”
      }
      })
      .then(function(value){}) //成功响应时执行的回调 value.data可以获取到服务器响应内容
      .catch(function(reason){}); //有异常时执行的回调 reason.response.data可以获取到响应的内容

                                                               reason.message / reason.stack 可以查看错误的信息
      

    2-2. 客户端向服务器发送JSON格式的数据

    • 什么是JSON
      JSON是一种数据格式
      XML也是一种数据格式
      XML格式表示两个学员信息的代码如下:


      jim
      18


      tom
      19


      JSON格式表示两个学员信息的代码如下:
      [{sid:“s001”,age:18},{sid:“s002”,age:19}]
    • JSON表达数据更简洁,更能够节约网络带宽
    • 客户端发送JSON格式的数据给服务器端
    1. 客户端中params需要修改成: data:

    2. 服务器获取参数值不再是 request.getParameter()…
      而是:
      StringBuffer stringBuffer = new StringBuffer(“”);
      BufferedReader bufferedReader = request.getReader();
      String str = null ;
      while((str=bufferedReader.readLine())!=null){
      stringBuffer.append(str);
      }
      str = stringBuffer.toString() ;

    3. 我们会发现 str的内容如下:
      {“uname”:“lina”,“pwd”:“ok”}

    • 服务器端给客户端响应JSON格式的字符串,然后客户端需要将字符串转化成js Object

你可能感兴趣的:(java,java,tomcat,servlet)