SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--后端实现

目录

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--后端实现

技术栈

实现功能04-添加家居信息

需求分析/图解

思路分析

代码实现

创建\service\FurnService.java 和\service\FurnServiceImpl.java, 增加添加方法

修改Furn.java , 当创建Furn 对象imgPath 为null 时, imgPath 给默认值 

创建FurnServiceTest.java ,测试方法

创建Msg.java用来返回json 的数据的通用类

创建FurnController.java , 处理添加请求

使用Postman 来完成Controller 层的测试, 通过Postman 添加Furn 数据

点击添加按钮, 可以出现添加家居的对话框, 修改

完成测试: 看看点击新增按钮,能否正常的弹窗添加家居的对话框(含有表单)

项目前端安装axios, 用于发送Ajax 请求给后台, 一定要注意 

创建工具文件D:\idea_java_projects\ssm_vue\src\utils\request.js , 用于创建axios 

修改HomeView.vue , 在methods 编写save 方法, 并测试会出现跨域问题

创建vue.config.js 解决跨域问题, 因为修改了配置文件

修改Home.vue, 使用跨域请求, 并完成测试, 查看数据库,是否有新数据添加成功

注意事项和细节

实现功能05-显示家居信息

需求分析/图解

 思路分析

代码实现 

 FurnService.java

 FurnServiceImpl

修改FurnServiceTest.java ,测试findAll.

修改FurnController.java , 处理显示请求, 并使用Postman 完成测试

修改HomeView.vue , 编写list 方法

 完成测试,看看是否可以显示家居列表信息.

修改src\utils\request.js 增加response 拦截器, 统一处理响应后结果 

 修改Home.vue , 简化返回处理

 完成测试.

实现功能06-修改家居信息 

需求分析/图解 

思路分析

 代码实现

修改FurnService.java接口 

修改FurnServiceImpl.java

修改FurnServiceTest.java ,测试update

修改FurnController.java , 处理修改请求, 并使用Postman 完成测试

 修改HomeView.vue , 编写handleEdit 方法, 回显数据并测试

可以测试一下, 点击编辑, 回显数据

修改HomeView.vue , 修改save 方法,

完成测试

实现功能07-删除家居信息

需求分析/图解

思路分析

代码实现

修改FurnService.java接口 

修改FurnServiceImpl.java

修改FurnServiceTest.java ,测试del

修改FurnController.java , 处理删除请求, 并使用Postman 完成测试

修改HomeView.vue , 编写handleDel 方法, 完成删除

 完成测试测试

将修改家居信息功能, 回显家居表单数据, 改成从后端-DB 获取 

修改FurnService.java接口 

修改FurnServiceImpl.java

修改FurnServiceTest.java ,处理根据id返回对应的furn对象 

 修改FurnController.java , 处理根据id返回对应的furn对象, 并使用Postman 完成测试

 修改HomeView.vue , 编写handleEdit 第二种方法, 回显数据并测试 

实现功能08-分页显示列表

需求分析/图解

 思路分析

代码实现

1. 修改pom.xml 加入分页插件

2. 修改mybatis-config.xml, 配置分页拦截器

3. 修改FurnController.java 增加分页查询处理

修改FurnServiceTest.java ,测试分页查询是否OK 

使用Postman 进行测试,看看分页查询是否OK 

修改HomeView.vue , 完成分页导航显示、分页请求 

增加element-plus 分页控件 

完成测试

分页显示效果

实现功能09-带条件查询分页显示列表

需求分析/图解​编辑

 思路分析

代码实现

修改FurnService.java接口 

修改FurnServiceImpl.java

修改FurnController.java , 处理带条件分页查询 

修改FurnServiceTest.java ,测试条件分页查询是否OK  

 使用Postman 测试,是否通过

修改HomeView.vue , 完成带条件分页查询

 测试分页条件查询

 实现功能10-添加家居表单前端校验

说明: 参考element-plus 表单验证

思路分析

代码实现

修改HomeView.vue , 增加表单验证处理代码

测试

