SpringBoot +axios 结合发送ajax
1.搭建环境
1.1 创建表并添加数据
DROP TABLE t_posts;
CREATE TABLE IF NOT EXISTS t_posts(
pid INT PRIMARY KEY AUTO_INCREMENT,
author VARCHAR(20) NOT NULL DEFAULT '海康',
title VARCHAR(50) NOT NULL DEFAULT '中国人民'
)ENGINE=INNODB DEFAULT CHARSET=utf8;
1.2 创建SpringBOot 项目
1.3 相关数据库配置:
server:
port: 80
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/crud?characterEncoding=utf-8&useSSL=false
username: root
password: root
POJO 类
package com.haikang.axios.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Post implements Serializable {
private Integer pid;
private String author;
private String title;
}
统一数据响应类
package com.haikang.axios.pojo;
import lombok.Data;
import java.io.Serializable;
@Data
public class JsonResult<E> implements Serializable {
private Integer state;
private String message;
private E date;
public JsonResult() {
}
public JsonResult(Integer state) {
this.state = state;
}
public JsonResult(Throwable e) {
this.message = e.getMessage();
}
public JsonResult(Integer state, E date) {
this.state = state;
this.date = date;
}
public JsonResult(Integer state, String message, E date) {
this.state = state;
this.message = message;
this.date = date;
}
}
1.4 测试
创建index.html 页面,并且需要引入axios 文件
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js"></script>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>index页面</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<script>
console.log(axios);
</script>
</body>
</html>
打开页面访问http://localhost/ :在控制台中出现说明测试成功
2.axios 基本使用
API | 描述 |
---|
axios(config) | config 中需要接收一个对象类型的参数,可以指定相关的配置信息 |
2.1 使用axios(config) 发送GET 请求
前端页面:
let bnts = document.getElementsByTagName("button");
bnts[0].onclick = ()=>{
axios({
method:'GET',
url:'http://localhost:80/axios/posts'
}).then(
(value)=>{
console.log(value);
},
(reason)=>{
console.log(reason);
}
);
}
Dao 层的编写
Mapper 接口
@Mapper
public interface PostMapper {
List<Post> getAllPosts();
}
xml 文件
<select id="getAllPosts" resultType="Post">
select * from t_posts;
</select>
Service 层
PostService 接口
public interface PostService {
List<Post> getPosts();
}
PostServiceImpl 实现类
@Service
public class PostServiceImpl implements PostService {
@Autowired
private PostMapper postMapper;
@Override
public List<Post> getPosts() {
return postMapper.getAllPosts();
}
}
controller 层
package com.haikang.axios.controller;
import com.haikang.axios.pojo.Post;
import com.haikang.axios.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/axios")
public class AxiosController {
@Autowired
private PostService postService;
@RequestMapping("/posts")
public List<Post> posts(){
return postService.getPosts();
}
}
返回结果
2.2 使用axios(config) 发送POST 请求
案例:使用POST 请求添加用户信息
bnts[1].onclick = ()=>{
axios({
method: 'POST',
url:'http://localhost:80/axios/posts',
data:{
"title": "haikang",
"author": "haiknag人民",
}
}).then(
(value)=>{
console.log(value);
},
(reason)=>{
console.log(reason);
}
);
}
dao 层
mapper 接口
@Mapper
public interface PostMapper {
Integer addPost(Post post);
}
xml 文件
<insert id="addPost" useGeneratedKeys="true" keyProperty="pid">
insert into t_posts (author,title) value(#{author},#{title});
</insert>
service 层
service 接口
public interface PostService {
Integer addPost(Post post);
}
service 实现类
@Service
public class PostServiceImpl implements PostService {
@Autowired
private PostMapper postMapper;
@Override
public Integer addPost(@RequestBody Post post) {
return postMapper.addPost(post);
}
}
controller 层
@RestController
@RequestMapping("/axios")
public class AxiosController {
private static final Integer OK = 200;
@Autowired
private PostService postService;
@PostMapping("/posts")
public JsonResult addPost(@RequestBody Post post){
System.out.println(post);
return new JsonResult(OK,postService.addPost(post));
}
}
响应数据:
2.3使用axios(config) 发送PUT 请求
**案例:**修改Post 信息
bnts[2].onclick = ()=>{
axios({
method:'PUT',
url:'http://localhost:80/axios/posts',
data:{
"pid":10,
"title": "西安",
"author": "haiknag人民"
}
}).then(
(value)=>{
console.log(value);
},
(reason)=>{
console.log(reason);
}
);
}
dao 层
Mapper 接口
@Mapper
public interface PostMapper {
Integer updatePost(Post post);
}
xml 文件
<update id="updatePost">
update t_posts set author=#{author},title=#{title} where pid=#{pid}
</update>
service 层
public interface PostService {
Integer updatePost(Post post);
}
controller 层
package com.haikang.axios.controller;
import com.haikang.axios.pojo.JsonResult;
import com.haikang.axios.pojo.Post;
import com.haikang.axios.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/axios")
public class AxiosController {
private static final Integer OK = 200;
@Autowired
private PostService postService;
@PutMapping("/posts")
public JsonResult updatePost(@RequestBody Post post){
return new JsonResult(OK,postService.updatePost(post));
}
}
响应结果:
2.4 使用axios(config) 发送DELETE 请求
案例:根据pid 删除post 信息
bnts[3].onclick = ()=>{
axios({
method:'DELETE',
url:'http://localhost:80/axios/posts',
params: {
pid: 10
}
}).then(
(value)=>{
console.log(value);
},
(reason)=>{
console.log(reason);
}
);
}
dao 层
mapper 接口
@Mapper
public interface PostMapper {
Integer deletePost(@Param("pid") Integer pid);
}
xml 文件
<delete id="deletePost">
delete from t_posts where pid=#{pid}
</delete>
service 层
接口:a
Integer deletePost(Integer pid);
实现类:
@Override
public Integer deletePost(Integer pid) {
return postMapper.deletePost(pid);
}
contorller 层
@DeleteMapping("/posts")
public JsonResult deletePost(Integer pid){
System.out.println(pid);
return new JsonResult(OK,postService.deletePost(pid));
}
响应结果:
3.axios 其他方法发送ajax 请求
在[] 括号中表示是不是必须的,上述的这些方法也可以发送ajax 请求
注意是:config 表示是需要一个对象类型的参数
3.1.axios.request(config) 方法
使用axios.request(config) 方法发送ajax请求,也是需要一个对象类型的参数,使用方式和上面的基本使用一致也需要一个对象类型参数
bnts[4].onclick = ()=>{
axios.request({
method:'GET',
url:'http://localhost:80/axios/posts'
}).then(
(value)=>{
console.log(value);
},
(reason)=>{
console.log(reason);
}
);
}
3.2 axios.get(url[,config]) 方法
config 表示是需要一个对象类型的参数,get 和delete 的使用一致
bnts[5].onclick = ()=>{
axios.get(
'http://localhost:80/axios/posts/1',).then(
(value)=>{
console.log(value);
},
(reason)=>{
console.log(reason);
});
}
3.3 axios.post(url[,data[,config]]) 方法
注意是:data 表示是请求体,post 和put 的使用一致
bnts[6].onclick = ()=>{
axios.post(
'http://localhost:80/axios/posts',
{
title: '菜菜的程序员',
author:'明天'
}).then(
(value)=>{
console.log(value);
},
(reason)=>{
console.log(reason);
}
);
}
注意是:config 是一个配置对象,对象是{} 包裹着
5.config 配置对象介绍
config 就是上述需要使用config 对象,可以设置那些属性
{
url: '/user',
method: 'get',
baseURL: 'https://some-domain.com/api/',
transformRequest: [function (data, headers) {
return data;
}],
transformResponse: [function (data) {
return data;
}],
headers: {'X-Requested-With': 'XMLHttpRequest'},
params: {
ID: 12345
},
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
data: {
firstName: 'Fred'
},
data: 'Country=Brasil&City=Belo Horizonte',
timeout: 1000,
withCredentials: false,
adapter: function (config) {
},
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
responseType: 'json',
responseEncoding: 'utf8',
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
onUploadProgress: function (progressEvent) {
},
onDownloadProgress: function (progressEvent) {
},
maxContentLength: 2000,
maxBodyLength: 2000,
validateStatus: function (status) {
return status >= 200 && status < 300;
},
maxRedirects: 5,
socketPath: null,
httpAgent: new http.Agent({ keepAlive: true }),
httpsAgent: new https.Agent({ keepAlive: true }),
proxy: {
protocol: 'https',
host: '127.0.0.1',
port: 9000,
auth: {
username: 'mikeymike',
password: 'rapunz3l'
}
},
cancelToken: new CancelToken(function (cancel) {
}),
decompress: true
}
常用设置:
-
url :用于请求的服务器url -
method :是创建请求时使用的方法,默认是get -
baseURL :可以通过设置一个baseURL 便于axios 实例的方法传递相对url ,如:baseURL:'https://some-domain.com/api/' -
params : 是与请求一起发送的url 参数,必须是一个简单对象或URLSearchParams 对象 params:{
ID:123
},
-
data :是作为请求体被发送数据, 仅适用 ‘PUT’, ‘POST’, 'DELETE 和 ‘PATCH’ 请求方法 data: {
firstName:'haikang'
},
6.axios 默认配置
axios 默认配置常用默认配置有:
axios.defaults.method 设置默认请求类型axios.defaults.baseURL 设置基础的URL axios.defaults.timeout 超时时间
<script>
const btns = document.querySelectorAll('button');
axios.defaults.method = 'GET';
axios.defaults.baseURL = 'http://localhost:3000';
axios.defaults.params = {id:100};
axios.defaults.timeout = 3000;
btns[0].onclick = function(){
axios({
url: '/posts'
}).then(response => {
console.log(response);
})
}
</script>
7.axios 创建实例对象发送请求
就是通过axios 对象创建实例来发送请求,作用就是为我们方便使用
使用和axios一致
<script>
const haikang = axios.create({
baseURL:'http://localhost:3000/',
timeout:2000
});
haikang.get(
'/posts/3'
).then(Response=>{
console.log(Response);
});
</script>
8.拦截器
在请求或响应被then 或catch 处理前拦截它们
如果你稍后需要移除拦截器,可以这样:
可以给自定义的axios 实例添加拦截器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>拦截器</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<script>
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 1号');
config.params = {a:100};
return config;
}, function (error) {
console.log('请求拦截器 失败 - 1号');
return Promise.reject(error);
});
axios.interceptors.request.use(function (config) {
console.log('请求拦截器 成功 - 2号');
config.timeout = 2000;
return config;
}, function (error) {
console.log('请求拦截器 失败 - 2号');
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 1号');
return response.data;
}, function (error) {
console.log('响应拦截器 失败 1号')
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
console.log('响应拦截器 成功 2号')
return response;
}, function (error) {
console.log('响应拦截器 失败 2号')
return Promise.reject(error);
});
axios({
method: 'GET',
url: 'http://localhost:3000/posts'
}).then(response => {
console.log('自定义回调处理成功的结果');
console.log(response);
});
</script>
</body>
</html>
多个拦截器执行流程是:后加先执行,2号是后添加的
这样执行的原因:
var chain = [dispatchRequest, undefined];
var promise = Promise.resolve(config);
this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
chain.unshift(interceptor.fulfilled, interceptor.rejected);
});
this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {
chain.push(interceptor.fulfilled, interceptor.rejected);
});
9.取消请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>取消请求</title>
<link crossorigin='anonymous' href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<div class="container">
<h2 class="page-header">axios取消请求</h2>
<button class="btn btn-primary"> 发送请求 </button>
<button class="btn btn-warning" > 取消请求 </button>
</div>
<script>
const btns = document.querySelectorAll('button');
let cancel = null;
btns[0].onclick = function(){
if(cancel !== null){
cancel();
}
axios({
method: 'GET',
url: 'http://localhost:3000/posts',
cancelToken: new axios.CancelToken(function(c){
cancel = c;
})
}).then(response => {
console.log(response);
cancel = null;
})
}
btns[1].onclick = function(){
cancel();
}
</script>
</body>
</html>
|