栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JavaWeb

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JavaWeb

JS

1 JS是客户端(浏览器端)运行的脚本语言,语法风格和java比较类似
2 JS是弱类型的语言 var str = 99 ;
3 JS的函数 function hello(var num){}
4 DOM技术:

4-1) 鼠标悬浮:onmouseover,event.srcElement,事件传递,parentElement,style.backgroundColor
     鼠标离开:onmouseout
4-2) 鼠标点击:hand/pointer,onclick , td.innerText , td.innerHTML="", td.firstChild.value=oldPrice
     失去焦点:onblur , input.parentElement.innerText = newPrice ;
     更新小计:input = event.srcElement , tr = input.parentElement.parentElement ; tr.cells , parseInt
     更新总计:document.getElementById("fruit_tbl") , fruitTbl.rows 
4-3) 删除一行:img , img.parentElement.parentElement.rowIndex , table.deleteRow(rowIndex)
课程体系

.
.

流程图

.
.
.

第一章:tomcat

1、BS和CS

.
.

2、tomcat介绍

.
.
.

第二章:servlet

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

1、使用servlet
  1. 新建项目 - 新建模块
  2. 在模块中添加web
  3. 创建artifact - 部署包
  4. lib 和 artifact
    先有artifact,后来才添加的mysql.jar。此时,这个jar包并没有添加到web部署包中
    那么在projectSettings中有一个Problems中会有提示的,我们点击fix选择add to…
    另外,我们也可以直接把lib文件夹直接新建在WEB-INF下。
    这样不好的地方是这个lib只能是当前这个moudle独享。如果有第二个moudle我们需要再次重复的新建lib。
  5. 在部署的时候,修改application Context。然后再回到server选项卡,检查URL的值。
    URL的值指的是tomcat启动完成后自动打开你指定的浏览器,然后默认访问的网址。
    启动后,报错404.404意味着找不到指定的资源。
    如果我们的网址是:http://localhost:8080/pro01/ , 那么表明我们访问的是index.html.
    我们可以通过标签进行设置欢迎页(在tomcat的web.xml中设置,或者在自己项目的web.xml中设置)
  6. 405问题。当前请求的方法不支持。比如,我们表单method=post , 那么Servlet必须对应doPost。否则报405错误。
  7. 空指针或者是NumberFormatException 。因为有价格和库存。如果价格取不到,结果你想对null进行Integer.parseInt()就会报错。错误的原因大部分是因为 name="price"此处写错了,结果在Servlet端还是使用request.getParameter(“price”)去获取。
  8. XML配置文件中的中以斜杠开头

.
.

2、action(活动)对应类的流程

.
.

3、设置编码

① tomcat8之前设置编码:

  • 1)get请求方式:
    如果是get请求发送的中文数据,转码稍微有点麻烦(tomcat8之前)
    String fname = request.getParameter(“fname”);
    ① 将字符串打散成字节数组
    byte[] bytes = fname.getBytes(“ISO-8859-1”);
    ② 将字节数组按照设定的编码重新组装成字符串
    fname = new String(bytes,“UTF-8”);
  • 2)post请求方式:
    request.setCharacterEncoding(“UTF-8”);

② tomcat8设置编码,只需要针对post方式(get方式不需要设置编码)

  • request.setCharacterEncoding(“UTF-8”);
  • 注意:需要注意的是,设置编码(post)这一句代码必须在所有的获取参数动作之前。

.
.

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

① 继承关系

  javax.servlet.Servlet接口
      javax.servlet.GenericServlet抽象类
          javax.servlet.http.HttpServlet抽象子类

.

② 相关方法

  • 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) - 不是抽象的
    源码分析:
String method = req.getMethod(); 获取请求的方式
        //各种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")) {
			...

        //在HttpServlet这个抽象类中,do方法都差不多:继承的类不重写这些方法默认就是405
        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);
            }
        }

③ 小结:

  • 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方法

.
.

5、Servlet的生命周期

生命周期:从出生到死亡的过程就是生命周期。
对应Servlet中的三个方法:init(),service(),destroy()

.

