大数据------JavaWeb------FilterListenerAJAXAxiosJSON

news2024/11/20 16:34:59

Filter

Filter简介

在这里插入图片描述

  • 定义:Filter表示过滤器,是JavaWeb三大组件(ServletFilterListener)之一。

  • 作用:它可把对资源(ServletJSPHtml)的请求拦截下来从而实现一些特殊功能

    • 过滤器一般完成一些通用操作,比如:权限控制、统一编码处理、敏感字符处理等待
  • 举例:将来我们可能在不同的资源中做一样的操作代码,此时我们就可将其一样的操作提取出来放到过滤器中。

    • 以会话跟踪技术中的登录案例为例,如果没有Filter过滤器,此时不论我们是否登录,我们都能访问查询所有的页面,如图所示

      • 正常登录:登录成功后会自动跳转到查询所有的页面

        在这里插入图片描述

      • 此时我们不进行登录,直接输入对应的url即可跳转到查询所有页面

        在这里插入图片描述

Filter快速入门

在这里插入图片描述

  • 注意

    • 由于Filter是JavaWeb的三大资源之一,其代码放在filter包下,而filter包放在web包中

    • 配置Filter拦截资源的路径时,注解的参数为要拦截的资源的路径。参数为/*时代表拦截任何资源

    • 快速入门以新创建的Web项目FilterListenerAjax为例

      • 该项目结构如图所示

        在这里插入图片描述

      • Tomcat运行后,输入对应的url即可访问hello.jsp页面,如图所示

        在这里插入图片描述

  • FilterListenerAjaxhello.jsp页面加上过滤器的步骤及代码如下

    • Step1: 定义一个实现Filter接口的类,并重写其所有方法

      • 注意:Filterjavax.servlet包下的接口
    • Step2: 在类上定义@WebFilter注解并配置想要拦截的资源的路径

      • 注意:当注解参数配置为/*时代表拦截任何资源
    • Step3:doFilter方法中输出一句话并放行

      • 注意:doFilter方法中利用chain.doFilter(request, response);方法放行
    • 满足以上步骤的不放行代码

      package at.guigu.web.filter;
      
      import javax.servlet.*;
      import javax.servlet.annotation.*;
      import java.io.IOException;
      
      @WebFilter("/*")
      public class FilterDemo implements Filter {
          @Override
          public void init(FilterConfig config) throws ServletException {
          }
      
          @Override
          public void destroy() {
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
              System.out.println("FilterDemo...被执行");
          }
      }
      
      • Tomcat运行该Web项目,此时访问hello.jsp时,并不会跳出对应页面,如图所示

        在这里插入图片描述

    • 满足以上步骤的放行代码

      package at.guigu.web.filter;
      
      import javax.servlet.*;
      import javax.servlet.annotation.*;
      import java.io.IOException;
      
      @WebFilter("/*")
      public class FilterDemo implements Filter {
          @Override
          public void init(FilterConfig config) throws ServletException {
          }
      
          @Override
          public void destroy() {
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
              System.out.println("FilterDemo...被执行");
              //放行
              chain.doFilter(request, response);
              System.out.println("资源被放行了...");
          }
      }
      

      在这里插入图片描述

Filter执行流程

在这里插入图片描述

  • 注意

    • 放行前request对象中就已存在数据,一般需要在放行前对request数据进行处理,这样在放行时就可以使用处理好的requset对象中的数据
      • 原因: 浏览器请求资源时会向服务端发送request请求数据,所以在浏览器被限制访问该资源之前就已经向服务端发送了request请求数据。也就是说不论是否限制访问该资源,服务端都会获取到request请求数据
    • 放行后response对象中才会有数据,所以需要在放行后对response对象中的数据进行处理
      • 原因: 浏览器请求资源时若服务端允许其访问则会发回response响应数据,所以放行就相当于允许浏览器访问请求的资源,所以在放行后才会有response数据
    • 放行后访问对应资源,资源访问完成后,还会回到Filter中,回到Filter中后会执行放行后的逻辑代码,即执行流程为:
      • 执行前放行逻辑→放行→访问资源→执行放行后逻辑
  • 代码示例如下:

    • hello.jsp代码

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h2>Hello World!</h2>
              <%
                  System.out.println("2 放行:hello.jsp资源文件被执行");
              %>
          </body>
      </html>
      
    • FilterDemo代码

      package at.guigu.web.filter;
      
      import javax.servlet.*;
      import javax.servlet.annotation.*;
      import java.io.IOException;
      
      @WebFilter("/*")
      public class FilterDemo implements Filter {
          @Override
          public void init(FilterConfig config) throws ServletException {
          }
      
          @Override
          public void destroy() {
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
              System.out.println("1 放行前需要对request对象的数据进行处理");
              //放行
              chain.doFilter(request, response);
              System.out.println("3 放行后需要对response数据进行处理");
          }
      }
      
    • Tomcat运行该Web项目后的截图如下

      在这里插入图片描述

Filter拦截路径配置

  • Filter可根据需求,配置不同的拦截资源路径

    • 即注解@WebFilter("拦截资源路径")的参数
  • 拦截路径种类有四种

    拦截种类示例解释
    拦截具体的资源/index.jsp只有访问index.jsp时才会拦截
    目录拦截/user/*访问/user目录下的所有资源时才会被拦截
    后缀名拦截*.jsp访问后缀名为jsp的资源时才会被拦截
    拦截所有/*访问任何资源都会被拦截

Filter过滤器链

在这里插入图片描述

  • 定义:一个Web应用中可以配置多个过滤器,这多个过滤器称为过滤器链

  • 过滤器链执行过程如上图所示

  • 执行过滤器链中Filter过滤器的顺序

    • 通过注解配置的Filter过滤器的执行优先级顺序是按照过 滤器类名的自然排序 依次执行
  • 代码示例

    • hello.jsp文件代码

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <h2>Hello World!</h2>
              <%
                  System.out.println("5 hello.jsp资源文件被执行");
              %>
          </body>
      </html>
      
    • 过滤器FilterDemo类代码

      package at.guigu.web.filter;
      
      import javax.servlet.*;
      import javax.servlet.annotation.*;
      import java.io.IOException;
      
      @WebFilter("/*")
      public class FilterDemo implements Filter {
          @Override
          public void init(FilterConfig config) throws ServletException {
          }
      
          @Override
          public void destroy() {
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
              System.out.println("1 过滤器Filter1 放行前需要对request对象的数据进行处理");
              //放行
              chain.doFilter(request, response);
              System.out.println("3 过滤器Filter1 放行后需要对response数据进行处理");
          }
      }
      
    • 过滤器FilterDemo2代码

      package at.guigu.web.filter;
      
      import javax.servlet.*;
      import javax.servlet.annotation.WebFilter;
      import java.io.IOException;
      
      @WebFilter("/*")
      public class FilterDemo2 implements Filter {
          @Override
          public void init(FilterConfig config) throws ServletException {
          }
      
          @Override
          public void destroy() {
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
              System.out.println("1 过滤器Filter2 放行前需要对request对象的数据进行处理");
              //放行
              chain.doFilter(request, response);
      
              System.out.println("3 过滤器Filter2 放行后需要对response数据进行处理");
          }
      }
      
    • Tomcat运行该Web项目后会先按照优先级把FilterDemo作为第一个过滤器,FilterDemo2作为第二个过滤器,运行截图如下所示

      在这里插入图片描述

案例——登陆验证

  • 需求:访问服务器资源时,需要先进行登陆验证,若没有登录则自动跳转到登录界面

  • 解释:本案例以会话跟踪技术中的登陆案例项目为基础,解决Filter简介的举例所说明的问题

    • 注意:本项目名为FilterListenerAjaxDemo,可自行在Gitee下载
  • 工作流程如下:

    • 由于访问的所有Web资源均需要登陆后才能访问,所以拦截路径配置的拦截种类为拦截所有

      • 注意:做这一步时我们要判断访问的资源是否为登录之后才能看的资源
        • 若不是:则放行,即对所有的登陆和注册相关的资源(比如:cssimgslogin.jspLoginServlet等)进行放行。
        • 若是:则进行拦截并跳转到登陆页面,之后即可进行登录或注册。
    • 由于我们将登录后的用户对应的User对象存储到了Session中,所以我们判断用户是否登录只需要看Session对象中是否有User对象

    在这里插入图片描述

  • Web层

    • web包下创建filter包,并创建一个实现Filter接口的类LoginFilter,该类代码如下

      • Step1:将 ServletRequest对象强转成 HttpServletRequest 对象,因为ServletRequest 类型的 requset 对象没有获取 session 对象的方法
      • Step2:在数组中存储登陆之前可访问的所有资源并对其放行
      • Step3:从 session 对象中获取User对象并判断用户是否登录
        • 若登录:则放行
        • 若未登录:则跳转到登陆界面
      package at.guigu.web.filter;
      
      import javax.servlet.*;
      import javax.servlet.annotation.*;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpSession;
      import java.io.IOException;
      
      @WebFilter("/*")
      public class LoginFilter implements Filter {
          @Override
          public void init(FilterConfig config) throws ServletException {
          }
      
          @Override
          public void destroy() {
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
              //1 将ServletRequest强转为HttpServletRequest对象
              HttpServletRequest req = (HttpServletRequest) request;
      
              //2 在数组中存储登陆之前可访问的所有资源并对其放行
              //2.1 将登陆之前就可访问到的资源存到数组中
              String[] urls = {"/imgs/", "/css/", "/login.jsp", "/loginServlet", "/register.jsp", "/registerServlet" ,"/checkCodeServlet"};
              //2.2 获取当前访问的资源路径
              String url = req.getRequestURL().toString();
              //2.3 循环判断是否为需要放行的资源,若是则放行并退出该方法,不会再继续执行循环后面的代码
              for (String u : urls) {
                  if (url.contains(u)) {
                      chain.doFilter(request, response);
                      return;
                  }
              }
              //3 获取Session对象并获取其中的User对象
              //3.1 获取Session对象
              HttpSession session = req.getSession();
              //3.2 获取Session中的User对象
              Object user = session.getAttribute("user");
              if (user != null) {//若用户已登录则放行
                  //放行前需要对request对象的数据进行处理
      
                  //放行
                  chain.doFilter(request, response);
                  //放行后需要对response数据进行处理
                  
              } else {//若用户未登录
                  req.setAttribute("login_msg", "您尚未登录,请先进行登录!");
                  //注意:forward的第一个参数用req或request都一样
                  req.getRequestDispatcher("/login.jsp").forward(request, response);
              }
          }
      }
      

      Tomcat运行该Web项目后,若不进行登录则会跳转到登录页面并给出提示,如图所示

      在这里插入图片描述

    • 为什么在for循环中就使用return跳出doFilter方法

      1. 浏览器申请的每一个资源都会经过过滤器,以登录页面为例,登陆了页面有多个资源(比如:imgscsslogin.jsp等),它的每个资源都会经过过滤器,经过滤器来判断是否放行
      2. 可以避免不必要的会话检查和重定向逻辑

Listener

  • 定义: Listener即监听器,是JavaWeb三大组件(ServletFilterListener)之一。

  • 作用: 监听在applicationsessionrequest三个对象中创建、销毁或往其中添加修改删除属性时 自动 执行代码的功能组件

    • applicationServletContext 类型的对象。ServletContext 代表整个web应用,在服务器启动的时候,tomcat会自动创建该对象。在服务器关闭时会自动销毁该对象。
  • JavaWeb提供了8个监听器

    监听器分类监听器名称作用
    servletContext监听servletContextListener用于对ServletContext对象进行监听(创建、销毁)
    ServletContextAttributeListenerServletContext对象中属性的监听(增删改属性)
    session监听HttpSessionListenerSession对象的整体状态的监听(创建、销毁)
    HttpSessionAttributeListenerSession对象中的属性监听(增删改属性)
    HttpSessionBindingListener监听对象于Session的绑定和解除
    HttpsessionActivationListenerSession数据的钝化和活化的监听
    Request监听servletRequestListenerRequest对象进行监听(创建、销毁)
    servletRequestAttributeListenerRequest对象中属性的监听(增删改属性)
    • 在不同的监听器中只有 ServletContextListener 这个监听器后期我们会接触到,ServletContextListener 是用来监听 ServletContext 对象的创建和销毁。
  • ServletContextListener 接口中有以下两个方法

    方法解释
    void contextInitialized(ServletContextEvent sce)ServletContext 对象被创建了会自动执行的方法
    void contextDestroyed(ServletContextEvent sce)ServletContext 对象被销毁时会自动执行的方法
  • ServletContextListener 接口使用步骤

    • Step1:在web包下创建listener包,定义一个实现ServletContextListener 接口的实现类

    • Step2:在实现类上添加@WebListener注解

    • 代码如下

      package at.guigu.web.listener;
      
      import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.servlet.annotation.*;
      
      @WebListener
      public class ContextLoaderListener implements ServletContextListener {
      
          public ContextLoaderListener() {
          }
      
          @Override
          public void contextInitialized(ServletContextEvent sce) {
              /* 加载资源 */
              System.out.println("ContextLoaderListener...");
          }
      
          @Override
          public void contextDestroyed(ServletContextEvent sce) {
              /* 释放资源 */
          }
      
      }
      
      • 由于servletContextListener属于ServletContext 监听器,该监听器在服务器启动的时候,tomcat会自动创建该对象并执行,Tomcat运行该Web项目后截图如下所示

        在这里插入图片描述

