在我的上一篇文章:
前言
详细描述了一个web项目的增删改查操作怎么去实现,在前端页面中我们定义form表单,输入text文本信息,再提交表单,数据信息便会传入表单的action指定的资源路径中(servlet层中),再通过req.getParameter(" name")方法获取url中指定的属性值。
接下来我详细记录一下如何使用ajax和vue来实现数据的传递与接收
一,ajax+vue展示所有用户
1.1 创建数据库smbms以及用户表smbms_user
/*
Navicat Premium Data Transfer
Source Server : localhost_3306
Source Server Type : MySQL
Source Server Version : 80028
Source Host : localhost:3306
Source Schema : smbms
Target Server Type : MySQL
Target Server Version : 80028
File Encoding : 65001
Date: 06/04/2023 21:14:48
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for smbms_user
-- ----------------------------
DROP TABLE IF EXISTS `smbms_user`;
CREATE TABLE `smbms_user` (
`id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`userCode` varchar(15) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '用户编码',
`userName` varchar(15) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '用户名称',
`userPassword` varchar(15) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL COMMENT '用户密码',
`gender` int(0) NULL DEFAULT NULL COMMENT '性别(1:女、 2:男)',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 112 CHARACTER SET = utf8 COLLATE = utf8_unicode_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of smbms_user
-- ----------------------------
INSERT INTO `smbms_user` VALUES (2, 'admin', '管理员', '123456', 0);
INSERT INTO `smbms_user` VALUES (5, 'hanlubiao', '韩路彪', '0000000', 0);
INSERT INTO `smbms_user` VALUES (6, 'zhanghua', '张华', '0000000', 1);
INSERT INTO `smbms_user` VALUES (7, 'wangyang', '王洋', '123', 0);
INSERT INTO `smbms_user` VALUES (8, 'zhaoyan', '赵燕', '0000000', 1);
INSERT INTO `smbms_user` VALUES (10, 'sunlei', '孙磊', '0000000', 0);
INSERT INTO `smbms_user` VALUES (12, 'zhangchen', '张晨', '0000000', 1);
INSERT INTO `smbms_user` VALUES (13, 'dengchao', '邓超', '0000000', 0);
INSERT INTO `smbms_user` VALUES (14, 'yangguo', '杨过', '0000000', 0);
SET FOREIGN_KEY_CHECKS = 1;
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (2, 'admin', '管理员', '123456', 0);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (5, 'hanlubiao', '韩路彪', '0000000', 0);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (6, 'zhanghua', '张华', '0000000', 1);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (7, 'wangyang', '王洋', '123', 0);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (8, 'zhaoyan', '赵燕', '0000000', 1);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (10, 'sunlei', '孙磊', '0000000', 0);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (12, 'zhangchen', '张晨', '0000000', 1);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (13, 'dengchao', '邓超', '0000000', 0);
INSERT INTO `smbms_user`(`id`, `userCode`, `userName`, `userPassword`, `gender`) VALUES (14, 'yangguo', '杨过', '0000000', 0);
1.2 创建实体类User
@Data
@NoArgsConstructor
@AllArgsConstructor //lombok插件
public class User {
@JSONField(ordinal = 1) //字段排序
private Integer id; //id
@JSONField(ordinal = 2)
private String userCode; //用户编码
@JSONField(ordinal = 3)
private String userName; //用户名称
@JSONField(ordinal = 4)
private String userPassword; //用户密码
@JSONField(ordinal = 5)
private Integer gender; //性别
}
1.3 ajax+vue前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script
src="https://cdn.bootcss.com/vue/2.5.17-beta.0/vue.min.js"></script>
<script src="js/jquery-2.1.0.min.js">
</script>
<title>Title</title>
<style> //样式
table, tr, td, th {
border: 1px black solid;
}
td {
text-align: center;
}
table {
width: 600px;
margin: auto;
}
</style>
</head>
<body>
<div id="app">
<button @click="getStudentInfo">显示用户列表
</button>
<table>
<tr>
<th>ID</th>
<th>userCode</th>
<th>userName</th>
<th>gender</th>
</tr>
<tr v-for="stu in studentList"> //遍历用户集合studentList,每个用户是一个stu
<td v-for="(value, key) in stu" v-if="key =='gender'"> //遍历stu的各个属性
{{value ? '女' : '男'}} //数据库中的gender字段的值为0或1,而我们需要显现出来的是男和女
</td>
<td v-else>{{value}}</td> //gender以外字段数据遍历
</tr>
</table>
</div>
<script>
var v1 = new Vue({
el: "#app", //对应div:app
data: {
studentList: "", //vue的属性,上面表格中遍历的数据就是这个
},
methods: {
getStudentInfo: function () { //通过@click按钮调用该方法,从而调用ajax
ajaxGetStudentInfo();
}
}
});
function ajaxGetStudentInfo() {
$.ajax({
url: "http://localhost:8080/loginServlet?method=allUsers", //数据传递到的资源路径
data: {}, //传递到上面url资源路径时携带的数据
type: "get", //请求方式
dataType: "json", //明确后端返回来得资源的格式是json字符串
success: function (ret) { //成功的操作,ret是后端后端返回的数据
v1.studentList = ret; //将后端返回的数据传给vue的studentList 属性
},
error: function () { //失败后的操作
alert("无数据");
}
})
}
</script>
</body>
</html>
1.4 dao层
public class UserDaoImpl extends BaseDao implements UserDao {
@Override
public List<User> getAllUsers() throws SQLException {
String sql = "select id,userCode,userName,gender from smbms_user"; //所有用户列表
List<User> users = super.queryBeanList(sql, User.class);
return users;
}
}
baseDao工具类放下自取
工具类
密码:skr8
接口对着实现类自己写
1.5 service层
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl();
@Override
public List<User> allUsers() throws SQLException {
List<User> allUsers = userDao.getAllUsers();
return allUsers;
}
}
1.6 servlet层
@WebServlet("/loginServlet") //资源路径
public class LoginServlet extends BaseServlet { //继承封装包,无论在多的方法功能都可以写在一个Servlet中,极大的简化代码
UserService userService= new UserServiceImpl();
public String allUsers(HttpServletRequest req, HttpServletResponse resp) throws SQLException {
List<User> mapList = userService.allUsers();
String s = JSON.toJSONString(mapList); //将List集合转化为字符串
System.out.println(s);
return s;
}
}
这个方法名是关键,你可以研究下BaseServlet封装包,他可以根据前端传来的url中的method属性值来调用指定的方法。
具体说明查看我的上一篇文章BaseServlet封装
1.7 BaseServlet封装包
package com.shop.util;
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
/**
* 1. 所有的 Servlet 程序都可以使用当前 BaseServlet 统一管理和简化操作
* 2. 具备针对于 下层 Servlet 反馈的数据处理能力
* 【分为两种】
* a. 用户提交的数据 ==> JSON 反馈
* b. 特定字符串前缀:
* "forward:XXX" 转发
* "redirect:XXX" 重定向
*
* @author Anonymous 2023/3/29 15:02
*/
public abstract class BaseServlet extends HttpServlet {
@Override
protected void service (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 通过 Request 对象,获取 method 对应的参数情况
try {
// 2. 通过当前名称获取对应的方法,并且执行。
Object returnValue = this.getClass ()
.getMethod (req.getParameter ("method"), HttpServletRequest.class, HttpServletResponse.class)
.invoke (this, req, resp);
if (null == returnValue) {
return;
}
resp.setContentType ("application/json;charset=utf-8");
PrintWriter writer = resp.getWriter ();
if (returnValue instanceof String) {
// 针对于 下层 Servlet 返回结果为 String 字符串的处理方式
String value = (String) returnValue;
if (value.startsWith ("forward:")) {
// 转发操作
req.getRequestDispatcher (value.substring (value.indexOf (":") + 1)).forward (req, resp);
/*
int i = value.indexOf(":");
String forward = value.substring(i + 1);
req.getRequestDispatcher(forward).forward(req, resp);
*/
} else if (value.startsWith ("redirect:")) {
// 执行重定向操作
resp.sendRedirect (value.substring (value.indexOf (":") + 1));
} else {
writer.write (value);
}
//}
//else if (returnValue instanceof Boolean) {
// resp.setContentType ("text/html;charset=utf-8");
} else {
// 针对于 下层 Servlet 返回结果为其他类型
writer.write (JSON.toJSONString (returnValue));
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace ();
}
}
}
关键的也是基本用到的都是最后一种情况
else {
// 针对于 下层 Servlet 返回结果为其他类型
writer.write (JSON.toJSONString (returnValue)); //将returnValue转为json字符串格式返回到前端,就是那个ret
}
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace ();
}