① 默认情况下

  • 第一次接收请求时,这个Servlet会进行实例化(调用构造方法)、初始化(调用init())、然后服务(调用service())
  • 从第二次请求开始,每一次都是服务
  • 当容器关闭时,其中的所有的servlet实例会被销毁,调用销毁方法

提问:默认情况下 初始化,然后再服务,这样的好处是什么?

  • 提高系统的启动速度 。

提问:这样的缺点是什么?

  • 第一次请求时,耗时较长。

因此得出结论: 如果需要提高系统的启动速度,当前默认情况就是这样。如果需要提高响应速度,我们应该设置Servlet的初始化时机。

.

② Servlet的初始化时机

  • 我们可以通过在标签内添加来设置servlet启动的先后顺序,数字越小,启动越靠前,最小值0

.

③ Servlet在容器中是:单例的、线程不安全的

  • 单例:所有的请求都是同一个实例去响应
  • 线程不安全:一个线程需要根据这个实例中的某个成员变量值去做逻辑判断。但是在中间某个时机,另一个线程改变了这个成员变量值,从而导致第一个线程的执行路径发生了变化
  • 我们已经知道了servlet是线程不安全的,给我们的启发是: 尽量的不要在servlet中定义成员变量。如果不得不定义成员变量,那么不去:
    ①不要去修改成员变量的值
    ②不要去根据成员变量的值做一些逻辑判断

.
.

6、Http协议

Http 称之为 超文本传输协议

① Http包含两个部分:请求和响应
请求:包含三个部分: 请求行 、请求消息头、请求主体

  • 1)请求行包含是三个信息: 1. 请求的方式 ; 2.请求的URL ; 3.请求的协议(一般都是HTTP1.1)
  • 2)请求消息头中包含了很多客户端需要告诉服务器的信息,比如:浏览器型号、版本、浏览器接收的内容的类型、浏览器给服务端发的内容的类型、内容的长度等等
  • 3)请求体,三种情况:
    get方式,没有请求体,但是有一个queryString
    post方式,有请求体,form data
    json格式,有请求体,request payload

响应:也包含三个部分:响应行 、响应头、响应体

  • 1)响应行包含三个信息:① 协议 ② 响应状态码(200) ③ 响应状态(ok)
  • 2)响应头:包含了服务器的信息;服务器发送给浏览器的信息(内容的媒体类型、编码、内容长度等)
  • 3)响应体:响应的实际内容(比如请求add.html页面时,响应的内容就是

② Http是无状态的

  • HTTP 无状态 :服务器无法判断这两次请求是同一个客户端发过来的,还是不同的客户端发过来的
  • 无状态带来的现实问题:第一次请求是添加商品到购物车,第二次请求是结账;如果这两次请求服务器无法区分是同一个用户的,那么就会导致混乱
  • 通过会话跟踪技术来解决无状态的问题。

.
.

7、会话

一次会话就是一次进程!!!!!!!!!!!!!!!!!!!!!
通过会话跟踪技术可以解决HTTP无状态的问题。

① 会话跟踪技术

  • 客户端第一次发请求给服务器,服务器获取session,获取不到,则创建新的,然后响应给客户端。
  • 下次客户端给服务器发请求时,会把sessionID带给服务器,那么服务器就能获取到了,那么服务器就判断这一次请求和上次某次请求是同一个客户端,从而能够区分开客户端。

.

② API:

获取会话

  • request.getSession() -> 获取当前的会话,没有则创建一个新的会话
  • request.getSession(true) -> 效果和不带参数相同
  • request.getSession(false) -> 获取当前会话,没有则返回null,不会创建新的

常用的会话API

  • session.getId() -> 获取sessionID
  • session.isNew() -> 判断当前session是否是新的
  • session.getMaxInactiveInterval() -> session的非激活间隔时长,默认1800秒
  • session.setMaxInactiveInterval()
  • session.invalidate() -> 强制性让会话立即失效
    …

.

③ session保存作用域
session保存作用域是和具体的某一个session对应的。

  • 常用的API:
    void session.setAttribute(k,v)----创建key-value
    Object session.getAttribute(k)----根据key值获得value值
    void removeAttribute(k)----根据key值删除对应的key-value

.
.

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

1、服务器内部转发 : request.getRequestDispatcher(“…”).forward(request,response);

  • 一次请求响应,服务端多次转发的过程,对于客户端而言,内部经过了多少次转发,客户端是不知道的。
  • 地址栏没有变化

.

2、客户端重定向: response.sendRedirect(“…”);

  • 两次或多次请求响应的过程。客户端知道请求URL有变化
  • 地址栏有变化

.

3、重定向与转发的区别

.
.

9、Thymeleaf - 视图模板技术

① 使用步骤

  • 1) 添加thymeleaf的jar包
  • 2) 新建一个Servlet子类ViewBaseServlet
  • 3)在web.xml文件中添加配置:注意(除了的值可变其他都是固定格式)
    - 配置前缀 view-prefix
    - 配置后缀 view-suffix
  • 4) 让我们的Servlet继承ViewBaseServlet