AJAX

  • 定义:AJAX(Asynchronous JavaScript And XML):异步的JavaScript和XML

  • 作用

    • 与服务器进行数据交换: 通过AJAX可以给服务器发送请求,服务器将数据直接响应回给浏览器。

      • 在学AJAX之前三层架构的实现过程为: 浏览器向服务器端请求数据时会先请求表现层的控制器(即Servlet),然后控制器会调用业务逻辑层的代码(这些代码组装了数据访问层的CRUD等基本功能)来获取数据库中的数据,并将数据返回给表现层中的控制器(即Swervlet),然后再由控制器(即Servlet)对数据进行封装,放到request域中传给视图(即JSP),最终由视图(即JSP)将响应数据返回给浏览器,使其展现在页面上

        • 原因:HTML无法获取服务端的响应数据,所以必须与JSP联合使用

        在这里插入图片描述

      • AJAX之后 ,我们可以直接使用AJAX来和服务器进行通信,此时就可以使用HTML+AJAX替换 JSP页面此时三层结构的实现过程为: 浏览器通过AJAX向服务器端请求数据时会先请求表现层的控制器(即Servlet),然后控制器会调用业务逻辑层的代码(这些代码组装了数据访问层的CRUD等基本功能)来获取数据库中的数据,并将数据返回给表现层中的控制器(即Servlet),然后再由控制器(即Servlet)将数据直接通过AJAX响应给浏览器页面,页面可直接使用HTML来进行数据展示

        在这里插入图片描述

    • 异步交互: 可以在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术,如:搜索联想、用户名是否可用校验,等等…

      • 示例1:当我们在百度输入一些关键字(例如 奥运)后就会在下面联想出相关的内容,而联想出来的这部分数据肯定是存储在百度的服务器上,而我们并没有看出页面重新刷新,这就是更新局部页面的效果。

        在这里插入图片描述

      • 示例2:当我们注册用户时,在用户名输入框输入完自己想要的用户名后只要用户名输入框一失去焦点,就会立马提示该用户名是否被占用;在这整个过程中也没有页面的刷新,只是在局部展示出了提示信息,这也是更新局部页面的效果。

        在这里插入图片描述

  • 同步异步的区别

    • 同步:浏览器页面在发送请求给服务器,在服务器处理请求的过程中,浏览器页面不能做其他的操作。只能等到服务器响应结束后浏览器页面才能继续做其他的操作。

      在这里插入图片描述

    • 异步:浏览器页面发送请求给服务器,在服务器处理请求的过程中,浏览器页面还可以做其他的操作。

      在这里插入图片描述

  • 使用AJAX的优点

    • 不刷新页面即可自动更新网页
    • 在页面加载后从服务器请求数据
    • 在页面加载后从服务器接收数据
    • 在后台向服务器发送数据

