【Spring MVC学习笔记 六】SpringMVC框架整合AJAX完成局部刷新

简介: 【Spring MVC学习笔记 六】SpringMVC框架整合AJAX完成局部刷新

本篇Blog介绍另一个常用的技术Ajax。虽然Ajax可以脱离SpringMVC去使用,但是SpringMVC对AJax有更好的支持

AJAX概念概述

AJAX即Asynchronous Javascript And XML(异步JavaScript和XML),AJAX不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的 Web 应用程序的技术。它是一套综合了多项技术的浏览器端网页开发技术。这些技术包括Javascript、XHTML和CSS、DOM、XML和XMLHttpRequest。

通过在浏览器与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新

AJAX优缺点归纳

使用AJAX的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的html代码信息。

  1. 减轻服务器负担,按需要获得数据。
  2. 无刷新更新页面,减少用户的实际和心理的等待时间。
  3. 更好的用户体验。
  4. 减轻宽带的负担。
  5. 主流浏览器支持。

当然缺点也比较明显:

  1. AJAX大量使用了Javascript和AJAX引擎,使用AJAX的程序必须测试针对各个浏览器的兼容性
  2. AJAX更新页面内容的时候并没有刷新整个页面,因此,网页的后退功能是失效的。
  3. 对搜索引擎支持不好

索性AJAX提供了一些浏览器的兼容使用方式。

AJAX原理

AJAX的原理简单来说通过浏览器的javascript对象XmlHttpRequest(Ajax引擎)对象来向服务器发异步请求并接收服务器的响应数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。即用户的请求间接通过AJAX引擎发出而不是通过浏览器直接发出,同时Ajax引擎也接收服务器返回响应的数据,所以不会导致浏览器上的页面全部刷新通俗的说,就是浏览器使用AJAX引擎做代理来处理请求和响应

浏览器创建ajax对象,AJAX对象向后端发送请求,后端接收请求响应数据给前端,AJAX对象接收响应数据通过dom操作更新视图,整个过程浏览器“不刷新”,真正的请求是由AJAX引擎发出。不是由浏览器窗口发出,所以浏览器窗口是不会刷新的, AJAX引擎同时也接收服务器返回的响应内容

AJAX发送请求方式

上述我们提到了AJAX引擎,AJAX引擎就是XMLHttpRequest对象,所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。它同时也是一个Javascript对象,常用方法与属性如下:

常用属性:

使用JavaScript语法发送请求

以下是使用JavaScript语法发送请求的get请求方式的标准步骤:

//1.创建ajax对象
    var xhr = new XMLHttpRequest();
//2.配置请求方式和请求地址
   xhr.open("get","xxx地址");
    //如果要传入参数
    xhr.open("get","xxx地址?参数名1=参数值1&参数名2=参数值2")
    //如果要设置请求方式,true表示同步,false表示异步
    xhr.open("get","xxx地址?参数名1=参数值1&参数名2=参数值2",true)
//3.发送请求
   xhr.send();
//4.监听状态变化&接收响应数据
   xhr.onreadystatechange = function(){
        if(xhr.readyState===4 && xhr.status===200){
               var data = xhr.reponseText;
        }
  }

这里需要注意两点,同步异步以及事件监听机制。

同步和异步的概念

  • 同步:就是在发出一个功能调用时,在没有得到结果之前,不能够继续调用其他功能。
  • 异步:异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果,程序继续向下执行。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。

同步是阻塞模式,异步是非阻塞模式。发送请求的区别:

  • 同步是指:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式。
  • 异步是指:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式

AJAX中的异步请求是异步的真正的实现,是指用户页面(HTML)没有直接和服务器打交道而是通过Ajax引擎间接和服务器打交道的, 而用户页面和Ajax引擎打交道时并不会等待服务器返回的响应内容,页面中的Javascript代码继续执行,也可以继续发出新的Ajax请求

事件监听的概念

需要注意其中onreadystatechange是一个监听事件(监听ajax对象的状态(readyState)变化,整个过程中readyState状态值会不断发生改变),readyState: 一共有五个值(状态4需要记忆)

  • 0 刚创建的ajax对象状态为0
  • 1 调用了open方法之后
  • 2 后端接收请求
  • 3 后端处理数据,响应数据中,数据可能没有完全传输完
  • 4 数据传输完成已就绪,放在responseText属性中。