修改Homeview.vue 当表单验证不通过时,不提交表单 

完成测试

 实现功能11-添加家居表单后端校验

 需求分析/图解

 2. 后端校验-需求分析, 当后端校验没有通过,会出现灰色框提示, 后台不真正入库数据

思路分析

代码实现

1. 修改pom.xml 引入hibernate-validator jar 文件 

 2. 修改Furn.java , 使用hibernate-validator

 3. 修改FurnController.java , 对save 方法进行完善

4. 修改HomeView.vue , 显示服务器校验返回的提示信息

完成测试: 添加家居表单后端校验

测试页面效果 

测试完毕后, 记得恢复valid 的正确写法 


SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--后端实现

技术栈

SSM 项目【前后端分离】

- 说明: 前后端分离开发, 前端框架Vue + 后端框架SSM
1. 前端框架Vue
2. 后台框架-SSM(SpringMVC+Spring+MyBatis)
3. 数据库-MySQL
4. 项目的依赖管理-Maven
5. 分页-pagehelper。
6. 逆向工程-MyBatis Generator。
7. 其它...

-前端框架Vue
1. 使用了ElementPlus 来展示数据。
2. 使用Axios 对象来请求数据/走接口。

-后端框架SSM
1. 使用经典的三层结构。
2. 使用MyBatis Generator 和MyBatis pageHelper。

实现功能04-添加家居信息

需求分析/图解

 

思路分析

1. 完成后台代码从dao -> serivce -> controller , 并对每层代码进行测试, 到controller 这一层,使用Postman 发送http post 请求完成测试
2. 完成前端代码, 使用axios 发送ajax(json 数据)给后台, 实现添加家居信息 

代码实现

创建\service\FurnService.java 和\service\FurnServiceImpl.java, 增加添加方法

 FurnService接口

public interface FurnService {//添加public void save(Furn furn);
}

FurnServiceImpl 