AJAX快速入门

  • 服务端步骤

    • Step1: 创建新的Web项目(该项目名为Ajax),引入坐标(在pom.xml文件中引入坐标依赖),并配置Tomcat插件(可详见Tomcat部分)

      • 需要的坐标依赖有mybatis、mysql驱动、servlet、jsp、jstl
      • 需要的插件有Tomcat插件
      • 完整pom.xml文件如下
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.example</groupId>
        <artifactId>Ajax</artifactId>
        <packaging>war</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>Ajax Maven Webapp</name>
        <url>http://maven.apache.org</url>
        <dependencies>
          <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
          </dependency>
      
          <!--MyBatis依赖-->
          <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.16</version>
          </dependency>
      
          <!--mysql驱动-->
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
          </dependency>
      
          <!--Servlet依赖-->
          <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
            <!--依赖范围关键字provided:在编译环境和测试环境有效,但在真正运行时就不会在使用该jar包-->
          </dependency>
      
          <!--JSP依赖-->
          <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
          </dependency>
      
          <!--jstl依赖-->
          <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
          </dependency>
          <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
          </dependency>
        </dependencies>
        <build>
          <finalName>Ajax</finalName>
          <plugins>
            <!-- Tomcat插件 -->
            <plugin>
              <groupId>org.apache.tomcat.maven</groupId>
              <artifactId>tomcat7-maven-plugin</artifactId>
              <version>2.2</version>
            </plugin>
          </plugins>
        </build>
      </project>
      
    • Step2: 创建三层架构包结构,并在web包下创建servlet包,如图所示

      在这里插入图片描述

    • Step3:at.guigu.web.servlet包下创建名为 AjaxServletServlet接口的实现类,并写入响应数据。代码如下:

      package at.guigu.web.servlet;
      
      import javax.servlet.*;
      import javax.servlet.http.*;
      import javax.servlet.annotation.*;
      import java.io.IOException;
      
      @WebServlet("/ajaxServlet")
      public class AjaxServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              //响应数据
              response.getWriter().write("hello ajax...");
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      
  • 客户端步骤

    • 在webapp目录下创建一个ajaxdemo1.html,在该html文件内书写 ajax 代码,步骤代码如下:

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <!--script标签体内写入AJAX代码,有三步,如下所示-->
              <script>
                  //1 创建核心对象
      
                  //2 发送请求
      
                  //3 获取响应
                  
              </script>
          </body>
      </html>
      
  • 注意:AJAX代码不需记忆,直接去W3school官网教程中复制粘贴即可

    • 创建核心对象:不同版本的浏览器创建核心对象的方式不同

      var xhttp;
                  if (window.XMLHttpRequest) {
                      // code for IE7+、Fierfox、Chrome、Opera、Safari
                      xhttp  = new XMLHttpRequest();
                  } else {
                      // code for IE6, IE5
                      xhttp = new ActiveXObject("Microsoft.XMLHTTP");
                  }
      
    • 发送请求

      核心对象的方法解释
      open(method, url, async)规定请求的类型。method:请求的类型:GET 还是 POST;url:服务器(文件)位置;asynctrue(异步,默认值)或 false(同步)
      send()向服务器发送请求(用于 GET
      send(string)向服务器发送请求(用于 POST

      注意:当为异步时,要访问的资源的url要写全

      • 发送GET请求简单代码示例

        xhttp.open("GET", "http://localhost:8080/Ajax/ajaxServlet");
                    xhttp.send();
        
      • 发送POST请求简单代码示例

        xhttp.open("POST", "http://localhost:8080/Ajax/ajaxServlet", true);
        xhttp.send();
        
      • 发送复杂的请求请详见W3school官网教程

    • 获取响应

      服务器响应属性解释
      responseText获取字符串形式的响应数据
      responseXML获取 XML 数据形式的响应数据
      xhttp.onreadystatechange = function() {
                      if (this.readyState == 4 && this.status == 200) {
                          // 通过 this.responseText 可以获取到服务端响应的数据
                          /*document.getElementById("demo").innerHTML =
                              this.responseText;*/
                          alert(this.responseText);
                      }
                  };
      
  • 客户端完整代码如下

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <!--script标签体内写入AJAX代码,有三步,如下所示-->
            <script>
                //1 创建核心对象
                // 不同版本的浏览器创建核心对象的方式不同
                var xhttp;
                if (window.XMLHttpRequest) {
                    // code for IE7+、Fierfox、Chrome、Opera、Safari
                    xhttp  = new XMLHttpRequest();
                } else {
                    // code for IE6, IE5
                    xhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }
                
                //2 发送请求——默认为异步
                // 注意:当为异步时,要访问的资源的url要写全
                xhttp.open("GET", "http://localhost:8080/Ajax/ajaxServlet");
                xhttp.send();
                
                //3 获取响应
                xhttp.onreadystatechange = function() {
                    if (this.readyState == 4 && this.status == 200) {
                        // 通过 this.responseText 可以获取到服务端响应的数据
                        /*document.getElementById("demo").innerHTML =
                            this.responseText;*/
                        alert(this.responseText);
                    }
                };
            </script>
        </body>
    </html>
    
  • Tomcat运行该Web项目后截图如下所示

在这里插入图片描述

AJAX 案例

  • 需求:使用AJAX验证用户名是否存在

  • 解释:在进行用户注册时,当用户名输入框失去焦点时立即校验用户名是否在数据库已存在

  • 本案例Web项目名为AjaxDemo,可自行下载

  • 要完成该案例,前后端分离需要完成的工作流程如下图所示

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 环境准备工作步骤省略,可详见会话跟踪技术中的登陆案例项目

  • 服务端

    • Service层

      • UserService代码如下

        package at.guigu.service;
        
        import at.guigu.mapper.UserMapper;
        import at.guigu.pojo.User;
        import at.guigu.util.SqlSessionFactoryUtils;
        import org.apache.ibatis.session.SqlSession;
        import org.apache.ibatis.session.SqlSessionFactory;
        
        public class UserService {
            //1 获取SqlSessionFactory对象
            SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
        
            /**
             *登录方法
             * @param username
             * @param password
             * @return
             */
            public User login(String username, String password) {
                //2 获取SqlSession对象,执行SQL语句
                //2.1 获取SqlSession对象
                SqlSession sqlSession = sqlSessionFactory.openSession();
                //2.2 获取Mapper接口UserMapper的代理对象
                UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
                //2.3 执行sql语句
                User user = userMapper.select(username, password);
                //释放资源
                sqlSession.close();
                return user;
            }
        
            /**
             * 注册功能
             * @param user
             * @return
             */
            public boolean register(User user) {
                //2 获取SqlSession对象,执行SQL语句
                //2.1 获取SqlSession对象
                SqlSession sqlSession = sqlSessionFactory.openSession();
                //2.2 获取Mapper接口UserMapper的代理对象
                UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
                //3 判断用户名是否存在,若不存在则可添加用户
                User u = userMapper.selectByUsername(user.getUsername());
                if (u == null) {//用户名不存在,注册
                    //4 执行sql语句
                    userMapper.add(user);
                    //5 注意:增删改的SQL语句需要手动提交事务让其生效
                    sqlSession.commit();
                }
                //释放资源
                sqlSession.close();
                //当u!=null时代表用户名存在,会返回false;反之会返回true
                return u==null;
            }
        
            /**
             * 判断用户注册的用户名是否存在
             * @param username
             * @return
             */
            public boolean selectByUsername(String username) {
                //2 获取SqlSession对象,执行SQL语句
                //2.1 获取SqlSession对象
                SqlSession sqlSession = sqlSessionFactory.openSession();
                //2.2 获取Mapper接口UserMapper的代理对象
                UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
                //3 判断用户名是否存在
                User u = userMapper.selectByUsername(username);
                //释放资源
                sqlSession.close();
                //当u!=null时代表用户名存在,会返回false;反之会返回true
                return u==null;
            }
        }
        
    • Web

      • 创建Servlet的实现类 SelectUserServlet,代码如下:

        package at.guigu.web.servlet;
        
        import at.guigu.service.UserService;
        
        import javax.servlet.*;
        import javax.servlet.http.*;
        import javax.servlet.annotation.*;
        import java.io.IOException;
        
        @WebServlet("/selectUserServlet")
        public class SelectUserServlet extends HttpServlet {
            //1 创建一个私有的UserService对象
            private UserService userService = new UserService();
            @Override
            protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                //1 接收用户名
                String username = request.getParameter("username");
                //2 调用service查询User对象——判断用户名是否存在
                boolean flag = userService.selectByUsername(username);
                //3 响应标记
                response.getWriter().write("" + flag);
            }
        
            @Override
            protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                this.doGet(request, response);
            }
        }
        
  • 客户端

    • 创建注册页面register.html, 代码如下

      <!DOCTYPE html>
      <html>
          <head>
              <title>Title</title>
              <meta charset="utf-8">
          </head>
          <body>
              <form action="/AjaxDemo/selectUserServlet" method="get">
                  <h1>欢迎注册</h1>
                  用户名:<input name="username" type="text" id="username">
                  <span id="username_err" style="display:none;">用户名已被占用</span><br>
                  密码:<input name="password" type="password"><br>
                  <input value="注册" type="submit">
              </form>
      
              <script>
                  //为用户名输入框绑定一个失去焦点onblur事件
                  document.getElementById("username").onblur = function () {
                      //1 用户名为用户输入的字符串
                      var username = this.value;
                      //2 创建核心对象
                      var xhttp;
                      if (window.XMLHttpRequest) {
                          xhttp = new XMLHttpRequest();
                      } else {
                          // code for IE6, IE5
                          xhttp = new ActiveXObject("Microsoft.XMLHTTP");
                      }
      
                      //3 建立连接
                      xhttp.open("GET", "http://localhost:8080/AjaxDemo/selectUserServlet?username=" + username);
                      //4 发送请求
                      xhttp.send();
                      //5 获取响应
                      xhttp.onreadystatechange = function () {
                          if (this.readyState == 4 && this.status == 200) {
                              // 通过 this.responseText 可以获取到服务端响应的数据
                              // alert(this.responseText);
                              // 判断用户名存在
                              if (this.responseText == "true") {
                                  document.getElementById("username_err").style.display = 'none';
                              } else {
                                  //若显示则将display属性值设为空字符串即可
                                  document.getElementById("username_err").style.display = '';
                              }
                          }
                      };
                  }
              </script>
          </body>
      </html>
      
  • Tomcat运行该Web项目后运行截图如下

    在这里插入图片描述