status是状态码,标识请求结果,responseText用来存放后端响应的数据,是字符串格式。post的方式类似:

//1.创建ajax对象
   var xhr = new XMLHttpRequest();
//2.配置请求方式和请求地址
    xhr.open("post","xxx地址");
    //如果要传入参数
    xhr.open("post","xxx地址?参数名1=参数值1&参数名2=参数值2")
    //如果要设置请求方式,true表示同步,false表示异步
    xhr.open("post","xxx地址?参数名1=参数值1&参数名2=参数值2",true)
//3.设置请求头
    xhr.setRequestHeader("Content-Type","application/x-www-form-encoded");
//4.发送
    xhr.send();
//5.监听状态和接收数据
    xhr.onreadystatechange = function(){
       if(xhr.readyState===4 && xhr.status===200){
          var data = xhr.responseText;
       }
    }

使用JQuery语法发送请求

上述示例是使用原生JS语法发送AJAX请求,下面这几种是JQuery语法的形式:

//1.get方式
    $.get('xxx地址',{
        "属性名1":"属性值1",
        "属性名2":"属性值2"
    },function(data){
        //data存储就是后端响应的数据
        console.log(data);
    });
//2.post方式
    $.post('xxx地址',{
        "属性名1":"属性值1",
        "属性名2":"属性值2"
    },function(data){
        //data存储就是后端响应的数据
        console.log(data);
    });
//3.万能模式
   $.ajax({
       url:'xxx地址',
       type:"请求方式",
       dataType:”json” , //告诉后端我们想要的数据格式
       data:{
            "属性名1":"属性值1",
            "属性名2":"属性值2"    
       },
       success:function(data){
          //data存放的就是后端响应的数据
          console.log(data);
      }
   })

我们一般更多的是使用JQuery的形式去实现

SpringMVC整合AJAX

我们一般使用AJAX作为表单的验证和用户信息的验证,这样提示信息就可以直接打到前端页面上。我们的目标是模拟一个用户验证,只用用户名和密码输入完全正确才允许登录。

1 新建一个项目

首先我们新建一个AJAX的SpringMVC项目

配置pom.xml依赖,同时也引入jackson包

<!--https://mvnrepository.com/仓库获取的最新包 20210831-->
    <dependencies>
        <!-- jackson包引入-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.1</version>
        </dependency>
        <!--Spring MVC框架依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.9</version>
        </dependency>
        <!--JSP相关依赖-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!--servlet相关依赖-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!--单元测试相关依赖-->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

2 创建Model类

我们创建一个Model类,这个Model类就是要返回给前端的VO

package com.example.ajax.model;
import lombok.Data;
@Data
public class User {
    private String username;
    private String password;
}

3 编写AJAX控制器Controller

我们需要编写一个控制器,注意控制器可以使用注解@RestController来标明所有返回的数据都将被序列化为Json格式:

package com.example.ajax.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class AjaxController {
    @RequestMapping("/argcheck")
    public String ArgCheck(String name,String pwd){
        String msg = "";
        //模拟数据库中存在数据
        if (name!=null){
            if ("admin".equals(name)){
                msg = "OK";
            }else {
                msg = "用户名输入错误";
            }
        }
        if (pwd!=null){
            if ("111111".equals(pwd)){
                msg = "OK";
            }else {
                msg = "密码输入有误";
            }
        }
        return msg; //由于@RestController注解,将msg转成json格式返回
    }
}

4 注册DispatcherServlet