.

② thymeleaf会将逻辑视图名称 对应到 物理视图名称 上去

  • ViewBaseServlet 类中 processTemplate(“index”,req,resp); 方法中的 index 就是逻辑视图名称
  • 逻辑视图名称 : index
  • 物理视图名称 : view-prefix + 逻辑视图名称 + view-suffix
  • 所以真实的视图名称是:/index.html

.

③ thymeleaf的标签

  • th:if
  • th:unless
  • th:each
  • th:text
    …

.
.

10、@WebServlet属性表

.
.

11、保存作用域

原始情况下,保存作用域我们可以认为有四个:

  • page(页面级别,现在几乎不用)

  • ServletRequest(一次请求响应范围)

  • ServletSession(一次会话范围)

  • ServletContext(整个应用程序范围)

  • 隐藏域 : 功能类似于文本框 , 它的值会随着表单的发送也会发送给服务器,但是界面上用户看不到

.
.

12、路径问题

1)相对路径:图中红色
2)绝对路径:图中蓝色
../ 返回上一层

thymeleaf 中使用的 @{/} 默认已经写了项目的根目录 , 所以直接写基于根目录后的地址,注意斜杠不能少。

.
.

13、项目一、水果库存系统
  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中

    .

    ③ 如果我们想要在Servlet初始化时做一些准备工作,那么我们可以重写init方法

    • 我们可以通过如下步骤去获取初始化设置的数据
      获取config对象:ServletConfig config = getServletConfig();
      通过config对象获取初始化参数值: config.getInitParameter(key);

    .
    .

    15、通过ServletContext获取配置上下文信息和(整个应用程序相关,任何Servlet都可以用)

    ① 在xml文件中配置ServletContext

    • 使用:标签

    .

    ② 获取ServletContext,有很多方法

    • 在初始化方法中: ServletContxt servletContext = getServletContext();
    • 在服务方法中也可以通过request对象获取,也可以通过session获取:
      request.getServletContext();
      session.getServletContext()

    .

    • 获取初始化值:
      servletContext.getInitParameter();

    .
    .

    16、什么是业务层

    ① MVC : Model(模型)、View(视图)、Controller(控制器)

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

    .

    ② 区分业务对象和数据访问对象:

    • DAO:DAO中的方法都是单精度方法或者称之为细粒度方法。什么叫单精度?一个方法只考虑一个操作,比如添加,那就是insert操作、查询那就是select操作…
    • BO:BO中的方法属于业务方法,也实际的业务是比较复杂的,因此业务方法的粒度是比较粗的

    例如:

    注册这个功能属于业务功能,也就是说注册这个方法属于业务方法。
    那么这个业务方法中包含了多个DAO方法。也就是说注册这个业务功能需要通过多个DAO方法的组合调用,从而完成注册功能的开发。
    
    流程:
    	1. 检查用户名是否已经被注册 - DAO中的select操作
    	2. 向用户表新增一条新用户记录 - DAO中的insert操作
    	3. 向用户积分表新增一条记录(新用户默认初始化积分100分) - DAO中的insert操作
    	4. 向系统消息表新增一条记录(某某某新用户注册了,需要根据通讯录信息向他的联系人推送消息) - DAO中的insert操作
    	5. 向系统日志表新增一条记录(某用户在某IP在某年某月某日某时某分某秒某毫秒注册) - DAO中的insert操作
    	6. ....
    

    .
    .

    17 、XML的Node节点
    • Node 节点 (父接口)
    • |—Element 元素节点(Node 子接口)
      例如:
    • |—Text 文本节点(Node 子接口)
      例如:文本啊撒发顺丰

    .
    .

    18、IOC

    ① 耦合/依赖

    依赖指的是某某某离不开某某某

    • 在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。
    • 我们系统架构或者是设计的一个原则是: 高内聚低耦合。
    • 层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)

    .

    ② 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 ;
        然后,在配置文件中配置:
       
            
       
    

    .
    .

    19、过滤器Filter

    Filter也属于Servlet规范,要实现Filter接口

    ① Filter开发步骤:

    • 新建类实现Filter接口
    • 然后实现其中的三个方法:init(初始化方法)、doFilter(服务方法)、destroy(销毁方法)
    • 配置Filter,可以用注解@WebFilter,也可以使用xml文件
    • 放行:在 doFilter 服务方法中使用 filterChain 形参的 doFilter() 方法。
    • Filter在配置时,和servlet一样,也可以配置通配符,例如 @WebFilter(“*.do”)表示拦截所有以.do结尾的请求

    .

    ② 过滤器链
    创建多个过滤器Filter
    1)执行的顺序依次是: A B C demo03 C2 B2 A2
    2)如果采取的是注解的方式进行配置,那么过滤器链的拦截顺序是按照全类名的先后顺序排序的
    3)如果采取的是xml的方式进行配置,那么按照配置的先后顺序进行排序

    .
    .

    20、事务管理


    ThreadLocal(本地线程)
    由于事务管理放到了过滤器上,但每一个DAO使用的Connection(连接)又得是相同的,我们可以使用TreadLocal类

    一个TreadLocal类实例只能保存一个Object

    • 两个主要方法 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();
         }
    

    .
    .

    21、监听器
    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域中的序列化和反序列化
    

    .
    .

    22、日期和字符串之间的格式化

    ① 在java代码中

    • String -> java.util.Date
    String dateStr1 = "2021-12-30 12:59:59";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try {
            Date date1 = sdf.parse(dateStr1);
    } catch (ParseException e) {
            e.printStackTrace();
    }
    
    • Date -> String
    Date date2 = new Date();
    String dateStr2 = sdf.format(date2);
    

    ② thymeleaf中使用#dates这个公共的内置对象

    • ${#dates.format(topic.topicDate ,'yyyy-MM-dd HH:mm:ss')}

    .
    .
    .

    以上Servlet内容总结

    一、系统启动时,我们访问的页面是: http://localhost:8080/pro23/page.do?operate=page&page=login
    为什么不是: http://localhost:8080/pro23/login.html ?

    • 答: 如果是后者,那么属于直接访问静态页面。那么页面上的thymeleaf表达式(标签)浏览器是不能识别的我们访问前者的目的其实就是要执行 ViewBaseServlet中的processTemplete()

    .
    .

    二、http://localhost:8080/pro23/page.do?operate=page&page=login 访问这个URL,执行的过程是什么样的?

    答:

    http://   localhost   :8080   /pro23          /page.do                        ?operate=page&page=login
    协议       ServerIP   port    context root    request.getServletPath()         query string
    
    1. DispatcherServlet -> urlPattern : “*.do” 拦截/page.do
    2. request.getServletPath() -> /page.do
    3. 解析处理字符串,将/page.do -> page
    4. 拿到page这个字符串,然后去IOC容器(BeanFactory)中寻找id=page的那个bean对象 -> PageController.java
    5. 获取operate的值 -> page 因此得知,应该执行 PageController中的page()方法
    6. PageController中的page方法定义如下:
      public String page(String page){
      return page ;
      }
    7. 在queryString: ?operate=page&page=login 中 获取请求参数,参数名是page,参数值是login
      因此page方法的参数page值会被赋上"login"
      然后return "login" --> super.processTemplete("login",request,response) , return 给 谁??
    8. 因为PageController的page方法是DispatcherServlet通过反射调用的
      method.invoke(…) ;
      因此,字符串"login"返回给DispatcherServlet
    9. DispatcherServlet接收到返回值,然后处理视图
      目前处理视图的方式有两种: 1.带前缀redirect: 2.不带前缀
      当前,返回"login",不带前缀
      那么执行 super.processTemplete(“login”,request,response);
    10. 此时ViewBaseServlet中的processTemplete方法会执行,效果是:
      在"login"这个字符串前面拼接 “/” (其实就是配置文件中view-prefixe配置的值)
      在"login"这个字符串后面拼接 “.html” (其实就是配置文件中view-suffix配置的值)
      最后进行服务器转发

    .
    .

    三、目前我们进行javaweb项目开发的“套路”:

    1. 拷贝 myssm包
    2. 新建配置文件applicationContext.xml或者可以不叫这个名字,在web.xml中指定文件名
    3. 在web.xml文件中配置:
    1) 配置前缀和后缀,这样thymeleaf引擎就可以根据我们返回的字符串进行拼接,再跳转
            
                        view-prefix
                        /
            
            
            
                		view-suffix
                		.html
            
    2) 配置监听器要读取的参数,目的是加载IOC容器的配置文件(也就是applicationContext.xml)
            
                		contextConfigLocation
                		applicationContext.xml
            
    

    .
    .

    开发具体的业务模块:
    1) 一个具体的业务模块纵向上由几个部分组成:

     - html页面
     - POJO类
     - DAO接口和实现类
     - Service接口和实现类
     - Controller 控制器组件
    

    2) 如果html页面有thymeleaf表达式,一定不能够直接访问,必须要经过PageController --> 也就是 super.processTemplete("login",request,response) 方法

    3) 在applicationContext.xml中配置 DAO、Service、Controller,以及三者之间的依赖关系

    4) DAO实现类中 , 继承BaseDAO,然后实现具体的接口, 需要注意,BaseDAO后面的泛型不能写错。

      例如:
      public class UserDAOImpl extends BaseDAO implements UserDAO{}
    

    5) Service是业务控制类,这一层我们只需要记住一点:

      - 业务逻辑我们都封装在service这一层,不要分散在Controller层。也不要出现在DAO层(我们需要保证DAO方法的单精度特性)
      - 当某一个业务功能需要使用其他模块的业务功能时,尽量的调用别人的service,而不是深入到其他模块的DAO细节
    

    6) Controller类的编写规则

    ① 在applicationContext.xml中配置Controller
          
            
          
      
      ③ 在表单中,组件的name属性和Controller中方法的参数名一致
          
          public String login(String loginId , String pwd , HttpSession session){}
          
      ④ 另外,需要注意的是: Controller中的方法中的参数不一定都是通过请求参数获取的
          if("request".equals...) else if("response".equals....) else if("session".equals....){
            直接赋值
          }else{
            此处才是从request的请求参数中获取
            request.getParameter("loginId") .....
          }
    

    .
    .

    7)DispatcherServlet中步骤大致分为:

    0. 从application作用域获取IOC容器
    1. 解析servletPath , 在IOC容器中寻找对应的Controller组件
    2. 准备operate指定的方法所要求的参数
    3. 调用operate指定的方法
    4. 接收到执行operate指定的方法的返回值,对返回值进行处理 - 视图处理
    

    8)为什么DispatcherServlet能够从application作用域获取到IOC容器?

    ContextLoaderListener这个监听器在容器启动时会执行初始化任务,而它的操作就是:
         1. 解析IOC的配置文件,创建一个一个的组件,并完成组件之间依赖关系的注入
         2. 将IOC容器保存到servletContext作用域
    

    .
    .
    .

    二、Cookie

    简介:
    服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。
    Cookie实际上就是服务器保存在浏览器上的一段信息。浏览器有了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: 十天免登录

    .
    .
    .

    三、Kaptcha (验证码)

    Kaptcha是一个Servlet

    1. kaptcha如何使用:
      • 添加kaptcha的jar包
      • 在web.xml文件中注册KaptchaServlet,并设置验证码图片的相关属性
      • 在html页面上编写一个img标签,然后图片设置src等于KaptchaServlet对应的url-pattern
    2. kaptcha验证码图片的各个属性在常量类:Constants类中
    3. KaptchaServlet在生成验证码图片时,会同时将验证码信息保存到session中
      因此,我们在注册请求时,首先将用户文本框中输入的验证码值和session中保存的值进行比较,相等,则进行注册
      Kaptcha保存在session中的 key = “KAPTCHA_SESSION_KEY”

    .
    .
    .

    四、JS - Exp(正则表达式)

    1、定义正则表达式对象

    • 正则表达式定义有两个方式:
    1. 对象形式:var reg = new RegExp("abc")
    2. 直接量形式:var reg = /abc/;

    .

    2、匹配模式

    - g 全局匹配
    - i 忽略大小写匹配
    - m 多行匹配
    - gim这三个可以组合使用,不区分先后顺序
       例如: var reg = /abc/gim , var reg = new RegExp("abc","gim");
    

    3、校验

    • 元字符(表示匹配的字符):百度搜正则表达式元字符表

    • []表示集合

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

    4、出现的次数

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

    .
    .
    .

    五、Ajax(异步)

    1、简介

    • AJAX 是 Asynchronous JavaScript And XML 的简称。直译为,异步的JS和XML。
    • AJAX的实际意义是,不发生页面跳转、异步载入内容并改写页面内容的技术。
    • AJAX也可以简单的理解为通过JS向服务器发送请求。
    • 局部刷新:降低服务器负担、减轻浏览器压力、减轻网络带宽压力。

    .
    .

    2、异步处理

    • 同步处理
      AJAX出现之前,我们访问互联网时一般都是同步请求,也就是当我们通过一个页面向服务器发送一个请求时,在服务器响应结束之前,我们的整个页面是不能操作的,也就是直观上来看他是卡主不动的。
      这就带来了非常糟糕的用户体验。首先,同步请求时,用户只能等待服务器的响应,而 不能做任何操作。其次,如果请求时间过长可能会给用户一个卡死的感觉。最后,同步请求的最大缺点就是即使整个页面中只有一小部分内容发生改变我们也要刷新整个页面。
    • 异步处理
      而异步处理指的是我们在浏览网页的同时,通过AJAX向服务器发送请求,发送请求的过程中我们浏览网页的行为并不会收到任何影响,甚至主观上感知不到在向服务器发送请求。当服务器正常响应请求后,响应信息会直接发送到AJAX中,AJAX可以根据服务器响应的内容做一些操作。
      使用AJAX的异步请求基本上完美的解决了同步请求带来的问题。首先,发送请求时不会影响到用户的正常访问。其次,即使请求时间过长,用户不会有任何感知。最后,AJAX可以根据服务器的响应信息局部的修改页面,而不需要整个页面刷新。

    .
    .
    3、异步请求对象

    • XMLHttpRequest对象是AJAX中非常重要的对象,所有的AJAX操作都是基于该对象的。
    • XMLHttpRequest对象用来封装请求报文,我们向服务器发送的请求信息全部都需要封装到该对象中。
    • 这里需要稍微注意一下,XMLHttpRequest对象并没有成为标准,但是现在的主流浏览器都支持该对象,而一些如IE6的老版本浏览器中的创建方式有一些区别,但是问题不大。

    XMLHttpRequest对象的获取:

    .
    .

    4、XMLHttpRequest对象的方法

    • open(method,url,async):用于设置请求的基本信息,接收三个参数。
      ①method请求的方法:get或post;接收一个字符串
      ②url:请求的地址,接收一个字符串
      ③Assync:发送的请求是否为异步请求,接收一个布尔值。
      true 是异步请求
      false 不是异步请求(同步请求)
    • send(string):用于将请求发送给服务器,可以接收一个参数
      ①string:该参数只在发送post请求时需要。
      string参数用于设置请求体。
    • setRequestHeader(header,value):用于设置请求头。
      ①header参数:字符串类型,要设置的请求头的名字。
      ②value参数:字符串类型,要设置的请求头的值。

    .
    .

    5、XMLHttpRequest对象的属性

    • readyState:描述XMLHttpRequest的状态
      0 :请求尚未初始化,open()尚未被调用
      1 :服务器连接已建立,send()尚未被调用
      2 :请求已接收,服务器尚未响应
      3 :请求已处理,正在接收服务器发送的响应
      4 :请求已处理完毕,且响应已就绪。

    • status:请求的响应码
      200 响应成功
      404 页面为找到
      500 服务器内部错误

    • onreadystatechange:该属性需要指向一个函数
      该函数会在readyState属性发生改变时被调用

    • responseText:获得字符串形式的响应数据。

    • responseXML(用的比较少):获得 XML 形式的响应数据。

    3、开发步骤:

    1. 创建XMLHttpRequest
    2. 调用open进行设置:xmlHttpRequest.open("GET" , URL , true)
    3. 绑定状态改变时执行的回调函数 -> xmlHttpRequest.onreadystatechange = function(){}
    4. 发送请求 - send()
    5. 编写回调函数,在回调函数中,
      我们只对XMLHttpRequest的readystate为4的时候感兴趣
      我们只对XMLHttpRequest的status为200的时候感兴趣
    • 示例:GET

    • 示例:POST

    .
    .
    .

    六、Vue(Vue.js)
    • {{}} - 相当于innerText

    • v-bind:attr 绑定属性值。例如,v-bind:value - 绑定value值
      简写: :value

    • v-model 双向绑定
      v-model:value , 简写 v-model

    • v-if , v-else , v-show
      v-if和v-else之间不能有其他的节点
      v-show是通过样式表display来控制节点是否显示

    • v-for 迭代
      v-for={fruit in fruitList}

    • v-on 绑定事件
      简写:

    Vue生命周期

    .
    .
    .

    七、Axios (封装Ajax的js框架)

    Axios是Ajax的一个框架,简化Ajax操作

    Axios执行Ajax操作的步骤:

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

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

      • 基本格式: 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 可以查看错误的信息
    

    .
    .
    .

    八、JSON格式的数据

    1、什么是JSON
    JSON和XML一样是一种数据格式

    • XML格式表示两个学员信息的代码如下:
    
        
            jim
            18
        
        
            tom
            19
        
      
    
    • JSON格式表示两个学员信息的代码如下:
     [{sid:"s001",age:18},{sid:"s002",age:19}]
    
    • 由此可看出JSON表达数据更简洁,更能够节约网络带宽

    .
    .

    2、客户端发送JSON格式的数据给服务器端

    • 客户端中传参数给服务器的 params 需要修改成: data

    • 服务器获取参数值不再是 request.getParameter() --> 而是:request.getReader() 获得一个字符输入流

    • 获取数据代码如下:

    StringBuffer stringBuffer = new StringBuffer("");
       BufferedReader bufferedReader = request.getReader();
       String str = null ;
       while((str=bufferedReader.readLine())!=null){
           stringBuffer.append(str);
       }
       str = stringBuffer.toString() ;
    
    我们会发现 str的内容如下格式: {"uname":"lina","pwd":"ok"}
    
    • 添加Gson jar包把json格式的字符串转换为java中的对象
    • Gson两个重要API:
    1.fromJson(string,T)		将字符串转化成java object
    2.toJson(java Object)		将java object转化成json字符串,这样才能响应给客户端 !!!
    

    .
    .

    3、服务器端再把要响应给客户端的 Object 数据 转换为 JSON 格式的字符串发送过去

    客户端则根据需要将JSON字符串转化成 js的Object 进行操作

    • js的Object 与 JSON字符串 的转换可以使用js内置的JSON操作~
      JSON两个方法:
      JSON.stringify(obj) 返回 js的Object
      JSON.parse(str) 返回 字符串

    js的Object 转换 JSON字符串:JSON.stringify(obj)
    JSON字符串 转换 js Object:JSON.parse(str)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/999968.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号