Axios

  • 定义:它是对原生的AJAX进行封装的,可以简化书写
  • 官网:https://www.axios-http.cn
  • 注意:Axios的学习以AJAX案例为基础,Axios``的Web项目名为AxiosDemo`,已上传到Gitee可自行下载

Axios快速入门

  • 步骤

    • Step1: 在Web项目核心目录(即webapp)下创建js目录,引入Axios的源码文件axios-0.18.0.js,该文件代码如下

      /* axios v0.18.0 | (c) 2018 by Matt Zabriskie */
      !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e){var t=new s(e),n=i(s.prototype.request,t);return o.extend(n,s.prototype,t),o.extend(n,t),n}var o=n(2),i=n(3),s=n(5),u=n(6),a=r(u);a.Axios=s,a.create=function(e){return r(o.merge(u,e))},a.Cancel=n(23),a.CancelToken=n(24),a.isCancel=n(20),a.all=function(e){return Promise.all(e)},a.spread=n(25),e.exports=a,e.exports.default=a},function(e,t,n){"use strict";function r(e){return"[object Array]"===R.call(e)}function o(e){return"[object ArrayBuffer]"===R.call(e)}function i(e){return"undefined"!=typeof FormData&&e instanceof FormData}function s(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function u(e){return"string"==typeof e}function a(e){return"number"==typeof e}function c(e){return"undefined"==typeof e}function f(e){return null!==e&&"object"==typeof e}function p(e){return"[object Date]"===R.call(e)}function d(e){return"[object File]"===R.call(e)}function l(e){return"[object Blob]"===R.call(e)}function h(e){return"[object Function]"===R.call(e)}function m(e){return f(e)&&h(e.pipe)}function y(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function w(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function g(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)}function v(e,t){if(null!==e&&"undefined"!=typeof e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n<o;n++)t.call(null,e[n],n,e);else for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&t.call(null,e[i],i,e)}function x(){function e(e,n){"object"==typeof t[n]&&"object"==typeof e?t[n]=x(t[n],e):t[n]=e}for(var t={},n=0,r=arguments.length;n<r;n++)v(arguments[n],e);return t}function b(e,t,n){return v(t,function(t,r){n&&"function"==typeof t?e[r]=E(t,n):e[r]=t}),e}var E=n(3),C=n(4),R=Object.prototype.toString;e.exports={isArray:r,isArrayBuffer:o,isBuffer:C,isFormData:i,isArrayBufferView:s,isString:u,isNumber:a,isObject:f,isUndefined:c,isDate:p,isFile:d,isBlob:l,isFunction:h,isStream:m,isURLSearchParams:y,isStandardBrowserEnv:g,forEach:v,merge:x,extend:b,trim:w}},function(e,t){"use strict";e.exports=function(e,t){return function(){for(var n=new Array(arguments.length),r=0;r<n.length;r++)n[r]=arguments[r];return e.apply(t,n)}}},function(e,t){function n(e){return!!e.constructor&&"function"==typeof e.constructor.isBuffer&&e.constructor.isBuffer(e)}function r(e){return"function"==typeof e.readFloatLE&&"function"==typeof e.slice&&n(e.slice(0,0))}/*!
       * Determine if an object is a Buffer
       *
       * @author   Feross Aboukhadijeh <https://feross.org>
       * @license  MIT
       */
          e.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},function(e,t,n){"use strict";function r(e){this.defaults=e,this.interceptors={request:new s,response:new s}}var o=n(6),i=n(2),s=n(17),u=n(18);r.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,{method:"get"},this.defaults,e),e.method=e.method.toLowerCase();var t=[u,void 0],n=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)n=n.then(t.shift(),t.shift());return n},i.forEach(["delete","get","head","options"],function(e){r.prototype[e]=function(t,n){return this.request(i.merge(n||{},{method:e,url:t}))}}),i.forEach(["post","put","patch"],function(e){r.prototype[e]=function(t,n,r){return this.request(i.merge(r||{},{method:e,url:t,data:n}))}}),e.exports=r},function(e,t,n){"use strict";function r(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function o(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(8):"undefined"!=typeof process&&(e=n(8)),e}var i=n(2),s=n(7),u={"Content-Type":"application/x-www-form-urlencoded"},a={adapter:o(),transformRequest:[function(e,t){return s(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};a.headers={common:{Accept:"application/json, text/plain, */*"}},i.forEach(["delete","get","head"],function(e){a.headers[e]={}}),i.forEach(["post","put","patch"],function(e){a.headers[e]=i.merge(u)}),e.exports=a},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(2),o=n(9),i=n(12),s=n(13),u=n(14),a=n(10),c="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n(15);e.exports=function(e){return new Promise(function(t,f){var p=e.data,d=e.headers;r.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest,h="onreadystatechange",m=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in l||u(e.url)||(l=new window.XDomainRequest,h="onload",m=!0,l.onprogress=function(){},l.ontimeout=function(){}),e.auth){var y=e.auth.username||"",w=e.auth.password||"";d.Authorization="Basic "+c(y+":"+w)}if(l.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),l.timeout=e.timeout,l[h]=function(){if(l&&(4===l.readyState||m)&&(0!==l.status||l.responseURL&&0===l.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in l?s(l.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?l.response:l.responseText,i={data:r,status:1223===l.status?204:l.status,statusText:1223===l.status?"No Content":l.statusText,headers:n,config:e,request:l};o(t,f,i),l=null}},l.onerror=function(){f(a("Network Error",e,null,l)),l=null},l.ontimeout=function(){f(a("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",l)),l=null},r.isStandardBrowserEnv()){var g=n(16),v=(e.withCredentials||u(e.url))&&e.xsrfCookieName?g.read(e.xsrfCookieName):void 0;v&&(d[e.xsrfHeaderName]=v)}if("setRequestHeader"in l&&r.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),e.withCredentials&&(l.withCredentials=!0),e.responseType)try{l.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&l.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&l.upload&&l.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){l&&(l.abort(),f(e),l=null)}),void 0===p&&(p=null),l.send(p)})}},function(e,t,n){"use strict";var r=n(10);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";var r=n(11);e.exports=function(e,t,n,o,i){var s=new Error(e);return r(s,t,n,o,i)}},function(e,t){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e}},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=n(2);e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(o.isURLSearchParams(t))i=t.toString();else{var s=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)?t+="[]":e=[e],o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),s.push(r(t)+"="+r(e))}))}),i=s.join("&")}return i&&(e+=(e.indexOf("?")===-1?"?":"&")+i),e}},function(e,t,n){"use strict";var r=n(2),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,s={};return e?(r.forEach(e.split("\n"),function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(s[t]&&o.indexOf(t)>=0)return;"set-cookie"===t?s[t]=(s[t]?s[t]:[]).concat([n]):s[t]=s[t]?s[t]+", "+n:n}}),s):s}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t){"use strict";function n(){this.message="String contains an invalid character"}function r(e){for(var t,r,i=String(e),s="",u=0,a=o;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&t>>8-u%1*8)){if(r=i.charCodeAt(u+=.75),r>255)throw new n;t=t<<8|r}return s}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";n.prototype=new Error,n.prototype.code=5,n.prototype.name="InvalidCharacterError",e.exports=r},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,s){var u=[];u.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&u.push("expires="+new Date(n).toGMTString()),r.isString(o)&&u.push("path="+o),r.isString(i)&&u.push("domain="+i),s===!0&&u.push("secure"),document.cookie=u.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";function r(){this.handlers=[]}var o=n(2);r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=r},function(e,t,n){"use strict";function r(e){e.cancelToken&&e.cancelToken.throwIfRequested()}var o=n(2),i=n(19),s=n(20),u=n(6),a=n(21),c=n(22);e.exports=function(e){r(e),e.baseURL&&!a(e.url)&&(e.url=c(e.baseURL,e.url)),e.headers=e.headers||{},e.data=i(e.data,e.headers,e.transformRequest),e.headers=o.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),o.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=e.adapter||u.adapter;return t(e).then(function(t){return r(e),t.data=i(t.data,t.headers,e.transformResponse),t},function(t){return s(t)||(r(e),t&&t.response&&(t.response.data=i(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t,n){return r.forEach(n,function(n){e=n(e,t)}),e}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(23);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r(function(t){e=t});return{token:t,cancel:e}},e.exports=r},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}}])});
      //# sourceMappingURL=axios.min.map
      
    • Step2: 在web项目核心目录(即webapp)下创建axios.html文件并在该html文件中引入Axios的源码js文件

      <script src="js/axios-0.18.0.js"></script>
      
    • Step3:axios.html文件中重新定义一个<script>标签并在该标签体内使用Axios代码发送请求并获取响应结果

      • GET方式发送请求

        axios({
        	// 请求方式
            method:"get",
        	// 请求的资源路径及参数
            url:"http://localhost:8080/AxiosDemo/axiosServlet?username=zhangsan"
        }).then(function (resp){
        	// resp.data获取服务端回响数据
            alert(resp.data);
        })
        
      • POST方式发送请求

        axios({
        	// 请求方式
            method:"post",
        	// 请求的资源路径
            url:"http://localhost:8080/AxiosDemo/axiosServlet",
        	// 请求参数
            data:"username=zhangsan"
        }).then(function (resp){
        	// resp.data获取服务端回响数据
            alert(resp.data);
        })
        
  • GET请求代码示例

    • 在Web项目核心目录(即webapp)下创建js目录,引入Axios的源码文件axios-0.18.0.js,如下图所示

      在这里插入图片描述

    • servlet包下创建实现Servlet接口的实现类AxiosGetServlet,代码如下:

      package at.guigu.web.servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet("/axiosGetServlet")
      public class AxiosGetServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              System.out.println("get...");
              //1 获取响应数据
              String username = request.getParameter("username");
              System.out.println(username);
              //2 返回响应数据
              response.getWriter().write("hello axios...");
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      
    • 在web项目核心目录(即webapp)下创建axiosget.html文件并在该html文件中引入Axios的源码js文件,代码如下

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
          </body>
      </html>
      
    • axiosget.html文件中重新定义一个<script>标签并在该标签体内使用Axios发送请求并获取响应结果

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
              <script>
                  axios({
                      // 请求方式
                      method:"get",
                      // 请求的资源路径及参数
                      url:"http://localhost:8080/AxiosDemo/axiosGetServlet?username=zhangsan"
                  }).then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>
          </body>
      </html>
      

      Tomcat运行该项目后截图如下所示

      在这里插入图片描述

  • POST请求代码示例(以AJAX案例为基础,本Web项目名为AxiosDemo

    • 第一步与GET请求代码示例一致,所以此处省略。直接写第二步

    • servlet包下创建实现Servlet接口的实现类AxiosPostServlet,代码如下:

      package at.guigu.web.servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      @WebServlet("/axiosPostServlet")
      public class AxiosPostServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              //1 获取响应数据
              String username = request.getParameter("username");
              System.out.println(username);
              //2 返回响应数据
              response.getWriter().write("hello axiosPost...");
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              System.out.println("post...");
              this.doGet(request, response);
          }
      }
      
    • 在web项目核心目录(即webapp)下创建axiospost.html文件并在该html文件中引入Axios的源码js文件,代码如下

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
          </body>
      </html>
      
    • axiospost.html文件中重新定义一个<script>标签并在该标签体内使用Axios代码发送请求并获取响应结果

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
              <script>
                  axios({
                      // 请求方式
                      method:"post",
                      // 请求的资源路径
                      url:"http://localhost:8080/AxiosDemo/axiosPostServlet",
                      // 请求参数
                      data:"username=lisi"
                  }).then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>
          </body>
      </html>
      

      Tomcat运行该项目后截图如下所示

      在这里插入图片描述

Axios请求方式别名

方法解释
axios.get(url[,config])get 请求
axios.delete(url[,config])delete 请求
axios.head(url[,config])head 请求
axios.option(url[,config])options 请求
axios.post(url[,data[,config])post 请求
axios.put(url[,data[,config])put 请求
axios.patch(url[,data[,config])patch 请求

在这里插入图片描述

  • 解释:在Axios快速入门中GET和POST请求方式略显繁琐, 所以Axios 为所有支持的请求方式都提供了对应的方法,如上所示

  • 注意:繁琐的请求方式和简略的请求方式视不同的情况用户自己而定

  • 快速入门中GETPOST请求方式代码更改如下

    • Get请求方式代码如下

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
              <script>
                  axios.get("http://localhost:8080/AxiosDemo/axiosGetServlet?username=zhangsan").then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>
          </body>
      </html>
      
    • POST请求方式代码如下

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
              <script>
                  axios.post("http://localhost:8080/AxiosDemo/axiosPostServlet", "username=lisi").then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>
          </body>
      </html>
      

JSON

  • 定义:JSON(即JavaScript Object Notation):JavaScript对象表示法。它是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。

  • JSON语法简单,层次结构鲜明,现多用于作为 数据载体 ,在网络中进行数据传输

  • JSON的Web项目名为AxiosDemo,已上传到Gitee可自行下载

  • JavaScript与JSON区别

    • JavaScript对象的属性用一个大括号括起来并用键值对表示,可详见[W3school官网的JavaScript对象](JavaScript 对象 (w3school.com.cn)),简略表示如图所示

      在这里插入图片描述

    • JSON对象的属性也是用键值对表示,但是 键必须为字符串形式且必须为双引号, 可详见W3school官网的JSON对象,简略表示如图所示

      在这里插入图片描述

JSON基础语法

  • 定义格式如下:var 变量名 = '{"key":value, "key":value, ...}';

    • value可取的数据类型为:

      • 数字(整数或浮点数)
      • 字符串(必须在双引号中)
      • 逻辑值(true或false)
      • 数组(在方括号中)
      • 对象(在花括号中)
      • null
    • 示例:在Web项目核心目录下创建jsondemo1.html文件,代码如下

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script>
                  //1 定义JSON
                  var jsonStr = '{"name":"zhangsan", "age":23, "addr":["北京", "上海", "西安"]}';
                  alert(jsonStr);
              </script>
          </body>
      </html>
      

      Tomcat运行该Web项目后,运行截图如下

      在这里插入图片描述

    • 注意:JSON对象可以嵌套

  • JSON字符串转为JS对象: 由上述运行截图可知,页面显示的均为JSON字符串并不是JS对象,所以我们可以用JSON对象中的方法JSON.parse(jsonStr)JSON字符串转换为JS对象,jsondemo1.html文件代码如下:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <script>
                //1 定义JSON
                var jsonStr = '{"name":"zhangsan", "age":23, "addr":["北京", "上海", "西安"]}';
                //2 将JSON字符串转换为JS对象
                let jsObject = JSON.parse(jsonStr);
                alert(jsObject);
            </script>
        </body>
    </html>
    

    在这里插入图片描述

  • 获取JS对象中属性的值:JSON字符串转为JS对象后,通过方法js对象名.属性名来获取JS对象中属性的值,jsondemo1.html文件代码如下:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <script>
                //1 定义JSON
                var jsonStr = '{"name":"zhangsan", "age":23, "addr":["北京", "上海", "西安"]}';
                //2 将JSON字符串转换为JS对象
                let jsObject = JSON.parse(jsonStr);
                //3 获取JS对象中指定键的值
                let name = jsObject.name;
                alert(name);
            </script>
        </body>
    </html>
    

    在这里插入图片描述

  • JS对象转为JSON字符串: 利用JSON.stringify(obj)方法来将JS对象转为对应的JSON字符串,新创建jsondemo2.html文件且文件代码如下:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <script>
                //1 定义JSON
                var jsonStr = '{"name":"zhangsan", "age":23, "addr":["北京", "上海", "西安"]}';
                //2 将JSON字符串转换为JS对象
                let jsObject = JSON.parse(jsonStr);
                //3 将JS对象转为JSON字符串
                let jsonStr2 = JSON.stringify(jsObject);
                alert(jsonStr2)
            </script>
        </body>
    </html>
    

    在这里插入图片描述

发送异步请求携带参数

  • 注意:

    • 使用 Axios 发送请求时,如果要携带复杂的数据时都会以 JSON 格式进行传递
    • Axios中,JSON字符串和JS对象会自动进行转换
    • 发送异步请求时,如果请求参数是 JSON 格式,那请求方式必须是 POST。因为 JSON 串需要放在请求体中。
  • 步骤如下:

    • 原始的POST请求的代码如下:

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
              <!--<script>
                  axios({
                      // 请求方式
                      method:"post",
                      // 请求的资源路径
                      url:"http://localhost:8080/AxiosDemo/axiosPostServlet",
                      // 请求参数
                      data:"username=lisi"
                  }).then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>-->
              <script>
                  axios.post("http://localhost:8080/AxiosDemo/axiosPostServlet", "username=lisi").then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>
          </body>
      </html>
      
    • 由于请求参数不可能由我们自己拼接字符串的,我们可以提前定义一个 js 对象,用来封装需要提交的参数,然后使用 JSON.stringify(js对象) 转换为 JSON 串,再将该 JSON 串作为 axiosdata 属性值进行请求参数的提交。使用JSON后的代码如下:

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
              <!--<script>
                  var jsObject = {name:"zhangsan"};
                  axios({
                      // 请求方式
                      method:"post",
                      // 请求的资源路径
                      url:"http://localhost:8080/AxiosDemo/axiosPostServlet",
                      // 请求参数:手动将JS对象转为JSON字符串
                      data:JSON.stringify(jsObject)
                  }).then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>-->
              <script>
                  var jsObject = {name:"zhangsan"};
                  axios.post("http://localhost:8080/AxiosDemo/axiosPostServlet", JSON.stringify(jsObject)).then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>
          </body>
      </html>
      
    • 由于Axios会自动将JS对象转为 JSON 字符串进行提交,所以我们只需要将需要提交的参数封装成 js 对象,并将该 js 对象作为 Axiosdata 属性值即可,最终使用JSON后的代码如下:

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <script src="js/axios-0.18.0.js"></script>
              <!--<script>
                  var jsObject = {name:"zhangsan"};
                  axios({
                      // 请求方式
                      method:"post",
                      // 请求的资源路径
                      url:"http://localhost:8080/AxiosDemo/axiosPostServlet",
                      // 请求参数:Axios自动将JS对象转为JSON字符串
                      data:jsObject
                  }).then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>-->
              <script>
                  var jsObject = {name:"zhangsan"};
                  axios.post("http://localhost:8080/AxiosDemo/axiosPostServlet", jsObject).then(function (resp){
                      // resp.data获取服务端回响数据
                      alert(resp.data);
                  })
              </script>
          </body>
      </html>
      

      Tomcat运行该Web项目截图如下

      在这里插入图片描述

JSON数据和Java对象转换

  • 由于JSON是作为 数据载体 ,在网络中进行数据传输的。

    • 服务端接收到数据后需要将数据转为Java对象来进行使用
      • 前端Axios会自动将JS对象转为JSON字符串传给后端,后端接收到后会将该字符串数据转为Java对象
    • 服务端发送响应时需要先将Java对象转为JSON字符串数据然后才会给前端做出响应
  • 我们主要学习两部分

    • 请求数据:JSON字符串转为Java对象
    • 响应数据:Java对象转为JSON字符串
    • 阿里提供了一个Java语言编写的高性能功能完善的JSONFastjson,它是目前Java语言中最快的JSON库,可以实现Java对象和JSON字符串的相互转换
  • Fastjson库导入坐标依赖后即可使用,坐标依赖代码如下:

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.83</version>
    </dependency>
    
  • Java对象转JSON字符串: 只需要使用 Fastjson 提供的 JSON 类中的 toJSONString() 静态方法即可。String jsonStr = JSON.toJSONString(obj);

  • JSON字符串转Java对象: 只需要使用 Fastjson 提供的 JSON 类中的 parseObject() 静态方法即可。User user = JSON.parseObject(jsonStr, User.class);

  • Java对象与JSON字符串互相转换的测试步骤如下:

    • Step1: 导入Fastjson坐标,pom.xml文件完整代码如下:

      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.example</groupId>
        <artifactId>AxiosDemo</artifactId>
        <packaging>war</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>AxiosDemo Maven Webapp</name>
        <url>http://maven.apache.org</url>
        <dependencies>
          <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
          </dependency>
      
          <!--MyBatis依赖-->
          <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.16</version>
          </dependency>
      
          <!--mysql驱动-->
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
          </dependency>
      
          <!--Servlet依赖-->
          <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
            <!--依赖范围关键字provided:在编译环境和测试环境有效,但在真正运行时就不会在使用该jar包-->
          </dependency>
      
          <!--JSP依赖-->
          <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
          </dependency>
      
          <!--jstl依赖-->
          <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
          </dependency>
          <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
          </dependency>
          <!--Fastjson依赖-->
          <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
          </dependency>
          
        </dependencies>
        <build>
          <finalName>AxiosDemo</finalName>
          <plugins>
            <!-- Tomcat插件 -->
            <plugin>
              <groupId>org.apache.tomcat.maven</groupId>
              <artifactId>tomcat7-maven-plugin</artifactId>
              <version>2.2</version>
            </plugin>
          </plugins>
        </build>
      </project>
      
    • Step2: 创建一个测试目录,并在该测试目录下创建一个包at.guigu.json并在该包下创建测试类FastJsonDemo1,代码如下:

      package at.guigu.json;
      
      import at.guigu.pojo.User;
      import com.alibaba.fastjson.JSON;
      
      public class FastJsonDemo1 {
          public static void main(String[] args) {
              //1 将Java对象转为JSON字符串
              //1.1 创建User对象
              User user = new User();
              user.setId(10);
              user.setUsername("xiaofei");
              user.setPassword("123");
              //1.2 将User对象转为JSON字符串
              String jsonStr = JSON.toJSONString(user);
              System.out.println(jsonStr);
      
              //2 将JSON字符串转为指定的Java对象
              User user1 = JSON.parseObject("{\"id\":10,\"password\":\"123\",\"username\":\"xiaofei\"}", User.class);
              System.out.println(user1);
          }
      }
      

      运行该测试类后截图如下:

      在这里插入图片描述

Axios、JSON综合案例

在这里插入图片描述

  • 注意
    • 由于使用HTML+AJAX可以用来 替换 JSP页面 ,所以本案例不使用JSP
    • 本案例已上传到Gitee,可自行下载

环境准备

本项目以三层架构案例为基础进行重写,本项目名为AxiosJsonDemo,可自行在Gitee下载,需要额外环境准备的工作如下:

  • 引入坐标(在pom.xml文件中引入坐标依赖),并配置Tomcat(可详见Tomcat部分)

    • 需要的坐标依赖有mybatis、mysql驱动、servlet、jsp、jstl、Fastjson

    • 需要的插件有Tomcat插件

    • 完整pom.xml文件如下

      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>org.example</groupId>
        <artifactId>AxiosJsonDemo</artifactId>
        <packaging>war</packaging>
        <version>1.0-SNAPSHOT</version>
        <name>AxiosJsonDemo Maven Webapp</name>
        <url>http://maven.apache.org</url>
        <dependencies>
          <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
          </dependency>
      
          <!--MyBatis依赖-->
          <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.16</version>
          </dependency>
      
          <!--mysql驱动-->
          <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
          </dependency>
      
          <!--Servlet依赖-->
          <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
            <!--依赖范围关键字provided:在编译环境和测试环境有效,但在真正运行时就不会在使用该jar包-->
          </dependency>
      
          <!--JSP依赖-->
          <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
          </dependency>
      
          <!--jstl依赖-->
          <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
          </dependency>
          <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
          </dependency>
          <!--Fastjson依赖-->
          <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
          </dependency>
        </dependencies>
        <build>
          <finalName>AxiosJsonDemo</finalName>
          <plugins>
            <!-- Tomcat插件 -->
            <plugin>
              <groupId>org.apache.tomcat.maven</groupId>
              <artifactId>tomcat7-maven-plugin</artifactId>
              <version>2.2</version>
            </plugin>
          </plugins>
        </build>
      </project>
      
  • 创建数据库表tb_brandtb_user并使IDEA与数据库建立连接,SQL代码如下

    DROP TABLE IF EXISTS tb_brand;
    
    -- 创建品牌表brand
    CREATE TABLE IF NOT EXISTS tb_brand
    (
    	-- id 主键
    	id int PRIMARY KEY auto_increment,
    	-- 品牌名称
    	brand_name VARCHAR(20),
    	-- 企业名称
    	company_name VARCHAR(20),
    	-- 排序字段
    	ordered INT,
    	-- 描述信息
    	description VARCHAR(100),
    	-- 状态:0:禁用  1:启用
    	status INT
    );
    
    -- 添加数据
    INSERT INTO tb_brand(brand_name, company_name, ordered, description, status) 
    VALUES ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
    			 ('华为', '华为技术有限公司', 100, '华为致力于构建万物互联的世界', 1),
           ('小米', '小米科技有限公司', 50, 'Are you OK', 1);
    
    

在这里插入图片描述

  • 自行更改jsp文件中Servlet资源的访问路径

查询所有

  • 在查询所有之前需要先用户登录,用户登录代码步骤可详见会话跟踪技术中的案例,登陆后的查询所有需满足三层架构,各层需要做的工作如下所示

    在这里插入图片描述

  • Dao层/Map层 以及Service层 代码省略可详见会话跟踪技术中的案例

  • Web层

    • 重写SelectAllServlet类代码,代码如下

      package at.guigu.web.servlet;
      
      import at.guigu.pojo.Brand;
      import at.guigu.service.BrandService;
      import com.alibaba.fastjson.JSON;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.util.List;
      
      @WebServlet("/selectAllServlet")
      public class SelectAllServlet extends HttpServlet {
          //1 创建一个私有的BrandService对象
          private BrandService brandService = new BrandService();
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              //2 调用BrandService中的方法查询所有数据
              List<Brand> brands = brandService.getAll();
      
              //3 将集合转为JSON字符串数据:即将对象序列化为数据
              String jsonStr = JSON.toJSONString(brands);
              
              //4 处理中文乱码
              response.setContentType("text/json;charset=utf-8");
              
              //5 响应数据
              response.getWriter().write(jsonStr);
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      

      注意: 一般情况下当我们使用JSON数据进行交互的话,我们可以在Servlet实现类写完后直接运行该Web项目然后访问该实现类进行测试**(测试时要先将过滤器代码关闭注释,不然无法进行测试)** ,因为该Servlet实现类若无问题则JSON数据会直接呈现在页面上,如下截图所示

      在这里插入图片描述

    • 在web项目核心目录(即webapp)下创建brand.html文件并在该html文件中引入Axios的源码js文件

      <script src="js/axios-0.18.0.js"></script>
      
    • brand.html文件中重新定义一个<script>标签并在该标签体内使用Axios代码发送请求并获取响应结果,完整代码如下:

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <input type="button" value="新增" id="add"><br>
              <hr>
              <table border="1" cellspacing="0" id="brandTable">
      
              </table>
              <script src="js/axios-0.18.0.js"></script>
              <script>
                  //1 当页面完全被加载时执行该事件
                  window.onload = function () {
                      //2 页面加载完成后发送Ajax请求
                      axios({
                          method:"get",
                          url:"http://localhost:8080/AxiosJsonDemoo/selectAllServlet"
                      }).then(function (resp) {
                          //3 获取数据
                          let brands = resp.data;
                          //4 设置表头
                          let tableData = "<tr>\n" +
                              "                <th>序号</th>\n" +
                              "                <th>品牌名称</th>\n" +
                              "                <th>企业名称</th>\n" +
                              "                <th>排序</th>\n" +
                              "                <th>品牌介绍</th>\n" +
                              "                <th>状态</th>\n" +
                              "                <th>操作</th>\n" +
                              "            </tr>";
                          for (let i = 0; i < brands.length; i++) {
                              //5 获取数组中的JSON字符串数据
                              //前端会自动将JSON字符串数据转为Java对象
                              let brand = brands[i];
                              tableData += "<tr align=\"center\">\n" +
                                  "            <td>" + (i + 1) + "</td>\n" +
                                  "            <td>" + brand.brandName + "</td>\n" +
                                  "            <td>" + brand.companyName + "</td>\n" +
                                  "            <td>" + brand.ordered + "</td>\n" +
                                  "            <td>" + brand.description + "</td>\n" +
                                  "            <td>" + (brand.status == 1 ? "启用" : "禁用") + "</td>\n" +
                                  "<td><a href=\"/AxiosJsonDemoo/selectByIdServlet?id=" + brand.id + "\">修改</a> <a href=\"/AxiosJsonDemoo/deleteServlet?id=" + brand.id + "\">删除</a></td>" +
                                  "        </tr>"
                          }
                          //6 设置表格数据
                          document.getElementById("brandTable").innerHTML = tableData;
                      })
                  }
              </script>
          </body>
      </html>
      
  • Tomcat运行该Web项目后截图如下所示

    在这里插入图片描述

添加

在这里插入图片描述

  • 解释

    单击新增按钮后跳转到添加品牌的页面(该页面为addBrand.html),然后输入要添加的品牌信息后单击提交,提交后浏览器将请求数据提交到服务器的Servlet,然后将数据保存到数据库中,最后重新展示一下查询所有的页面,即可显示出最新的所有数据

  • 各层需要做的工作如图所示

    在这里插入图片描述

  • Dao层/Map层 以及Service层 代码省略可详见会话跟踪技术中的案例

  • Web层

    • 重写AddServlet类代码,代码及步骤如下

      1. 获取请求参数
        • 由于前端提交的是 JSON 格式的数据,所以我们不能使用request.getParameter()方法获取请求参数
          • 如果提交的数据格式是 username=zhangsan&age=23 ,后端就可以使用 request.getParameter() 方法获取
          • 如果提交的数据格式是 JSON,后端就需要通过 request.getReader() 来获取输入流,然后通过输入流读取数据
      2. 将获取到的请求参数(json格式的数据)转换为 Brand 对象
      3. 调用 service 的 add() 方法进行添加数据的逻辑处理
      4. JSON 数据响应回给浏览器。
      package at.guigu.web.servlet;
      
      import at.guigu.pojo.Brand;
      import at.guigu.service.BrandService;
      import com.alibaba.fastjson.JSON;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.BufferedReader;
      import java.io.IOException;
      
      @WebServlet("/addServlet")
      public class AddServlet extends HttpServlet {
          //1 创建一个私有的BrandService对象
          private BrandService brandService = new BrandService();
          @Override
          protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      
              //2 接收表单提交的JSON数据并封装为Brand对象
              /*request.getParameter不能接收JSON字符串数据
              String brandName = request.getParameter("brandName");
              String companyName = request.getParameter("companyName");
              String ordered = request.getParameter("ordered");
              String description = request.getParameter("description");
              String status = request.getParameter("status");*/
              //2.1 获取请求体数据
              BufferedReader br = request.getReader();
              //获取到的客户端发送的JSON字符串数据不论多长都是一行,所以读取一行即可
              String jsonStr = br.readLine();
              //2.2 将JSON字符串数据转为Java的Brand对象
              Brand brand = JSON.parseObject(jsonStr, Brand.class);
      
              //3 调用brandService完成添加
              brandService.add(brand);
      
              //4 响应成功标识
              response.getWriter().write("success");
          }
      
          @Override
          protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
              this.doGet(request, response);
          }
      }
      
    • brand.html文件中为新增按钮绑定单击事件,代码如下:

      <!DOCTYPE html>
      <html lang="en">
          <head>
              <meta charset="UTF-8">
              <title>Title</title>
          </head>
          <body>
              <input type="button" value="新增" id="add"><br>
              <hr>
              <table border="1" cellspacing="0" id="brandTable">
      
              </table>
              <script src="js/axios-0.18.0.js"></script>
              <script>
                  //1 当页面完全被加载时执行该事件
                  window.onload = function () {
                      //2 页面加载完成后发送Ajax请求
                      axios({
                          method:"get",
                          url:"http://localhost:8080/AxiosJsonDemoo/selectAllServlet"
                      }).then(function (resp) {
                          //3 获取数据
                          let brands = resp.data;
                          //4 设置表头
                          let tableData = "<tr>\n" +
                              "                <th>序号</th>\n" +
                              "                <th>品牌名称</th>\n" +
                              "                <th>企业名称</th>\n" +
                              "                <th>排序</th>\n" +
                              "                <th>品牌介绍</th>\n" +
                              "                <th>状态</th>\n" +
                              "                <th>操作</th>\n" +
                              "            </tr>";
                          for (let i = 0; i < brands.length; i++) {
                              //5 获取数组中的JSON字符串数据
                              //前端会自动将JSON字符串数据转为Java对象
                              let brand = brands[i];
                              tableData += "<tr align=\"center\">\n" +
                                  "            <td>" + (i + 1) + "</td>\n" +
                                  "            <td>" + brand.brandName + "</td>\n" +
                                  "            <td>" + brand.companyName + "</td>\n" +
                                  "            <td>" + brand.ordered + "</td>\n" +
                                  "            <td>" + brand.description + "</td>\n" +
                                  "            <td>" + (brand.status == 1 ? "启用" : "禁用") + "</td>\n" +
                                  "<td><a href=\"/AxiosJsonDemoo/selectByIdServlet?id=" + brand.id + "\">修改</a> <a href=\"/AxiosJsonDemoo/deleteServlet?id=" + brand.id + "\">删除</a></td>" +
                                  "        </tr>"
                          }
                          //6 设置表格数据
                          document.getElementById("brandTable").innerHTML = tableData;
                      })
                  }
                  document.getElementById("add").onclick = function () {
                      //addBrand.jsp的路径
                      location.href = "/AxiosJsonDemoo/addBrand.html";
                  }
              </script>
          </body>
      </html>
      
    • 在web项目核心目录(即webapp)下创建addBrand.html文件并在该html文件中引入Axios的源码js文件

      <script src="js/axios-0.18.0.js"></script>
      
    • addBrand.html文件中重新定义一个<script>标签并在该标签体内使用Axios代码发送请求并获取响应结果,完整步骤及代码如下:

      1. 将表单的action属性值设为空,并将=提交按钮的类型由submit改为普通的button
        • 原因: 表单直接提交属于同步请求方式提交表单,为了使用异步方式以及AJAX+JSON异步方式提交所以要将action属性值设为空并将提交按钮的type属性值设为button
      2. 给提交按钮绑定点击事件,并在绑定的匿名函数中发送AJAX异步请求
        1. 将表单数据转为JSON字符串数据并将其发送到服务端
        2. 判断是否添加成功,若添加成功则跳转到查询所有页面
      <!DOCTYPE html>
      <html lang="en">
      
          <head>
              <meta charset="UTF-8">
              <title>添加品牌</title>
          </head>
          <body>
              <h3>添加品牌</h3>
              <!--表单直接提交属于同步请求方式提交表单,为了使用异步方式以及AJAX+JSON异步方式提交所以要将action属性值设为空并将提交按钮的type属性值设为button-->
              <!--action的属性值为浏览器提交到服务器的资源路径-->
              <!--将action属性值由具体的url改为空-->
              <form action="" method="post">
                  品牌名称:<input id="brandName" name="brandName"><br>
                  企业名称:<input id="companyName" name="companyName"><br>
                  排序:<input id="ordered" name="ordered"><br>
                  描述信息:<textarea rows="5" cols="20" id="description" name="description"></textarea><br>
                  状态:
                  <input type="radio" name="status" value="0">禁用
                  <input type="radio" name="status" value="1">启用<br>
                  <!--将提交按钮的type属性由submit改为button-->
                  <input type="button" id="btn"  value="提交">
              </form>
      
              <script src="js/axios-0.18.0.js"></script>
      
              <script>
                  //1 给提交按钮绑定单击事件
                  document.getElementById("btn").onclick = function () {
                      //2 将表单数据转为JSON字符串数据
                      //2.1 设置JS对象
                      var formData = {
                          brandName:"",
                          companyName:"",
                          ordered:"",
                          description:"",
                          status:"",
                      };
                      //2.2 获取表单数据
                      let brandName = document.getElementById("brandName").value;
                      let companyName = document.getElementById("companyName").value;
                      let ordered = document.getElementById("ordered").value;
                      let description = document.getElementById("description").value;
                      // 获取单选框数组
                      let status = document.getElementsByName("status");
                      //2.3 给JS对象设置数据
                      formData.brandName = brandName;
                      formData.companyName = companyName;
                      formData.ordered = ordered;
                      formData.description = description;
                      // 判断选择的是禁用还是启用并设置数据
                      for (let i = 0; i < status.length; i++) {
                          if(status[i].checked){
                              formData.status = status[i].value ;
                          }
                      }
                      //console.log(formData);
                      //2 发送Ajax请求
                      axios({
                          method:"post",
                          url:"http://localhost:8080/AxiosJsonDemoo/addServlet",
                          //3 JSON数据格式发送请求
                          // formData为JS对象,Axios会自动将JS对象转为JSON字符串然后在传给服务端
                          data:formData
                      }).then(function (resp) {
                          //4 获取响应数据并判断响应数据是否为success
                          if(resp.data == "success"){
                              location.href = "http://localhost:8080/AxiosJsonDemoo/brand.html";
                          }
                      })
                  }
              </script>
          </body>
      </html>
      
  • Tomcat运行该Web项目后,运行截图如下

    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1912233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring系统学习 - AOP之基于注解的AOP和XML的AOP

上一篇我们围绕了AOP中代理模式的使用&#xff0c;这篇我们将主要围绕AOP的相关术语介绍&#xff0c;以及重点围绕基于注解的AOP进行相关知识的概述和使用说明。 AOP的相关术语 切面&#xff08;Aspect&#xff09;&#xff1a;切面是一个模块化的横切关注点&#xff0c;它包含…

【关于车载测试的基础知识的认知详解】

目录 一、目前车企的趋势 1. 电动化&#xff1a; 2. 自动驾驶技术&#xff1a; 3. 车联网&#xff08;Connected Cars&#xff09;&#xff1a; 4. 智能化和数字化&#xff1a; 5. 安全性&#xff1a; 6. 轻量化&#xff1a; 7. 个性化和定制化&#xff1a; 8. 供应链…

C基础day7

一、思维导图 二、课后练习 1、提示并输入一个字符串&#xff0c;统计该字符串中字母、数字、空格以及其他字符的个数 #include<myhead.h> #define M 20 int main(int argc, const char *argv[]) {int sum_a0,sum_b0,sum_c0,sum_d0;char str[M];printf("please en…

Vagrant配合VirtualBox搭建虚拟机

目录 前言一、软件下载及安装1.下载2.安装扩展&#xff1a; 二、创建一个虚拟机1.Vagrant官方镜像仓库 三、使用远程工具连接虚拟机1.修改相关配置文件 四、虚拟机克隆及使用1.通用配置2.简单搭建一个java环境3.克隆虚拟机1.重命名虚拟机&#xff08;可选&#xff09;2.打包指定…

阿里发布大模型发布图结构长文本处理智能体,超越GPT-4-128k

随着大语言模型的发展&#xff0c;处理长文本的能力成为了一个重要挑战。虽然有许多方法试图解决这个问题&#xff0c;但都存在不同程度的局限性。最近&#xff0c;阿里巴巴的研究团队提出了一个名为GraphReader的新方法&#xff0c;通过将长文本组织成图结构&#xff0c;并利用…

在FPGA程序中Handshake(握手)和Register(寄存器)区别

在FPGA程序中&#xff0c;Handshake&#xff08;握手&#xff09;和Register&#xff08;寄存器&#xff09;是两种不同的通信和数据传输机制。它们各有特点和适用场景。以下是它们的区别和应用场景的详细解释&#xff1a; Register&#xff08;寄存器&#xff09; 特点&#…

入门PHP就来我这(高级)19 ~ 捕获sql错误

有胆量你就来跟着路老师卷起来&#xff01; -- 纯干货&#xff0c;技术知识分享 路老师给大家分享PHP语言的知识了&#xff0c;旨在想让大家入门PHP&#xff0c;并深入了解PHP语言。 接着上篇我们来看下sql错误的捕获模式。 1 PDO中捕获SQL语句中的错误 在PDO中有3种方法可以捕…

产品经理/项目经理管理项目使用最多的12款项目软件对比

盘点不同行业、项目类型的下的12款主流的项目管理软件&#xff1a;PingCode、Worktile、Teambition、TAPD、广联达、Asana、Basecamp、Jira、Microsoft Project、ClickUp、Redmine、Trello。 在这个项目管理工具层出不穷的时代&#xff0c;选择一个合适的软件似乎成了一个令许多…

博客标题:C++中的继承:构建面向对象的基石

目录 ​编辑 引言 继承的基本形式 示例1&#xff1a;基本继承 继承的类型 示例2&#xff1a;不同类型的继承 多重继承 示例3&#xff1a;多重继承 继承与多态性 示例4&#xff1a;继承与多态 结论 结尾 引言 在面向对象编程&#xff08;OOP&#xff09;中&#xff…

可以添加todo清单桌面小组件的便签哪个好?

在我们快节奏的生活中&#xff0c;有效的时间管理和任务追踪是必不可少的。为了实现这一目标&#xff0c;许多人选择使用桌面便签&#xff0c;尤其是那些具有Todo清单桌面小组件的便签。但是&#xff0c;面对市场上众多选择&#xff0c;可以添加todo清单桌面小组件的便签哪个好…

企业级网关设计

tips&#xff1a;本文完全来源于卢泽龙&#xff01;&#xff01;&#xff01; 一、Gateway概述 1.1设计目标 1.2gateway基本功能 中文文档参考&#xff1a;https://cloud.tencent.com/developer/article/1403887?from15425 三大核心&#xff1a; 二、引入依赖和yaml配置…

14-52 剑和诗人26 - RAG 和 VectorDB 简介

检索增强生成 (RAG) 和 VectorDB 是自然语言处理 (NLP) 中的两个重要概念&#xff0c;它们正在突破 AI 系统所能实现的界限。 在这篇博文中&#xff0c;我将深入探讨 RAG&#xff0c;探索其工作原理、应用、优势和局限性。 我们还将研究 VectorDB&#xff0c;这是一种专用于向…

【动态规划Ⅵ】背包问题 /// 组合问题

背包问题 什么是背包问题0-1背包问题分数背包完全背包问题重复背包问题 背包问题例题416. 分割等和子集474. 一和零 完全平方数279. 完全平方数322. 零钱兑换 排列与组合组合&#xff0c;无重复&#xff1a;518. 零钱兑换 II排列&#xff0c;可重复&#xff1a;377. 组合总和 Ⅳ…

Commons-Collections篇-CC7链

前言 和CC5反序列化链相似&#xff0c;CC7也是后半条LazyMap执行命令链不变&#xff0c;但是中间过程通过AbstractMap.equals()触发LazyMap.get()方法 环境 我们可以接着使用之前已经搭建好的环境&#xff0c;具体过程可以看CC1分析文章的环境安装部分 Commons-Collections篇…

【Java 的四大引用详解】

首先分别介绍一下这几种引用 强引用&#xff1a; 只要能通过GC ROOT根对象引用链找到就不会被垃圾回收器回收&#xff0c;当所有的GC Root都不通过强引用引用该对象时&#xff0c;才能被垃圾回收器回收。 软引用&#xff08;SoftReference&#xff09;&#xff1a; 当只有软引…

262个地级市-市场潜力指数(do文件+原始文件)

全国262个地级市-市场潜力指数&#xff08;市场潜力计算方法代码数据&#xff09;_市场潜力数据分析资源-CSDN文库 市场潜力指数&#xff1a;洞察未来发展的指南针 市场潜力指数是一个综合性的评估工具&#xff0c;它通过深入分析市场需求、竞争环境、政策支持和技术创新等多个…

LLM应用构建前的非结构化数据处理(一)标准化处理认识数据

1.学习内容 本节次学习内容来自于吴恩达老师的Preprocessing Unstructured Data for LLM Applications课程&#xff0c;因涉及到非结构化数据的相关处理&#xff0c;遂做学习整理。 2.相关环境准备 2.1 建议python版本在3.9版本以上 chromadb0.4.22 langchain0.1.5 langcha…

Redis-Jedis连接池\RedisTemplate\StringRedisTemplate

Redis-Jedis连接池\RedisTemplate\StringRedisTemplate 1. Jedis连接池1.1 通过工具类1.1.1 连接池&#xff1a;JedisConnectionFactory&#xff1a;1.1.2 test&#xff1a;&#xff08;代码其实只有连接池那里改变了&#xff09; 2. SpringDataRedis&#xff08;lettuce&#…

洛谷 数学进制 7.9

P1100 高低位交换 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码一 #include<bits/stdc.h> using namespace std; typedef long long ll; #define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)const ll N1e510; char a[N];int main() {IOS;ll a;int b[32]…

【分布式系统】ceph部署(命令+截图巨详细版)

目录 一.存储概述 1.单机存储设备 2.单机存储的问题 3.商业存储 4.分布式存储​编辑 4.1.什么是分布式存储 4.2.分布式存储的类型 二.ceph概述 1.ceph优点 2.ceph架构 3.ceph核心组件 4.OSD存储后端 5.ceph数据存储过程 6.ceph版本发行生命周期 7.ceph集群部署 …