功能實作02
后端:https://github.com/liyuelian/furniture-back-end.git
前端:https://github.com/liyuelian/furniture-front-end.git
3.功能03-添加家居資訊
3.1需求分析
瀏覽器頁面點擊添加按鈕,彈出提示框,填寫家居資訊,點擊確定,可以把資料添加到資料庫中,
3.2思路分析
- 完成后臺代碼 dao->service->controller,并對每層代碼進行測驗,到controller層使用postman發送http post請求完成測驗
- 完成前端代碼,使用axios 發送ajax請求(json資料)給后臺,實作添加家居資訊
3.3代碼實作
后端專案使用的是 ssm 框架,src 下分為 bean,dao,service,controller,utils層,其中 controller 層由springmvc 接管,service 層由 spring 接管,dao 層由 mybatis 接管,
相比于傳統的 Javaweb 專案,它的三層結構并沒有發生根本變化,僅僅是框架化了,各組件由框架接管,原本的 jsp 則頁面變成了 vue 前端專案,
3.3.1后端代碼
由于使用了逆向工程,bean 層、dao 層以及dao層介面對應的mapper映射檔案已經生成,因此暫時不必在這兩層撰寫代碼了,
(1)Service層,創建對應的介面和實作類
FurnService.java(介面)
package com.li.furn.service;
import com.li.furn.bean.Furn;
/**
* @author 李
* @version 1.0
*/
public interface FurnService {
//添加
public void save(Furn furn);
}
FurnServiceImpl.java(實作類)
package com.li.furn.service.impl;
import com.li.furn.bean.Furn;
import com.li.furn.dao.FurnMapper;
import com.li.furn.service.FurnService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @author 李
* @version 1.0
*/
@Service //注入spring容器
public class FurnServiceImpl implements FurnService {
//自動裝配 FurnMapper介面物件(代理物件)
@Resource
private FurnMapper furnMapper;
//已經在spring組態檔中開啟事務
@Override
public void save(Furn furn) {
furnMapper.insertSelective(furn);
}
}
測驗代碼:
package com.li.furn.test.service;
import com.li.furn.bean.Furn;
import com.li.furn.service.FurnService;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.math.BigDecimal;
/**
* @author 李
* @version 1.0
*/
public class FurnServiceTest {
//spring容器
private ApplicationContext ioc;
//從spring容器中獲取的是FurnService介面的代理物件
private FurnService furnService;
@Before
public void init() {
ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
//通過FurnService.class型別獲取FurnService介面物件的代理物件
furnService = ioc.getBean(FurnService.class);
}
@Test
public void FurnServiceTest() {
//添加資料
Furn furn = new Furn(null, "復古沙發", "森林之家",
new BigDecimal(1088), 12, 28,
"/assets/images/product-image/7.jpg");
furnService.save(furn);
System.out.println("添加成功");
//關閉sqlSession的動作底層會自動釋放
}
}
測驗成功:
(2)關于家居圖片路徑
給新增的家居增加一個默認圖片的路徑值,修改Furn.java(部分代碼):
//默認圖片路徑
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 && !imgPath.equals("")
// =>使用StringUtils.hasText()代替,該方法要求傳入的字串不是null,并且不是"",并且不能全為空格
if (StringUtils.hasText(imgPath)) {
this.imgPath = imgPath;
}
}
(3)bean層創建Msg.java,用來回傳給前端 Json 資料的通用類,本質就是一個”協議“
package com.li.furn.bean;
import java.util.HashMap;
import java.util.Map;
/**
* @author 李
* @version 1.0
* 用來回傳給前端Json資料的通用類
*/
public class Msg {
//狀態碼 200-成功 , 400-失敗
private int code;
//資訊-對回傳的資料的說明
private String msg;
//回傳給瀏覽器的資料-Map集合
private Map<String, Object> extend = new HashMap<>();
//幾個常用的方法-封裝好msg
//回傳一個success的 msg說明
public static Msg success() {
Msg msg = new Msg();
msg.setCode(200);
msg.setMsg("success");
return msg;
}
//回傳一個fail的 msg說明
public 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;//回傳的是當前Msg物件
}
//省略setter,getter方法
}
(4)創建FurnController.java,處理添加家居請求
package com.li.furn.controller;
import com.li.furn.bean.Furn;
import com.li.furn.bean.Msg;
import com.li.furn.service.FurnService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
/**
* @author 李
* @version 1.0
*/
@Controller//由springmvc來處理
public class FurnController {
@Resource
private FurnService furnService;
/**
* 1.回應客戶端添加家居的請求
* 2.@RequestBody 注解將客戶端提交的json資料封裝成 Javabean 物件,
* 3.@ResponseBody 服務器回傳的資料是按照json來回傳的(底層是按照 http協議進行協商)
*
* @param furn
* @return
*/
@ResponseBody
@PostMapping("/save")
public Msg save(@RequestBody Furn furn) {
furnService.save(furn);
//如果沒有出現例外,就回傳成功
Msg success = Msg.success();
return success;
}
}
(5)Postman對Controller層進行測驗
使用postman測驗時,因為我們前臺發送的是json資料,被服務器接收到后,轉成Javabean資料,因此pom.xml需要引入jackson,處理json資料,否則后臺會報錯,
<!--引入jackson--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.4</version> </dependency>
請求結果:


3.3.2前端代碼
(1)修改HomeView.vue頁面,代碼略,
<template>
<div>
<!--增加按鈕和搜索框-->
<div style="margin:10px 5px">
<el-button type="primary" @click="add">新增</el-button>
<el-button>其他</el-button>
</div>
<div style="margin:10px 5px">
<el-input v-model="search" style="width: 30%" placeholder="請輸入關鍵字"/>
<el-button style="margin-left: 10px" type="primary">查找</el-button>
</div>
<!--表格-->
...
<!--添加家居的彈窗
1.el-dialog v-model="dialogVisible" 表示對話框,
和 dialogVisible 變數雙向系結,控制是否顯示對話框
2.el-form:mode="form" 表示表單資料和form資料變數雙向系結
3.el-input v-mode="form.name" 表示表單的input控制元件,
名字為name,必須需要和后端Javabean屬性一致
4.在前端中,物件的屬性是可以動態生成的-->
<el-dialog title="提示" v-model="dialogVisible" >
<el-form :model="form" label->
<el-form-item label="家居名">
<el-input v-model="form.name" style="width: 80%"></el-input>
...
...
</el-form>
<template #footer>
<span >
<el-button @click="dialogVisible=false">取 消</el-button>
<el-button type="primary" @click="save">確 定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import request from '@/utils/request.js'
//匯出組件
export default {
name: 'HomeView',
components: {},
data() {
return {
search: '',
dialogVisible: false,
form: {},//定義一個空表單
tableData: [...]
}
},
methods: {
add() {//顯示添加對話框
//顯示對話框
this.dialogVisible = true;
//每次點擊都要清空上一次的表單資料
this.form = {};
},
save() {//將填寫的表單資料發送給后端
//第一個引數為url,第二個引數是請求攜帶的資料
request.post("/api/save", this.form).then(res => {
console.log("res-", res)
this.dialogVisible = false;//隱藏表單
})
}
}
}
</script>
效果如下:
(2)安裝axios,用于發送ajax請求給后臺
(3)在前端專案的src目錄下創建utlis目錄,utils目錄下創建工具檔案request.js,用于創建axios request物件,發送ajax請求,
//引入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)
})
//匯出request物件,在其他檔案引入即可使用
export default request;
如果啟動前端專案,提示找不到axios,需要把游標放在import axios from ‘axios’ 的提示上,會有一個修復提示,點擊匯入axios即可,
(4)修改HomeView.vue,在methods撰寫save方法,并測驗,
...
save() {//將填寫的表單資料發送給后端
//第一個引數為url,第二個引數是請求攜帶的資料
request.post('http://localhost:8080/save', this.form).then(res => {
console.log("res-", res)
this.dialogVisible = false;//隱藏表單
})
}
...
測驗向后端專案發送請求,因為前后端的服務ip不一致,會出現跨域問題,瀏覽器會阻止訪問:
(5)在專案目錄下的vue.config.js,解決跨域問題
...
module.exports = {
devServer: {
port: 10001,//啟動埠
proxy: {//設定代理,必須填
'/api': {//設定攔截器 攔截器格式
target: 'http://localhost:8080/',//代理的目標地址,就是/api代替的地址
changeOrigin: true,//是否設定同源,如果為true,就允許跨域
pathRewrite: {//路徑重寫
'/api': ''//選擇忽略攔截器里面的單詞
}
}
}
}
}
因為修改了組態檔,npm serve 需要重啟,否則不能識別,
再次測驗,成功發送資料:
3.4注意事項和細節
- 一定要確定request.post("/api/save")被代理后的url是專案后臺服務對應提供的api介面url,否則報404
- postman測驗時,要指定content-type,否則會出錯(415錯誤)
- 如果后端需要將json提交的資料封裝到對應的Javabean中,需要配置@RequestBody,否則會報錯500
- 如果后端需要回傳json資料,需要在方法上配置@ResponseBody,否則會報錯404
4.功能04-顯示家居資訊
4.1需求分析
在頁面中展示資料庫的家居資訊,
4.2思路分析
- 完成后臺代碼從dao-service-controller,并對每層代碼進行測驗
- 完成前臺代碼,使用axios發送http請求,回傳所有家居資料,將資料系結展示
4.3代碼實作
4.3.1后端代碼
分層完成,由于使用了逆向工程,bean 層、dao 層以及dao層介面對應的mapper映射檔案已經生成,因此暫時不必在這兩層撰寫代碼了,
(1)service層,修改FurnService.java和FurnServiceImpl.java,增加findAll()方法,(展示不考慮分頁問題)
FurnService.java:
//查詢所有的家居資訊
public List<Furn> findAll();
FurnServiceImpl.java:
@Override
public List<Furn> findAll() {
//如果傳入為null表示回傳所有的家居資訊
return furnMapper.selectByExample(null);
}
(2)controller層,FurnController.java 處理現實家居的請求
@RequestMapping("/furns")
@ResponseBody
public Msg listFurns() {
List<Furn> furnList = furnService.findAll();
//將資料封裝到 Meg物件中回傳
Msg msg = Msg.success();
msg.add("furnList", furnList);
return msg;
}
(3)postman測驗成功
4.3.2前端代碼
(1)修改src/utils/request.js,增加response攔截器,統一處理回應后的結果
//response攔截器,可以在呼叫介面回應后,統一的處理回傳結果
request.interceptors.response.use(
response => {
let res = response.data;
//如果回傳的是檔案
if (response.config.responseType === 'blob') {
return res;
}
//如果回傳的是string,就轉成json物件
if (typeof res === 'string') {
//如果不為空,就轉成json物件
res = res ? JSON.parse(res) : res;
}
return res;
}, error => {
//如果失敗
console.log("err=", error);
return Promise.reject(error);
})
(2)修改HomeView.vue,當現實頁面之前就發出請求,然后將接收的資料顯示到頁面上
<template>
<div>
...
<!--表格顯示家居新-->
<el-table :data="https://www.cnblogs.com/liyuelian/archive/2023/03/08/tableData" stripe style="width: 90%">
<el-table-column prop="id" label="ID" sortable></el-table-column>
<el-table-column prop="name" label="家居名"></el-table-column>
...
...
<el-table-column fixed="right" label="操作" >
<template #default="scope">
<el-button link type="primary" size="small"
@click="handleEdit(scope.row)">編輯
</el-button>
<el-button link type="primary" size="small">洗掉</el-button>
</template>
</el-table-column>
</el-table>
...
</div>
</template>
<script>
import request from '@/utils/request.js'
//匯出組件
export default {
name: 'HomeView',
components: {},
data() {
return {
search: '',
dialogVisible: false,
form: {},//定義一個空表單
tableData: []
}
},
created() {//生命周期函式
this.list();
},
methods: {
add() {//顯示添加對話框
...
},
save() {//將填寫的表單資料發送給后端
request.post("/api/save", this.form).then(res => {
console.log("res-", res)
this.dialogVisible = false;
//呼叫list方法,重繪頁面顯示的資料
this.list();
})
},
list() {//list方法,請求回傳家居資訊,當我們打開頁面的時候,該方法就應該自動觸發
request.get("/api/furns").then(res => {//res已經經過攔截器的處理>res=res.data
//根據res的結構來獲取資料
this.tableData = https://www.cnblogs.com/liyuelian/archive/2023/03/08/res.extend.furnList;
})
}
}
}
</script>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/546189.html
標籤:其他
下一篇:專案中多級快取設計實踐總結