@Service
public class FurnServiceImpl implements FurnService {//注入/装配FurnMapper接口对象(代理对象)@Resourceprivate FurnMapper furnMapper;@Overridepublic void save(Furn furn) {//解读//1. 使用insertSelective//2. 因为我们的furn表的id是自增的,就使用insertSelectivefurnMapper.insertSelective(furn);}

修改Furn.java , 当创建Furn 对象imgPath 为null 时, imgPath 给默认值 

private String imgPath = "assets/images/product-image/1.jpg";
public Furn(Integer id, String name, String maker, BigDecimal price,Integer sales, Integer stock, String imgPath) {
                this.id = id;
                this.name = name;
                this.maker = maker;
                this.price = price;
                this.sales = sales;
                this.stock = stock;
                if(!(imgPath == null || imgPath.equals("")) ){
                this.imgPath = imgPath;
        }
}

创建FurnServiceTest.java  测试方法

public class FurnServiceTest {//属性private ApplicationContext ioc;//从spring容器中,获取的是FurnService接口对象/代理对象private FurnService furnService;@Beforepublic void init() {ioc = new ClassPathXmlApplicationContext("applicationContext.xml");//说明//1. 通过FurnService.class 类型获取 FurnService接口对象/代理对象furnService = ioc.getBean(FurnService.class);//com.sun.proxy.$Proxy21System.out.println("furnService-" + furnService.getClass());}@Testpublic void save() {Furn furn =new Furn(null, "小风扇", "wyx家居", new BigDecimal(180), 10,70, "assets/images/product-image/1.jpg");furnService.save(furn);System.out.println("添加成功~");}
}

创建Msg.java用来返回json 的数据的通用类

package com.wyxdu.furn.bean;import java.util.HashMap;
import java.util.Map;/*** Msg: 后端程序返回给前端的json数据的Msg对象=》本质就是数据规则*/
public class Msg {//状态码 200-成功 400-失败private int code;//信息-说明private String msg;//返回给客户端/浏览器的数据-Map集合private Map extend =new HashMap<>();//编写几个常用的方法-封装好msg//返回success对应的msgpublic static Msg success() {Msg msg = new Msg();msg.setCode(200);msg.setMsg("success");return msg;}//返回fail对应的msgpublic static Msg fail() {Msg msg = new Msg();msg.setCode(400);msg.setMsg("fail");return msg;}//给返回的msg设置数据-不难应该可以看懂public Msg add(String key, Object value) {extend.put(key, value);return this;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public Map getExtend() {return extend;}public void setExtend(Map extend) {this.extend = extend;}
}

创建FurnController.java , 处理添加请求

@Controller
public class FurnController {//注入配置FurnService@Resourceprivate FurnService furnService;/*** 解读* 1、响应客户端的添加请求* 2、@RequestBody: 使用 SpringMVC 的 @RequestBody 将客户端提交的 json 数据,封装成 JavaBean 对象* 3、@ResponseBody: 服务器返回的数据格式是按照 json 来返回的(底层是按照http协议进行协商)*/@PostMapping("/save")@ResponseBodypublic Msg save(@RequestBody Furn furn) {furnService.save(furn);return Msg.success();}

使用Postman 来完成Controller 层的测试, 通过Postman 添加Furn 数据

使用Postman 测试时,因为我们前台是发送的json 数据,被服务器接收到后,转成javabean 数据,因此pom.xml 需要引入jackson,处理json 数据,

否则后台会报错.Content type 'application/json;charset=UTF-8' not supported


com.fasterxml.jackson.corejackson-databind2.12.4

 

点击添加按钮, 可以出现添加家居的对话框, 修改

SSM-Vue 整合项目\HomeView.vue ,

说明el-dialog 从Dialog 对话框获取, 表单代码从Form 表单获取,组合一下并调整一下即可






//增加数据, 一定要, 否则你会发现,在后面弹出的表单不能输入数据
data() {return {form: {},
//注意这个因为是前端架子的测试数据太长了就没有展示了如果想要数据
//麻烦去看看架子搭建 然后把data补全 如果不想代表话就把大括好补全 
//这里是少了2给大括号的
//增加方法
methods: {add() {this.dialogVisible = truethis.form = {}}
}
//增加点击新增的按钮事件
新增其它

如图所示 

 

 

完成测试: 看看点击新增按钮,能否正常的弹窗添加家居的对话框(含有表单)

项目前端安装axios, 用于发送Ajax 请求给后台, 一定要注意 

 

创建工具文件D:\idea_java_projects\ssm_vue\src\utils\request.js , 用于创建axios 

// 引入axios 包
// 重要提示:如果在启动前端项目,提示找不到axios , 把光标放在import axios from 'axios' 的'axios', 会有一个修复提示, 导入axios, 小伙伴点击, 导入即可正常使用
import axios from 'axios'
// 通过axios 创建对象
const request = axios.create({timeout: 5000
})
// request 拦截器
// 1. 可以对请求做一些处理
// 2. 比如统一加token,Content-Type 等
request.interceptors.request.use(config => {config.headers['Content-Type'] = 'application/json;charset=utf-8';return config
}, error => {return Promise.reject(error)
});
//导出
export default request

修改HomeView.vue , 在methods 编写save 方法, 并测试会出现跨域问题

创建vue.config.js 解决跨域问题, 因为修改了配置文件

npm serve 需要重启, 否则不能识别.

const {defineConfig} = require('@vue/cli-service')
module.exports = defineConfig({transpileDependencies: true
})
module.exports = {devServer: {port: 10000, // 启动端口//解读如果我们请的地址 /api/save => 代理到 http://localhost:8080/ssm/saveproxy: {                    //设置代理,必须填'/api': {               //设置拦截器  拦截器格式   斜杠+拦截器名字,名字可以自己定target: 'http://localhost:8080/ssm',  //代理的目标地址, 就是/api 代替 http://localhost:10001/changeOrigin: true,                 //是否设置同源,输入是的, 浏览器就允许跨域pathRewrite: {                      //路径重写'/api': ''                      //选择忽略拦截器里面的单词}}}}
}

修改Home.vue, 使用跨域请求, 并完成测试, 查看数据库,是否有新数据添加成功

1. 将form 表单提交给/api/save 的接口

2. /api/save 等价http∶//locaLhost∶10001/save

3. 如果成功,就进入then 方法

4.res 就是返回的信息

5.查看mysql 看看数据是否保存

request.post("/api/save", this.form).then(res => {console.log(res)this.dialogVisible = false})
}

提醒, 这里容易出现的问题

1) 一定要确定request.post("/api/save") 被代理后的url , 是项目后台服务对应提供的API接口url ,  否则报404

2) 当跨域执行时请求,浏览器还是提示http://localhost:5927/api/xxx , 所以不要认为是api没有替换你的配置.

注意事项和细节

1. Postman 测试时, 要指定content-type ,否则会报错415

2. 如果需要将提交的json 数据, 封装到对应的Javabean, 需要配置@RequestBody , 否则会报错500

3. 如果需要返回json 数据, 需要在方法上, 配置@ResponseBody , 否则会报错404 


实现功能05-显示家居信息

需求分析/图解