接着是我们的传统艺能,注册SpringMVC过滤器来拦截请求

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:context="http://www.springframework.org/schema/context"
         xmlns:mvc="http://www.springframework.org/schema/mvc"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--配置前端控制器-->
    <servlet>
        <!--1.注册DispatcherServlet-->
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--关联一个springMVC的配置文件:【servlet-name】-servlet.xml-->
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--启动级别-1,在Tomcat启动时就初始化Spring容器-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--/ 匹配所有的请求;(不包括.jsp)-->
    <!--/* 匹配所有的请求;(包括.jsp)-->
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

5 编写springmvc-servlet.xml配置文件

编写springmvc-servlet.xml文件,并且在这里加一部分配置让返回的数据不会乱码。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
     <context:component-scan base-package="com.example.ajax.controller"/>
    <!-- 让Spring MVC不处理静态资源 -->
    <mvc:default-servlet-handler />
    <!--
    支持mvc注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
     -->
    <mvc:annotation-driven />
    <!--视图解析器-->
    <!--通过视图解析器解析处理器返回的逻辑视图名并传递给DispatcherServlet-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
</beans>

6 编写前端JSP视图文件

接下来我们要编写前端的请求文件,格式如下:

<%--
  Created by IntelliJ IDEA.
  User: 13304
  Date: 2021/9/12
  Time: 15:02
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ajax</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
    <script>
        function username(){
            $.post({
                url:"${pageContext.request.contextPath}/user/argcheck",
                data:{'name':$("#name").val()},
                success:function (data) {
                    if (data.toString()=='OK'){
                        $("#userInfo").css("color","green");
                    }else {
                        $("#userInfo").css("color","red");
                    }
                    $("#userInfo").html(data);
                }
            });
        }
        function password(){
            $.post({
                url:"${pageContext.request.contextPath}/user/argcheck",
                data:{'pwd':$("#pwd").val()},
                success:function (data) {
                    if (data.toString()=='OK'){
                        $("#pwdInfo").css("color","green");
                    }else {
                        $("#pwdInfo").css("color","red");
                    }
                    $("#pwdInfo").html(data);
                }
            });
        }
    </script>
</head>
<body>
<p>
    用户名:<input type="text" id="name" onblur="username()"/>
    <span id="userInfo"></span>
</p>
<p>
    密码:<input type="text" id="pwd" onblur="password()"/>
    <span id="pwdInfo"></span>
</p>
</body>
</html>

6 配置Tomcat服务器并测试

最后我们配置并启动Tomcat服务器来测试:

在浏览器中输入:http://localhost:8080/ajax/login.jsp,返回结果为:

接下来当我们在框中输入内容可以看到ajax请求而页面并没有刷新,观察请求的url我们发现ajax请求了我们的控制器:

然后将结果返回给dom

总结一下

AJAX还是比较经典的,我理解它的常用案例就是通过局部刷新进行逻辑处理,整体页面的资源无需再被处理,也就是我们不需要提交表单给controller,然后controller再将结果打回去进行一个页面刷新操作,在带宽资源紧张的情况下这么使用还是挺方便的。所以AJAX只是一种模式,Struts框架和SpringMVC框架都可以使用,只不过因为SpringMVC可以使用@RestController注解轻易的实现JSON传输,Struts却不易实现,而对于AJAX而言,JSON 可通过 JavaScript 进行解析,更加适合于AJAX 进行传输,所以对于自动集成AJAX这一点,SpringMVC又更胜一筹。

相关文章
|
19天前
|
存储 安全 Java
事件的力量:探索Spring框架中的事件处理机制
事件的力量:探索Spring框架中的事件处理机制
28 0
|
16小时前
|
安全 Java 开发者
如何在Spring框架中实现横切关注点的集中管理和重用?
【4月更文挑战第30天】如何在Spring框架中实现横切关注点的集中管理和重用?
5 0
|
4天前
|
Java Spring
Spring Boot脚手架集成校验框架
Spring Boot脚手架集成校验框架
12 0
|
6天前
|
安全 Java 数据库连接
[AIGC] Spring框架的基本概念和优势
[AIGC] Spring框架的基本概念和优势
|
6天前
|
Java Nacos 开发者
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
Java从入门到精通:4.2.1学习新技术与框架——以Spring Boot和Spring Cloud Alibaba为例
|
6天前
|
Dubbo Java 应用服务中间件
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
Java从入门到精通:3.2.2分布式与并发编程——了解分布式系统的基本概念,学习使用Dubbo、Spring Cloud等分布式框架
|
18天前
|
数据采集 前端开发 Java
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
数据塑造:Spring MVC中@ModelAttribute的高级数据预处理技巧
23 3
|
18天前
|
存储 前端开发 Java
会话锦囊:揭示Spring MVC如何巧妙使用@SessionAttributes
会话锦囊:揭示Spring MVC如何巧妙使用@SessionAttributes
14 1
|
18天前
|
前端开发 Java Spring
数据之桥:深入Spring MVC中传递数据给视图的实用指南
数据之桥:深入Spring MVC中传递数据给视图的实用指南
31 3
|
21天前
|
Java 测试技术 Spring
Spring系列文章:Spring集成Log4j2⽇志框架、整合JUnit
Spring系列文章:Spring集成Log4j2⽇志框架、整合JUnit