Axios
概述
Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。其实就是用来做异步的
特性
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
使用
首先进行项目搭建,创建一个Spring Boot项目,作为后台,在创建一个web项目,做前台
编写后台controller
@RestController
@RequestMapping("/user")
public class CustomerController {
/**
由于spring的RequestParam注解接收的参数是来自于requestHeader中,即请求头,
也就是在url中,格式为xxx?username=123&password=456,
而RequestBody注解接收的参数则是来自于requestBody中,即请求体中。
综上所述:当我们接收get请求时使用@RequestParam
接收post请求时使用@RequestBody
*/
@GetMapping("/findAll")
@CrossOrigin //用来处理跨域请求
public List<Customer> findAll(Integer id){
System.out.println(id);
List<Customer> list=new ArrayList<>();
list.add(new Customer("zs", 23, 178));
list.add(new Customer("ls", 24, 287));
list.add(new Customer("ww", 25, 199));
return list;
}
@PostMapping("/save")
@CrossOrigin
public Map<String,Object> save(@RequestBody String info){
System.out.println(info);
Map<String,Object> map=new HashMap<>();
map.put("name", "zs");
map.put("age", 23);
map.put("height", 178);
return map;
}
}
接着在另一个项目中创建html文件,引入vue和axios的cdn
<!--vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--axios-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
使用axios发送get请求,参数是请求url,
then
函数用来处理响应结果
<script>
//发送get请求
axios.get('http://localhost:8080/user/findAll?id=1').then(function (response) {
console.log(response);
})
</script>
使用axios发送post请求,
post
方法的第一个参数是请求url,第二个参数是你要传输到后台的数据,catch函数是用来处理异常的
<script>
axios.post('http://localhost:8080/user/save',{
name: 'ls',
age: 24,
height: 178
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
})
</script>
使用axios发送并发请求,也就是同时发出两条请求
<script>
function findAll() {
//这里需要返回,all那里才能接收到响应结果
return axios.get('http://localhost:8080/user/findAll?id=1')
}
function save() {
return axios.post('http://localhost:8080/user/save',{
name: 'ww',
age: 29,
height: 189
})
}
axios.all([findAll(),save()])
.then(axios.spread(function (resp1,resp2) {//spread将多个请求的响应结果汇总处理
console.log(resp1);
console.log(resp2);
}))
</script>
案例1
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--引入bootstrap的核心css文件-->
<link rel="stylesheet" href="boot/css/bootstrap.min.css"/>
</head>
<body>
<div class="container-fluid" id="app">
<form class="form-inline">
<div class="form-group">
<div class="input-group">
<span class="input-group-addon">城市</span>
<!--
@keyup.delete:当我们按回退的时候不显示
-->
<input type="text" class="form-control" v-model="name" @keyup.delete="notShow"/>
</div>
<!--阻止自动提交表单,按enter提交-->
<button class="btn btn-default" @click.prevent="searchCity" @keyup.enter="searchCity">搜索</button>
</div>
</form>
<div class="row">
<span v-for="city in hotCities">
<!--阻止自动跳转-->
<a @click.prevent="searchCity2(city)">{{city}}</a>
</span>
</div>
<div class="row" v-show="isShow">
<span>{{name}},今天的天气情况:{{message}}</span>
</div>
</div>
<!--vue-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!--axios-->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
name: "",
message: "",
isShow: false,
hotCities: [
'北京',
'上海',
'天津',
'深圳'
]
},
methods: {
searchCity() {
//获取要搜索的城市
console.log(this.name);
let _this=this;
//发送axios请求
axios.get('http://localhost:8080/city/find?name='+this.name)
.then(function (response) {
_this.message = response.data.message;
_this.isShow = true;
}).catch(function (error) {
console.log(error);
})
},
notShow() {
this.isShow = false;
},
searchCity2(name) {
this.name = name;
this.searchCity();
}
}
})
</script>
</body>
</html>
案例2(用户管理)
当前案例结合vue+bootstrap+springboot+mybatis+mysql制作
首先,创建数据库bootvue,建表t_user
CREATE TABLE `t_user` (
`id` varchar(50) NOT NULL,
`name` varchar(30) NOT NULL,
`age` int(3) NOT NULL,
`salary` double(7,2) NOT NULL,
`phone` varchar(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建SpringBoot项目,导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
</dependencies>
目录结构如下:
配置文件如下:
server:
port: 8888
# servlet:
# context-path: /user
spring:
application:
name: user
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/bootvue?characterEncoding=UTF-8
username: root
password: 123456
# 指定路径时才用classpath
mybatis:
mapper-locations: classpath:com/hzp/mapper/*.xml
type-aliases-package: com.hzp.entity
用户页面代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户管理界面</title>
<!--bootstrap css-->
<link rel="stylesheet" href="./bootvue/css/bootstrap.min.css"/>
</head>
<body>
<div id="app">
<!--导航条-->
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">用户管理系统</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">欢迎xxx</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<!--搜索框-->
<div class="container-fluid">
<div class="row">
<div class="col-sm-8">
<form class="form-inline">
<div class="form-group">
<label class="sr-only" for="username">姓名</label>
<div class="input-group">
<div class="input-group-addon">姓名</div>
<input type="text" class="form-control" id="username" placeholder="请输入姓名" v-model="name" @keyup.enter="search">
</div>
</div>
<div class="form-group">
<label for="phone" class="sr-only">邮箱</label>
<div class="input-group">
<div class="input-group-addon">号码</div>
<input type="text" class="form-control" id="phone" placeholder="请输入号码" v-model="phone" @keyup.enter="search"/>
</div>
</div>
<!--
@click.prevent:阻止表单自动提交
-->
<button type="submit" class="btn btn-primary" @click.prevent="search">搜索</button>
</form>
</div>
</div>
</div>
<!--表格-->
<div class="container-fluid" style="margin-top: 20px">
<div class="row">
<div class="col-sm-8">
<table class="table table-striped table-bordered table-hover table-condensed">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>年龄</th>
<th>薪资</th>
<th>手机</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="user of users" :key="user.id">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.age}}</td>
<td>{{user.salary}}</td>
<td>{{user.phone}}</td>
<td><button class="btn btn-danger" @click="deleteUser(user.id)">删除</button> <button @click="findOne(user.id)" class="btn btn-primary">修改</button></td>
</tr>
</tbody>
</table>
</div>
<!--表单-->
<div class="col-sm-4">
<form>
<div class="form-group">
<label for="uname">姓名</label>
<input type="text" class="form-control" id="uname" placeholder="请输入姓名" v-model="user.name">
</div>
<div class="form-group">
<label for="age">年龄</label>
<input type="text" class="form-control" id="age" placeholder="请输入年龄" v-model="user.age">
</div>
<div class="form-group">
<label for="salary">薪资</label>
<input type="text" class="form-control" id="salary" placeholder="请输入薪资" v-model="user.salary">
</div>
<div class="form-group">
<label for="uphone">手机号码</label>
<input type="text" class="form-control" id="uphone" placeholder="请输入手机号码" v-model="user.phone">
</div>
<button type="button" class="btn btn-primary" @click="saveUser">提交</button>
<button type="button" class="btn btn-danger" @click="reset">重置</button>
</form>
</div>
</div>
</div>
</div>
<!--vue js-->
<script src="./bootvue/js/vue.js"></script>
<!--axios js-->
<script src="./bootvue/js/axios.min.js"></script>
<script>
const app = new Vue({
el: "#app",
data: {
users: [], //用于接收数据库中的用户信息
user: {}, //用来完成双向的数据绑定
name: '', //和搜索框的内容进行绑定
phone: '',
},
methods:{
search() {
let _this=this;
axios.get('http://localhost:8888/user/findByNamePhone?name='+this.name+'&phone='+this.phone)
.then(function (response) {
console.log(response.data);
//更新表格中显示的内容
_this.users = response.data;
})
},
saveUser() {
let _this=this;
//使用axios发送post请求
axios.post('http://localhost:8888/user/save',this.user)
.then(function (response) {
console.log(response.data);
if (response.data.success){
_this.findAll();//添加后要更新列表
//清空表单
_this.user={};
}else{
alert(response.data.message);
}
}).catch(function (error) {
console.log(error);
})
},
findAll() {
let _this=this;
//请求用户数据
axios.get('http://localhost:8888/user/findAll')
.then(function (response) {
console.log(response.data);
_this.users = response.data
}).catch(function (error) {
console.log(error);
})
},
reset() {
//清空表单信息
this.user={};
},
deleteUser(id) {
let _this=this;
axios.get('http://localhost:8888/user/delete?id='+id)
.then(function (response) {
if (response.data.success){
//更新列表
_this.findAll();
} else {
alert(response.data.message);
}
}).catch(function (error) {
console.log(error.data);
})
},
//通过id查询到用户并进行回显
findOne(id){
// for (user of this.users){
// if (user.id == id){
// //回显
// this.user=user;
// }
// }
let _this=this;
axios.get('http://localhost:8888/user/findOne?id='+id).then(function (response) {
console.log(response.data);
//将查询到的用户进行回显
_this.user=response.data;
}).catch(function (error) {
console.log(error.data);
})
}
},
created() {
this.findAll();
}
})
</script>
</body>
</html>
User实体类
package com.hzp.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
/**
* @ClassName User
* @Description
* @Author HuangZhaoPeng
* @Date 2020/10/15 14:51
* @Version 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Accessors(chain = true) //setter方法将会返回当前对象
public class User {
private String id;
private String name;
private Integer age;
private Double salary;
private String phone;
}
UserDao接口
package com.hzp.dao;
import com.hzp.entity.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @ClassName UserDao
* @Description
* @Author HuangZhaoPeng
* @Date 2020/10/15 14:56
* @Version 1.0
*/
public interface UserDao {
//查询所有用户
List<User> findAll();
//添加用户
void save(User user);
//删除用户
void delete(String id);
//更新用户
void update(User user);
//查询单个
User findOne(String id);
/**
* 模糊查询
* @param name
* @param phone
* @return
* 如果是传入多个参数,需要使用@Param指定,要不然会报
* org.apache.ibatis.binding.BindingException: Parameter 'name' not found.
*/
List<User> findByNamePhone(@Param("name") String name, @Param("phone") String phone);
}
UserDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hzp.dao.UserDao">
<select id="findAll" resultType="User">
select * from t_user;
</select>
<insert id="save" parameterType="User">
insert into t_user value (#{id},#{name},#{age},#{salary},#{phone})
</insert>
<delete id="delete" parameterType="java.lang.String">
delete from t_user where id=#{id}
</delete>
<update id="update" parameterType="User">
update t_user
set name=#{name},age=#{age},salary=#{salary},phone=#{phone}
where id=#{id}
</update>
<select id="findOne" parameterType="java.lang.String" resultType="User">
select * from t_user where id=#{id}
</select>
<select id="findByNamePhone" resultType="User">
select * from t_user
<where>
<if test="name!=''">
name like concat('%',#{name},'%')
</if>
<if test="phone!=''">
or phone like concat('%',#{phone},'%')
</if>
</where>
</select>
</mapper>
UserService接口
package com.hzp.service;
import com.hzp.entity.User;
import java.util.List;
/**
* @ClassName UserService
* @Description
* @Author 19806
* @Date 2020/10/15 15:14
* @Version 1.0
*/
public interface UserService {
//查询所有
List<User> findAll();
//添加
void save(User user);
//删除
void delete(String id);
//更新
void update(User user);
//查询单个
User findOne(String id);
//模糊查询
List<User> findByNamePhone(String name,String phone);
}
UserServiceImpl
package com.hzp.service;
import com.hzp.dao.UserDao;
import com.hzp.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.UUID;
/**
* @ClassName UserServiceImpl
* @Description
* @Author HuangZhaoPeng
* @Date 2020/10/15 15:16
* @Version 1.0
*/
@Service
@Transactional //支持事务
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public List<User> findAll() {
return userDao.findAll();
}
@Override
public void save(User user) {
user.setId(UUID.randomUUID().toString());
userDao.save(user);
}
@Override
public void delete(String id) {
userDao.delete(id);
}
@Override
public void update(User user) {
userDao.update(user);
}
@Override
public User findOne(String id) {
return userDao.findOne(id);
}
@Override
public List<User> findByNamePhone(String name, String phone) {
return userDao.findByNamePhone(name, phone);
}
}
UserController类代码如下:
package com.hzp.controller;
import com.hzp.entity.User;
import com.hzp.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @ClassName UserController
* @Description
* @Author HuangZhaoPeng
* @Date 2020/10/15 15:23
* @Version 1.0
*/
@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/findAll")
public List<User> findAll(){
return userService.findAll();
}
@PostMapping("/save")
public Map<String,Object> save(@RequestBody User user){
Map<String,Object> map=new HashMap<>();
try{
//如果用户有id则是修改
if (!StringUtils.isEmpty(user.getId())){
userService.update(user);
}else{
userService.save(user);
}
map.put("success", true);
return map;
}catch (Exception e){
map.put("success", false);
map.put("message", "保存用户失败");
return map;
}
}
@GetMapping("/delete")
public Map<String,Object> delete(String id){
Map<String,Object> map=new HashMap<>();
try{
userService.delete(id);
map.put("success", true);
return map;
}catch (Exception e){
map.put("success", false);
map.put("message", "删除失败");
return map;
}
}
@GetMapping("/findOne")
public User findOne(String id){
return userService.findOne(id);
}
@GetMapping("/findByNamePhone")
public List<User> findByNamePhone(String name,String phone){
return userService.findByNamePhone(name, phone);
}
}