 思路分析

1. 完成后台代码从dao -> serivce -> controller , 并对每层代码进行测试
2. 完成前台代码, 使用axios 发送http 请求,返回所有家居数据, 将数据绑定显示

代码实现 

修改FurnService.java 和FurnServiceImpl.java, 增加findAll 方法 

 FurnService.java

    //查询所有的家居信息public List findAll();

 FurnServiceImpl

  @Overridepublic List findAll() {//查看分析FurnMapper.xml 文件//传入是null, 表示返回所有的家居信息return furnMapper.selectByExample(null);}

修改FurnServiceTest.java ,测试findAll.

 @Testpublic void findAll() {List furns = furnService.findAll();for (Furn furn : furns) {System.out.println("furn-" + furn);}}

修改FurnController.java , 处理显示请求, 并使用Postman 完成测试

    @RequestMapping("/furns")@ResponseBodypublic Msg listFurns() {List furnList = furnService.findAll();//Msg msg = Msg.success();把家居信息,封装到msg对象//msg.add("furnList", furnList);return Msg.success().add("furnList", furnList);}

修改HomeView.vue , 编写list 方法

//修改一下el-table


//修改一下tableData: []data() {return {form: {},dialogVisible: false,search: '',tableData: []}
}
//在created() 调用list() 完成页面数据获取
created() {this.list()
}
//编写list() method
list() { //请求显示家居列表-带检索request.get("/api/furns").then(res => {//绑定tableData, 显示在表格this.tableData = res.data.extend.furnsList})
}
//在save() 调用后,调用list() 刷新页面
save() {// =======说明====...request.post("/api/save", this.form).then(res => {console.log(res)this.dialogVisible = falsethis.list()})
}

 完成测试,看看是否可以显示家居列表信息.

 

修改src\utils\request.js 增加response 拦截器, 统一处理响应后结果 

//引入axios
import axios from "axios";
//通过axios创建对象-request对象,用于发送请求到后端
const request = axios.create({timeout: 5000
})//request拦截器的处理
//1. 可以对请求做统一的处理
//2. 比如统一的加入token, Content-Type等
request.interceptors.request.use(config => {config.headers['Content-Type'] = 'application/json;charset=utf-8'return config
}, error => {return Promise.reject(error)
})//response拦截器
//可以在调用接口响应后,统一的处理返回结果
request.interceptors.response.use(response => {let res = response.data//如果返回的是文件,就返回if (response.config.responseType === 'blob') {return res}//如果是string, 就转成json对象if (typeof res === 'string') {//如果res 不为null, 就进行转换成json对象res = res ? JSON.parse(res) : res}return res;},error => {console.log("err", error)return Promise.reject(error);}
)//导出request对象, 在其它文件就可以使用
export default request

 修改Home.vue , 简化返回处理

 完成测试.


实现功能06-修改家居信息 

需求分析/图解 

思路分析

1. 完成后台代码从dao -> serivce -> controller , 并对每层代码进行测试
2. 完成前台代码, 回显家居信息,再使用axios 发送http / ajax 请求,更新数据, 将数据绑定显示 

 代码实现

修改FurnService.java接口 和FurnServiceImpl.java, 增加update 方法

修改FurnService.java接口 

    //修改家居public void update(Furn furn);

修改FurnServiceImpl.java

    @Overridepublic void update(Furn furn) {furnMapper.updateByPrimaryKeySelective(furn);}

修改FurnServiceTest.java ,测试update

 @Testpublic void update() {Furn furn = new Furn();furn.setId(1);furn.setName("北欧风格小桌子~~");furn.setMaker("小猪家居");//因为imgPath属性有一个默认值,//所以如果我们不希望生成update 语句有对imgPath 字段修改,就显式的设置nullfurn.setImgPath(null);furnService.update(furn);System.out.println("修改OK");}

修改FurnController.java , 处理修改请求, 并使用Postman 完成测试

   @PutMapping("/update")@ResponseBodypublic Msg update(@RequestBody Furn furn) {furnService.update(furn);return Msg.success();}

 修改HomeView.vue , 编写handleEdit 方法, 回显数据并测试

handleEdit(row) {//说明//1. JSON.stringify(row) 将row 转成json 字符串//2. JSON.parse(xx) 将字符串转成json 对象//3. 为什么这样做? 其实JSON.parse(JSON.stringify(row)) 就是对row 进行了深拷贝//4. 这样表格中的行数据和弹出框的数据就是独立的了this.form = JSON.parse(JSON.stringify(row))this.dialogVisible = true}//触发handleEdit 方法编辑

可以测试一下, 点击编辑, 回显数据

修改HomeView.vue , 修改save 方法,

处理修改请求, 说明更新成功的消息框, 不需要做额外处理, 直接使用this.$message 即可.

save() {//增加处理修改逻辑if (this.form.id) {request.put("/api/update", this.form).then(res => {if (res.code === 200) {//如果code 为200this.$message({ //弹出更新成功的消息框type: "success",message: "更新成功"})} else {this.$message({//弹出更新失败信息type: "error",message: res.msg})}this.list() //刷新列表this.dialogVisible = false})} else {//添加//=======说明======//1. 将form 表单提交给/api/save 的接口//2. /api/save 等价http://localhost:10001/save//3. 如果成功,就进入then 方法//4. res 就是返回的信息//5. 查看Mysql 看看数据是否保存request.post("/api/save", this.form).then(res => {this.dialogVisible = falsethis.list()})}
}

完成测试

浏览器http://localhost:10000


实现功能07-删除家居信息

需求分析/图解

思路分析

1. 完成后台代码从dao -> serivce -> controller , 并对每层代码进行测试
2. 完成前台代码,使用axios 发送http Ajax 请求,删除数据, 将数据绑定显示

代码实现

修改FurnService.java 和FurnServiceImpl.java, 增加del 方法

修改FurnService.java接口 

    //删除家居public void del(Integer id);


修改FurnServiceImpl.java

    @Overridepublic void del(Integer id) {furnMapper.deleteByPrimaryKey(id);}

修改FurnServiceTest.java ,测试del

    @Testpublic void del() {furnService.del(17);System.out.println("删除OK");}

修改FurnController.java , 处理删除请求, 并使用Postman 完成测试

    @DeleteMapping("/del/{id}")@ResponseBodypublic Msg del(@PathVariable Integer id) {furnService.del(id);return Msg.success();}

修改HomeView.vue , 编写handleDel 方法, 完成删除

//处理删除方法
handleDel(id) {request.delete("/api/del/" + id).then(res => {if (res.code === 200) {this.$message({type: "success",message: "删除成功"})} else {this.$message({type: "error",message: res.msg})}this.list() // 刷新列表})
}//响应删除点击//增加分页初始化数据data() {return {currentPage: 1,pageSize: 5,total: 10,//修改list(), 换成分页请求数据list() { //请求显示家居列表-不带检索request.get("/api/furnsByPage", {params: {pageNum: this.currentPage,pageSize: this.pageSize}}).then(res => {//绑定tableData, 显示在表格this.tableData = res.extend.pageInfo.listthis.total = res.extend.pageInfo.total})}
//增加方法, 处理记录的变化, 这两个方法是和分页控件绑定的.
//处理每页显示多少条记录变化
handlePageSizeChange(pageSize) {this.pageSize = pageSizethis.list()},//处理当前页变化, 比如点击分页连接,或者go to 第几页handleCurrentChange(pageNum) {this.currentPage = pageNumthis.list()}

完成测试

启动项目后台服务furns_ssm
启动项目前台ssm_vue
浏览器: http://localhost:10000/

分页显示效果

● 测试分页显示效果, 浏览器: http://localhost:10000/


实现功能09-带条件查询分页显示列表

需求分析/图解

 思路分析

1. 完成后台代码从dao -> serivce -> controller , 并对每层代码进行测试
2. 完成前台代码,使用axios 发送http 请求,完成带条件查询分页显示

代码实现

修改FurnService.java 和FurnServiceImpl.java , 增加条件查询

修改FurnService.java接口 

    //根据家居名称进行查询public List findByCondition(String name);

修改FurnServiceImpl.java

 @Overridepublic List findByCondition(String name) {FurnExample furnExample = new FurnExample();//通过Criteria 对象可以设置查询条件FurnExample.Criteria criteria = furnExample.createCriteria();//判断name是有具体的内容if (StringUtils.hasText(name)) {criteria.andNameLike("%" + name + "%");}//说明:如果name没有传值null ,"", "   ", 依然是查询所有的记录return furnMapper.selectByExample(furnExample);}

修改FurnController.java , 处理带条件分页查询 

 /*** 根据家居名进行分页查询-条件** @param pageNum* @param pageSize* @return*/@ResponseBody@RequestMapping("/furnsByConditionPage")public Msg listFurnsByConditionPage(@RequestParam(defaultValue = "1") Integer pageNum,@RequestParam(defaultValue = "5") Integer pageSize,@RequestParam(defaultValue = "") String search) {PageHelper.startPage(pageNum, pageSize);List furnList = furnService.findByCondition(search);PageInfo pageInfo = new PageInfo(furnList, pageSize);//将pageInfo封装到Msg对象,返回return Msg.success().add("pageInfo", pageInfo);}

    @Testpublic void findByCondition() {List furns = furnService.findByCondition("风格");for (Furn furn : furns) {System.out.println("furn--" + furn);}}

修改FurnServiceTest.java ,测试条件分页查询是否OK  

    @Testpublic void findByCondition() {List furns = furnService.findByCondition("风格");for (Furn furn : furns) {System.out.println("furn--" + furn);}}

 使用Postman 测试,是否通过

修改HomeView.vue , 完成带条件分页查询

========增加搜索区========== 

< !--功能区域-->新增
< !--搜索区域-->检索

 ===========在数据池,增加search 变量=====

 ==========修改list 方法,请求带条件分页的API 接口===

 测试分页条件查询


 实现功能10-添加家居表单前端校验

说明: 参考element-plus 表单验证

思路分析

1. 完成前台代码,使用ElementPlus 的表单rules 验证即可
2. 参考ElementPlus 的表单验证文档 

代码实现

修改HomeView.vue , 增加表单验证处理代码

==========增加对表单各个字段的校验规则=========

tableData: [],rules: {name: [{ required: true, message: '请输入称家居名', trigger: 'blur' }],maker: [{ required: true, message: '请输入称制造商', trigger: 'blur' }],price: [{ required: true, message: '请输入价格', trigger: 'blur' },{ pattern: /^(([1-9]\d*)|(0))(\.\d+)?$/, message: '请输入数字', trigger: 'blur' }],sales: [{ required: true, message: '请输入销量', trigger: 'blur' },{ pattern: /^(([1-9]\d*)|(0))$/, message: '请输入数字', trigger: 'blur' }],stock: [{ required: true, message: '请输入库存', trigger: 'blur' },{ pattern: /^(([1-9]\d*)|(0))$/, message: '请输入数字', trigger: 'blur' }]
}

==========指定将创建的规则应用到form 表单, 注意名称要对应=========
 添加家居的弹窗
说明:
1. el-dialog :v-model="dialogVisible" 表示对话框, 和dialogVisible 变量双向绑定,控制是否显示对话框

2. el-form :model="form" 表示表单,数据和form 数据变量双向绑定

3. el-input v-model="form.name" 表示表单的input 空间, 名字为name 需要和后台Javabean 属性一致

测试

就可以看到验证规则生效了【是光标离开输出框时,出现校验效果,因为是trigger:'blur' 事件】, 但是用户提交还是能成

修改Homeview.vue 当表单验证不通过时,不提交表单 

========修改save()===========

save() {//增加处理修改逻辑if (this.form.id) {request.put("/api/update", this.form).then(res => {if (res.code === 200) {//如果code 为200this.$message({ //弹出更新成功的消息框type: "success",message: "更新成功"})} else {this.$message({//弹出更新失败信息type: "error",message: res.msg})}this.list() //刷新列表this.dialogVisible = false})} else {//添加//表单数据校验是否this.$refs['form'].validate((valid) => {if (valid) {//=======说明======//1. 将form 表单提交给/api/save 的接口//2. /api/save 等价http://localhost:10001/save//3. 如果成功,就进入then 方法//4. res 就是返回的信息//5. 查看Mysql 看看数据是否保存request.post("/api/save", this.form).then(res => {this.dialogVisible = falsethis.list()})} else {this.$message({//弹出更新失败信息type: "error",message: "验证失败,不提交"})return false}})}
}

===========修改add()============

add() {this.dialogVisible = truethis.form = {}this.$refs['form'].resetFields()//将添加验证提示消息,清空
}

完成测试


 实现功能11-添加家居表单后端校验

 需求分析/图解

1. 为什么前端校验了,后端还需要校验?-看使用Postman 添加数据, 破前端校验机制... 

 

 

 2. 后端校验-需求分析, 当后端校验没有通过,会出现灰色框提示, 后台不真正入库数据

思路分析

1. 后台使用JSR303 数据校验,引入hibernate-validator.jar ,在SpringMVC的博客有详细的 链接 
2. 前台使用ElementPlus 进行数据绑定,并显示错误信息 

代码实现

1. 修改pom.xml 引入hibernate-validator jar 文件 


org.hibernatehibernate-validator6.1.0.Final

 2. 修改Furn.java , 使用hibernate-validator

package com.wyxdu.furn.bean;import org.hibernate.validator.constraints.Range;
import org.springframework.util.StringUtils;import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;public class Furn {private Integer id;@NotEmpty(message = "请输入家居名")private String name;@NotEmpty(message = "请输入制造厂商")private String maker;@NotNull(message = "请输入数字")@Range(min = 0, message = "价格不能小于0")private BigDecimal price;@NotNull(message = "请输入数字")@Range(min = 0, message = "销量不能小于0")private Integer sales;@NotNull(message = "请输入数字")@Range(min = 0, message = "库存不能小于0")private Integer stock;//说明: 修改Furn.java ,// 当创建Furn对象 imgPath 为null时, imgPath 给默认值(默认图片路径)private String imgPath = "assets/images/product-image/1.jpg";//增加一个全参构造器public Furn(Integer id, String name, String maker, BigDecimal price, Integer sales, Integer stock, String imgPath) {this.id = id;this.name = name;this.maker = maker;this.price = price;this.sales = sales;this.stock = stock;//解读//如果imgPath 不为null ,而且是有数据,就设置给 this.imgPath,否则就使用默认值//imgPath != null && !imgPath.equals("") =>使用一个工具类方法完成/*** public static boolean hasText(@Nullable String str) {*         return str != null && !str.isEmpty() && containsText(str);*     }*///StringUtils.hasText(imgPath) 就是要求imgPath 不是 null ,而且不是"", 而且不是"     "//该方法后面小伙伴会常常使用if (StringUtils.hasText(imgPath)) {this.imgPath = imgPath;}}//声明无参构造器public Furn() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name == null ? null : name.trim();}public String getMaker() {return maker;}public void setMaker(String maker) {this.maker = maker == null ? null : maker.trim();}public BigDecimal getPrice() {return price;}public void setPrice(BigDecimal price) {this.price = price;}public Integer getSales() {return sales;}public void setSales(Integer sales) {this.sales = sales;}public Integer getStock() {return stock;}public void setStock(Integer stock) {this.stock = stock;}public String getImgPath() {return imgPath;}public void setImgPath(String imgPath) {this.imgPath = imgPath == null ? null : imgPath.trim();}@Overridepublic String toString() {return "Furn{" +"id=" + id +", name='" + name + '\'' +", maker='" + maker + '\'' +", price=" + price +", sales=" + sales +", stock=" + stock +", imgPath='" + imgPath + '\'' +'}';}
}

 3. 修改FurnController.java , 对save 方法进行完善
 

   @PostMapping("/save")@ResponseBodypublic Msg save(@Validated @RequestBody Furn furn, Errors errors) {Map map = new HashMap<>();List fieldErrors = errors.getFieldErrors();for (FieldError fieldError : fieldErrors) {map.put(fieldError.getField(), fieldError.getDefaultMessage());}if (map.isEmpty()) {//说明后端校验通过,因为没有发现校验错误furnService.save(furn);//返回成功msgreturn Msg.success();} else {//校验失败,把校验错误信息封装到Msg对象,并返回return Msg.fail().add("errorMsg", map);}}

4. 修改HomeView.vue , 显示服务器校验返回的提示信息

===========在数据池,增加显示错误信息变量========

data() {return {//存放错误信息serverValidErrors: {},

================修改save()方法,显示错误提示============

save() {//增加处理修改逻辑if (this.form.id) {request.put("/api/update", this.form).then(res => {if (res.code === 200) {//如果code 为200this.$message({ //弹出更新成功的消息框type: "success",message: "更新成功"})} else {this.$message({//弹出更新失败信息type: "error",message: res.msg})}this.list() //刷新列表this.dialogVisible = false})} else {//添加//表单数据校验是否this.$refs['form'].validate((valid) => {if (valid) {//=======说明======//1. 将form 表单提交给/api/save 的接口//2. /api/save 等价http://localhost:10001/save//3. 如果成功,就进入then 方法//4. res 就是返回的信息//5. 查看Mysql 看看数据是否保存request.post("/api/save", this.form).then(res => {if (res.code === 200) {this.dialogVisible = falsethis.list()} else if (res.code === 400) {this.serverValidErrors.name = res.extend.errorMsg.name;this.serverValidErrors.sales = res.extend.errorMsg.sales;this.serverValidErrors.price = res.extend.errorMsg.price;this.serverValidErrors.maker = res.extend.errorMsg.maker;this.serverValidErrors.stock = res.extend.errorMsg.stock;}})} else {this.$message({//弹出更新失败信息type: "error",message: "验证失败,不提交"})return false}})}
}

==========修改add()方法,清空错误信息=========

add() {this.dialogVisible = truethis.form = {}this.$refs['form'].resetFields()//将上传验证消息,清空this.serverValidErrors = {}},

========修改对话框,显示后台返回的校验错误信息========


{{ serverValidErrors.name }}{{ serverValidErrors.maker }}{{ serverValidErrors.price }}{{ serverValidErrors.sales }}{{ serverValidErrors.stock }}

完成测试: 添加家居表单后端校验

2、这时, 后台返回添加失败的提示信息 

启动项目前台ssm_vue 

浏览器: http://localhost:10000/

测试页面效果 

测试完毕后, 记得恢复valid 的正确写法 

本项目就已经全部完成


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部