(10)Ajax
Ajax
是一种不需要刷新整个网页就可以实现局部更新的技术
当我们在搜索栏输入字母的时候就会有一个响应,并没有刷新页面,提高了我们的效率
下面我们新建一个项目
首先导入依赖文件设置过滤器,添加web模块,配置Artfacts的lib
一个好的习惯能避免很多错误。
然后就是web.xml中DispatcherServlet的注册。
<?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"
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>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>enocodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>enocodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
以上就是DispatcherServlet和过滤器的配置
下面配置applicationContext.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
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- <!– 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 –>-->
<context:component-scan base-package="com.kang.Controller"/>
<!-- <!– 让Spring MVC不处理静态资源 –>-->
<mvc:default-servlet-handler />
<mvc:annotation-driven />
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
写个Controller测试一下环境有没有问题
package com.kang.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AjaxController {
@RequestMapping("/welcome")
public String welconme(){
return "index";
}
}
@RestController返回一个字符串
一定记得把ApplicationContext设置为/,这样就可以避免我们要输入冗长的工程名。
成功访问。
我们先使用iframe模拟一下如何实现无刷新更新页面信息。
写个前端练练手
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iframe页面无刷新</title>
<script>
function go(){
var url=document.getElementById("url").value;
document.getElementById("iframel").src=url;
}
</script>
</head>
<body>
<div>
<p>请输入地址</p>
<input type="text" id="url" value="www.baidu.com">
<input type="button" value="提交" onclick="go()">
</div>
<div>
<iframe id="iframel" style="width: 100%; height: 500px"></iframe>
</div>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iframe页面无刷新</title>
<script>
function go(){
var url=document.getElementById("url").value;
document.getElementById("iframel").src=url;
}
</script>
</head>
<body>
<div>
<p>请输入地址</p>
<input type="text" id="url" value="www.baidu.com">
<input type="button" value="提交" onclick="go()">
</div>
<div>
<iframe id="iframel" style="width: 100%; height: 500px"></iframe>
</div>
</body>
</html>
上面的html程序实现了通过输入框输入地址通过js程序赋值给iframe的src属性实现页面的转跳,这就搭建了一个类似于jQuery的小窗,他的特点就是不需要刷新页面就可以实现内容的变动
我们通过iframe也可以实现这种类似于jQuery的小窗;
我们下面学习一下正统的jQuery,首先,去jquery官网下载一个js文件
在这里选另存为就获得我们的jQuery文件了
这样我们就导入了jQuary文件。我们用jQuary’实现异步请求就是在失去焦点的时候发送一个请求
例如,百度的搜索框
当我们打开这个文件就可以看到他相应的信息就是我们下拉框弹出的信息
说明我们在输入的时候浏览器就执行了事件,所以我们的目的就是像他一样,在失去焦点或者获得焦点的时候执行一个事件。
下面让我们来实现这个功能,首先配置静态资源的过滤,才能在运行的时候加载我们的jQuery文件。
<!-- <!– 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 –>-->
<context:component-scan base-package="com.kang.Controller"/>
<!-- <!– 让Spring MVC不处理静态资源 –>-->
<mvc:default-servlet-handler />//过滤静态资源
<mvc:annotation-driven />
我们要使用jQuery就要先研究一下他的方法
<head>
<title>$Title$</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
$.post()
</script>
</head>
用绝对地址导入我们的jQuery文件,"$"符号与”jQuery"是等价的
$.post()
jQuery.post()
两种写法是意义一样$能简化我们的开发,关于post方法,我们产看一下他的源码
jQuery.each( [ "get", "post" ], function( _i, method ) {
jQuery[ method ] = function( url, data, callback, type ) {//指定请求方式
// Shift arguments if data argument was omitted
if ( isFunction( data ) ) {
type = type || callback;
callback = data;
data = undefined;
}
// The url can be an options object (which then must have .url)
return jQuery.ajax( jQuery.extend( {
url: url,//地址,就是我们的Controller的地址
type: method,//传递的方式
dataType: type,//数据类型
data: data,//数据
success: callback//成功以后要执行的函数
}, jQuery.isPlainObject( url ) && url ) );
};
} );
我们来使用一下这个方法。首先我们写一个Controller来响应接受的数据。
@RequestMapping("/a1")
public void a1(String name, HttpServletResponse response) throws IOException {
System.out.println("name=>"+name);
if ("KangKing".equals(name)){
response.getWriter().println("true");
}else{
response.getWriter().println("false");
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
function a(){
$.post({
url:"${pageContext.request.contextPath}/a1",//指定发送请求的地址
data:{"name":$("#name").val()},//要传递的数据,用$获取下面的name
success:function (data) {
alert(data);//用弹窗输出返回的数据就是Controller的逻辑判断。
}
})
}
</script>
</head>
<body>
<input type="text" id="name" onblur="a()">
</body>
</html>
在输入信息之后我们不需要提交就自动执行了方法用弹窗实现了响应。如果报错jQuery找不到就去applicationContext下面检查静态资源是否导入,即<mvc:default-servlet-handler />,然后下面我们梳理下。
我们通过焦点时间来调用a()函数通过ajax来实现前后端的分离,通过post或者get方式将参数传递给后端,后端进行业务处理,最后返回
信息,这样就实现了前后端的分离。
由此我们可以让后端返回一个json对象,吧具体的显示这些任务交给前端,让ajax来解析字符串。
首先我们创建一个user对象,让后让Controller来返回json字符串给前端。我们在前端接受这个字符串。
比如说在前端绘制一个表格来接收和展示数据。
创建对象:
package com.kang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
String name;
int age;
String sex;
}
Controller
@RequestMapping("/a2")
public List<User> a2(){
ArrayList<User> userList = new ArrayList<>();
userList.add(new User("小明",1,"男"));
userList.add(new User("小黄",1,"男"));
userList.add(new User("小蓝",1,"女"));
return userList;
}
成功返回字符串,然后我们让前端接受一下;
我们通过对一个按钮绑定一个点击事件来过去数据
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
$(function () {
$("#btn").click(function () {
$.post("${pageContext.request.contextPath}/a2",function (data){
console.log(data)
})
})
});
</script>
</head>
<body>
<input type="button" id="btn">
<table>
<tr>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
</tr>
</table>
</body>
</html>
当我们点击按钮的时候就会触发click事件,向/a1发送post请求返回我们的数组信息,然后打印
注:$.post(url,param(可省略),success){}这是一种简化的定义方式
在这里我们就成功获取到了后端发送的数据,下一步就是把它放进表格里面。
我们在这里使用对html页面的追加,就是在页面后面再及一段html代码
<script>
$(function () {
$("#btn").click(function () {
$.post("${pageContext.request.contextPath}/a2",function (data){
var html="";
for(let i=0;i<data.length;i++){
html+="<tr>"+
"<td>"+data[i].name+"</td>"+
"<td>"+data[i].age+"</td>"+
"<td>"+data[i].sex+"</td>"+
"</tr>"
}
$("#context").html(html);
})
})
});
</script>
我们在for循环里面用到的let是JavaScript6版本新特性,它可以定义局部变量,确保我们数据的准确性
这样我们就实现的对id名为context的tbody的追加信息
我们再来写一个实例,比如说我们在注册新账号的时候我们输入的密码后面会动态的显示我们,输入的是否合法,比如说
我们在注册的时候我们并没有提交,但是他就实现了校验,我们来实现这个功能。
首先新建jsp文件
<body>
<p>
用户名:<input type="text" id="userName" onblur="a()"><span id="nameId"></span>
</p>
<p>
密码:<input type="text" id="pwd" onblur="b()"><span id="pwdId"></span>
</p>
</body>
两个输入框,后面跟的标签来实现我们的内容的追加。
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
function a() {
$.post({
url: "${pageContext.request.contextPath}/login",
data: {"name":$("#userName").val()},
success:function (data) {
console.log(data);
if(data.toString()==="OK"){
$("#nameId").css("color","green");
}else{
$("#nameId").css("color","red");
}
$("#nameId").html(data);
}
})
}
function b(){
$.post({
url: "${pageContext.request.contextPath}/login",
data: {"pwd":$("#pwd").val()},
success:function (data) {
console.log(data);
if(data.toString()==="OK"){
$("#pwdId").css("color","green");
}else{
$("#pwdId").css("color","red");
}
$("#pwdId").html(data);
}
})
}
</script>
用jQuery对后台发送post请求。进行逻辑判断,将返回的数据追加到span中
@RequestMapping("/login")
public String login(String name,String pwd){
if(name!=null){
if("admin".equals(name)){
return "OK";
}else {
return "输入错误";
}
}
if(pwd!=null){
if("admin".equals(pwd)){
return "OK";
}else {
return "输入错误";
}
}
return "hh";
}
}
在后台进行逻辑判断,返回是否合法;
成功实现。
注意:
- 在获取数据的时候不要缺少"#“会导致取不到数据如data: {“pwd”😒(”#pwd").val()}
- 如果出现乱码可以配置乱码过滤器,详见百宝箱中JSON格式乱码的配置。