項目概述、環(huán)境搭建
課程內(nèi)容
軟件開發(fā)整體介紹
蒼穹外賣項目介紹
開發(fā)環(huán)境搭建
導(dǎo)入接口文檔
Swagger
項目整體效果展示:
管理端-外賣商家使用
用戶端-點餐用戶使用
當我們完成該項目的學(xué)習(xí),可以培養(yǎng)以下能力:
1. 軟件開發(fā)整體介紹
作為一名軟件開發(fā)工程師,我們需要了解在軟件開發(fā)過程中的開發(fā)流程, 以及軟件開發(fā)過程中涉及到的崗位角色,角色的分工、職責, 并了解軟件開發(fā)中涉及到的三種軟件環(huán)境。那么這一小節(jié),我們將從 軟件開發(fā)流程、角色分工、軟件環(huán)境 三個方面整體介紹一下軟件開發(fā)。
1.1 軟件開發(fā)流程
1). 第1階段: 需求分析
完成需求規(guī)格說明書、產(chǎn)品原型編寫。
需求規(guī)格說明書, 一般來說就是使用 Word 文檔來描述當前項目的各個組成部分,如:系統(tǒng)定義、應(yīng)用環(huán)境、功能規(guī)格、性能需求等,都會在文檔中描述。例如:
產(chǎn)品原型,一般是通過網(wǎng)頁(html)的形式展示當前的頁面展示什么樣的數(shù)據(jù), 頁面的布局是什么樣子的,點擊某個菜單,打開什么頁面,點擊某個按鈕,出現(xiàn)什么效果,都可以通過產(chǎn)品原型看到。 例如:
2). 第2階段: 設(shè)計
設(shè)計的內(nèi)容包含 UI設(shè)計、數(shù)據(jù)庫設(shè)計、接口設(shè)計。
UI設(shè)計:用戶界面的設(shè)計,主要設(shè)計項目的頁面效果,小到一個按鈕,大到一個頁面布局,還有人機交互邏輯的體現(xiàn)。例如:
數(shù)據(jù)庫設(shè)計:需要設(shè)計當前項目中涉及到哪些數(shù)據(jù)庫,每一個數(shù)據(jù)庫里面包含哪些表,這些表結(jié)構(gòu)之間的關(guān)系是什么樣的,表結(jié)構(gòu)中包含哪些字段。例如:
接口設(shè)計:通過分析原型圖,首先,粗粒度地分析每個頁面有多少接口,然后,再細粒度地分析每個接口的傳入?yún)?shù),返回值參數(shù),同時明確接口路徑及請求方式。例如:
3). 第3階段: 編碼
編寫項目代碼、并完成單元測試。
項目代碼編寫:作為軟件開發(fā)工程師,我們需要對項目的模塊功能分析后,進行編碼實現(xiàn)。
單元測試:編碼實現(xiàn)完畢后,進行單元測試,單元測試通過后再進入到下一階段。例如:
4). 第4階段: 測試
在該階段中主要由測試人員, 對部署在測試環(huán)境的項目進行功能測試, 并出具測試報告。
5). 第5階段: 上線運維
在項目上線之前, 會由運維人員準備服務(wù)器上的軟件環(huán)境安裝、配置, 配置完畢后, 再將我們開發(fā)好的項目,部署在服務(wù)器上運行。
1.2 角色分工
在對整個軟件開發(fā)流程熟悉后, 我們還有必要了解一下在整個軟件開發(fā)流程中涉及到的崗位角色,以及各個角色的職責分工。
崗位/角色 | 對應(yīng)階段 | 職責/分工 |
---|---|---|
項目經(jīng)理 | 全階段 | 對整個項目負責,任務(wù)分配、把控進度 |
產(chǎn)品經(jīng)理 | 需求分析 | 進行需求調(diào)研,輸出需求調(diào)研文檔、產(chǎn)品原型等 |
UI設(shè)計師 | 設(shè)計 | 根據(jù)產(chǎn)品原型輸出界面效果圖 |
架構(gòu)師 | 設(shè)計 | 項目整體架構(gòu)設(shè)計、技術(shù)選型等 |
開發(fā)工程師 | 編碼 | 功能代碼實現(xiàn) |
測試工程師 | 測試 | 編寫測試用例,輸出測試報告 |
運維工程師 | 上線運維 | 軟件環(huán)境搭建、項目上線 |
上述我們講解的角色分工, 是在一個項目組中比較標準的角色分工, 但是在實際的項目中, 有一些項目組由于人員配置緊張, 可能并沒有專門的架構(gòu)師或測試人員, 這個時候可能需要有項目經(jīng)理或者程序員兼任。
1.3 軟件環(huán)境
作為軟件開發(fā)工程師,在編碼的過程中就不可避免地會接觸多種軟件環(huán)境,我們主要來分析在工作中經(jīng)常遇到的三套環(huán)境, 分別是: 開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境。 接下來,我們分別介紹一下這三套環(huán)境的作用和特點。
1). 開發(fā)環(huán)境(development)
我們作為軟件開發(fā)人員,在開發(fā)階段使用的環(huán)境,就是開發(fā)環(huán)境,一般外部用戶無法訪問。
比如,我們在開發(fā)中使用的MySQL數(shù)據(jù)庫和其他的一些常用軟件,我們可以安裝在本地, 也可以安裝在一臺專門的服務(wù)器中, 這些應(yīng)用軟件僅僅在軟件開發(fā)過程中使用, 項目測試、上線時,我們不會使用這套環(huán)境了,這個環(huán)境就是開發(fā)環(huán)境。
2). 測試環(huán)境(testing)
當軟件開發(fā)工程師,將項目的功能模塊開發(fā)完畢,并且單元測試通過后,就需要將項目部署到測試服務(wù)器上,讓測試人員對項目進行測試。那這臺測試服務(wù)器就是專門給測試人員使用的環(huán)境, 也就是測試環(huán)境,用于項目測試,一般外部用戶無法訪問。
3). 生產(chǎn)環(huán)境(production)
當項目開發(fā)完畢,并且由測試人員測試通過之后,就可以上線項目,將項目部署到線上環(huán)境,并正式對外提供服務(wù),這個線上環(huán)境也稱之為生產(chǎn)環(huán)境。
**開發(fā)環(huán)境** **測試環(huán)境** **生產(chǎn)環(huán)境**
首先,會在開發(fā)環(huán)境中進行項目開發(fā),往往開發(fā)環(huán)境大多數(shù)都是本地的電腦環(huán)境和局域網(wǎng)內(nèi)的環(huán)境,當開發(fā)完畢后,然后會把項目部署到測試環(huán)境,測試環(huán)境一般是一臺獨立測試服務(wù)器的環(huán)境,項目測試通過后,最終把項目部署到生產(chǎn)環(huán)境,生產(chǎn)環(huán)境可以是機房或者云服務(wù)器等線上環(huán)境。
2. 蒼穹外賣項目介紹
在開發(fā)蒼穹外賣這個項目之前,我們需要全方位的來介紹一下當前我們學(xué)習(xí)的這個項目。接下來,我們將從項目簡介、產(chǎn)品原型、技術(shù)選型三個方面來介紹蒼穹外賣這個項目。
2.1 項目介紹
本項目(蒼穹外賣)是專門為餐飲企業(yè)(餐廳、飯店)定制的一款軟件產(chǎn)品,包括 系統(tǒng)管理后臺 和 小程序端應(yīng)用 兩部分。其中系統(tǒng)管理后臺主要提供給餐飲企業(yè)內(nèi)部員工使用,可以對餐廳的分類、菜品、套餐、訂單、員工等進行管理維護,對餐廳的各類數(shù)據(jù)進行統(tǒng)計,同時也可進行來單語音播報功能。小程序端主要提供給消費者使用,可以在線瀏覽菜品、添加購物車、下單、支付、催單等。
接下來,通過功能架構(gòu)圖來展示管理端和用戶端的具體業(yè)務(wù)功能模塊。
1). 管理端功能
員工登錄/退出 , 員工信息管理 , 分類管理 , 菜品管理 , 套餐管理 , 菜品口味管理 , 訂單管理 ,數(shù)據(jù)統(tǒng)計,來單提醒。
2). 用戶端功能
微信登錄 , 收件人地址管理 , 用戶歷史訂單查詢 , 菜品規(guī)格查詢 , 購物車功能 , 下單 , 支付、分類及菜品瀏覽。
2.2 產(chǎn)品原型
產(chǎn)品原型,用于展示項目的業(yè)務(wù)功能,一般由產(chǎn)品經(jīng)理進行設(shè)計。
注意事項: 產(chǎn)品原型主要用于展示項目的功能,并不是最終的頁面效果。
在課程資料的產(chǎn)品原型文件夾下,提供了兩份產(chǎn)品原型。
管理端原型圖:
用戶端原型圖:
1). 管理端
餐飲企業(yè)內(nèi)部員工使用。 主要功能有:
模塊 | 描述 |
---|---|
登錄/退出 | 內(nèi)部員工必須登錄后,才可以訪問系統(tǒng)管理后臺 |
員工管理 | 管理員可以在系統(tǒng)后臺對員工信息進行管理,包含查詢、新增、編輯、禁用等功能 |
分類管理 | 主要對當前餐廳經(jīng)營的 菜品分類 或 套餐分類 進行管理維護, 包含查詢、新增、修改、刪除等功能 |
菜品管理 | 主要維護各個分類下的菜品信息,包含查詢、新增、修改、刪除、啟售、停售等功能 |
套餐管理 | 主要維護當前餐廳中的套餐信息,包含查詢、新增、修改、刪除、啟售、停售等功能 |
訂單管理 | 主要維護用戶在移動端下的訂單信息,包含查詢、取消、派送、完成,以及訂單報表下載等功能 |
數(shù)據(jù)統(tǒng)計 | 主要完成對餐廳的各類數(shù)據(jù)統(tǒng)計,如營業(yè)額、用戶數(shù)量、訂單等 |
2). 用戶端
移動端應(yīng)用主要提供給消費者使用。主要功能有:
模塊 | 描述 |
---|---|
登錄/退出 | 用戶需要通過微信授權(quán)后登錄使用小程序進行點餐 |
點餐-菜單 | 在點餐界面需要展示出菜品分類/套餐分類, 并根據(jù)當前選擇的分類加載其中的菜品信息, 供用戶查詢選擇 |
點餐-購物車 | 用戶選中的菜品就會加入用戶的購物車, 主要包含 查詢購物車、加入購物車、刪除購物車、清空購物車等功能 |
訂單支付 | 用戶選完菜品/套餐后, 可以對購物車菜品進行結(jié)算支付, 這時就需要進行訂單的支付 |
個人信息 | 在個人中心頁面中會展示當前用戶的基本信息, 用戶可以管理收貨地址, 也可以查詢歷史訂單數(shù)據(jù) |
2.3 技術(shù)選型
關(guān)于本項目的技術(shù)選型, 我們將會從 用戶層、網(wǎng)關(guān)層、應(yīng)用層、數(shù)據(jù)層 這幾個方面進行介紹,主要用于展示項目中使用到的技術(shù)框架和中間件等。
1). 用戶層
本項目中在構(gòu)建系統(tǒng)管理后臺的前端頁面,我們會用到H5、Vue.js、ElementUI、apache echarts(展示圖表)等技術(shù)。而在構(gòu)建移動端應(yīng)用時,我們會使用到微信小程序。
2). 網(wǎng)關(guān)層
Nginx是一個服務(wù)器,主要用來作為Http服務(wù)器,部署靜態(tài)資源,訪問性能高。在Nginx中還有兩個比較重要的作用: 反向代理和負載均衡, 在進行項目部署時,要實現(xiàn)Tomcat的負載均衡,就可以通過Nginx來實現(xiàn)。
3). 應(yīng)用層
SpringBoot: 快速構(gòu)建Spring項目, 采用 "約定優(yōu)于配置" 的思想, 簡化Spring項目的配置開發(fā)。 SpringMVC:SpringMVC是spring框架的一個模塊,springmvc和spring無需通過中間整合層進行整合,可以無縫集成。 Spring Task: 由Spring提供的定時任務(wù)框架。 httpclient: 主要實現(xiàn)了對http請求的發(fā)送。 Spring Cache: 由Spring提供的數(shù)據(jù)緩存框架 JWT: 用于對應(yīng)用程序上的用戶進行身份驗證的標記。 阿里云OSS: 對象存儲服務(wù),在項目中主要存儲文件,如圖片等。 Swagger: 可以自動的幫助開發(fā)人員生成接口文檔,并對接口進行測試。 POI: 封裝了對Excel表格的常用操作。 WebSocket: 一種通信網(wǎng)絡(luò)協(xié)議,使客戶端和服務(wù)器之間的數(shù)據(jù)交換更加簡單,用于項目的來單、催單功能實現(xiàn)。
4). 數(shù)據(jù)層
MySQL: 關(guān)系型數(shù)據(jù)庫, 本項目的核心業(yè)務(wù)數(shù)據(jù)都會采用MySQL進行存儲。 Redis: 基于key-value格式存儲的內(nèi)存數(shù)據(jù)庫, 訪問速度快, 經(jīng)常使用它做緩存。 Mybatis: 本項目持久層將會使用Mybatis開發(fā)。 pagehelper: 分頁插件。 spring data redis: 簡化java代碼操作Redis的API。
5). 工具
git: 版本控制工具, 在團隊協(xié)作中, 使用該工具對項目中的代碼進行管理。 maven: 項目構(gòu)建工具。 junit:單元測試工具,開發(fā)人員功能實現(xiàn)完畢后,需要通過junit對功能進行單元測試。 postman: 接口測工具,模擬用戶發(fā)起的各類HTTP請求,獲取對應(yīng)的響應(yīng)結(jié)果。
3. 開發(fā)環(huán)境搭建
開發(fā)環(huán)境搭建主要包含前端環(huán)境和后端環(huán)境兩部分。作為服務(wù)端開發(fā)工程師, 我們課程學(xué)習(xí)的重心應(yīng)該放在后端的業(yè)務(wù)代碼上, 前端的頁面我們只需要導(dǎo)入資料中的nginx, 前端頁面的代碼我們只需要能看懂即可。
3.1 前端環(huán)境搭建
1). 前端工程基于 nginx 從資料中找到前端運行環(huán)境的nginx,移動到非中文目錄下。 sky目錄中存放了管理端的前端資源,具體如下:
2). 啟動nginx,訪問測試
雙擊 nginx.exe 即可啟動 nginx 服務(wù),訪問端口號為 80 http://localhost:80
3.2 后端環(huán)境搭建
3.2.1 熟悉項目結(jié)構(gòu)
后端工程基于 maven 進行項目構(gòu)建,并且進行分模塊開發(fā)。 1). 從當天資料中找到后端初始工程:
2). 用 IDEA 打開初始工程,了解項目的整體結(jié)構(gòu): 對工程的每個模塊作用說明:
序號 | 名稱 | 說明 |
---|---|---|
1 | sky-take-out | maven父工程,統(tǒng)一管理依賴版本,聚合其他子模塊 |
2 | sky-common | 子模塊,存放公共類,例如:工具類、常量類、異常類等 |
3 | sky-pojo | 子模塊,存放實體類(Entity)、VO、DTO等 |
4 | sky-server | 子模塊,后端服務(wù),存放配置文件、Controller、Service、Mapper等 |
對項目整體結(jié)構(gòu)了解后,接下來我們詳細分析上述的每個子模塊:
sky-common: 模塊中存放的是一些公共類,可以供其他模塊使用
分析sky-common模塊的每個包的作用:
名稱 | 說明 |
---|---|
constant | 存放相關(guān)常量類 |
context | 存放上下文類 |
enumeration | 項目的枚舉類存儲 |
exception | 存放自定義異常類 |
json | 處理json轉(zhuǎn)換的類 |
properties | 存放SpringBoot相關(guān)的配置屬性類 |
result | 返回結(jié)果類的封裝 |
utils | 常用工具類 |
sky-pojo: 模塊中存放的是一些 entity、DTO、VO
分析sky-pojo模塊的每個包的作用:
名稱 | 說明 |
---|---|
Entity | 實體,通常和數(shù)據(jù)庫中的表對應(yīng) |
DTO | 數(shù)據(jù)傳輸對象,通常用于程序中各層之間傳遞數(shù)據(jù) |
VO | 視圖對象,為前端展示數(shù)據(jù)提供的對象 |
POJO | 普通Java對象,只有屬性和對應(yīng)的getter和setter |
sky-server: 模塊中存放的是 配置文件、配置類、攔截器、controller、service、mapper、啟動類等
分析sky-server模塊的每個包的作用:
名稱 | 說明 |
---|---|
config | 存放配置類 |
controller | 存放controller類 |
interceptor | 存放攔截器類 |
mapper | 存放mapper接口 |
service | 存放service類 |
SkyApplication | 啟動類 |
3.2.2 Git版本控制
使用Git進行項目代碼的版本控制,具體操作:
1). 創(chuàng)建Git本地倉庫
當Idea中出現(xiàn): 說明本地倉庫創(chuàng)建成功。
2). 創(chuàng)建Git遠程倉庫
訪問https://gitee.com/,新建倉庫
點擊 創(chuàng)建
3). 將本地文件推送到Git遠程倉庫
提交文件至本地倉庫
忽略以下類型文件
開始提交
中間出現(xiàn):點擊commit
添加Git遠程倉庫地址 復(fù)制遠程地址:
添加地址:
推送
成功推送至遠程倉庫
3.2.3 數(shù)據(jù)庫環(huán)境搭建
從資料中找到sky.sql
通過該sql文件直接可創(chuàng)建數(shù)據(jù)庫,所以不需要提前創(chuàng)建數(shù)據(jù)庫,直接導(dǎo)入該文件執(zhí)行即可。
執(zhí)行sky.sql文件
執(zhí)行完成后,共創(chuàng)建出11張表
每張表的說明:
序號 | 表名 | 中文名 |
---|---|---|
1 | employee | 員工表 |
2 | category | 分類表 |
3 | dish | 菜品表 |
4 | dish_flavor | 菜品口味表 |
5 | setmeal | 套餐表 |
6 | setmeal_dish | 套餐菜品關(guān)系表 |
7 | user | 用戶表 |
8 | address_book | 地址表 |
9 | shopping_cart | 購物車表 |
10 | orders | 訂單表 |
11 | order_detail | 訂單明細表 |
我們目前先簡單了解大概有哪些表, 每張表存儲什么數(shù)據(jù), 有一個印象。對于具體的表結(jié)構(gòu), 以及表結(jié)構(gòu)中的字段, 可以參考資料中的《數(shù)據(jù)庫設(shè)計文檔》,同時在講解具體的功能開發(fā)時, 我們也會再詳細介紹。
3.2.4 前后端聯(lián)調(diào)
后端的初始工程中已經(jīng)實現(xiàn)了登錄功能,直接進行前后端聯(lián)調(diào)測試即可
實現(xiàn)思路:
1.Controller層
在sky-server模塊中,com.sky.controller.admin.EmployeeController
/** * 登錄 * * @param employeeLoginDTO * @return */ @PostMapping("/login") public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) { log.info("員工登錄:{}", employeeLoginDTO); //調(diào)用service方法查詢數(shù)據(jù)庫 Employee employee = employeeService.login(employeeLoginDTO); //登錄成功后,生成jwt令牌 Map<String, Object> claims = new HashMap<>(); claims.put(JwtClaimsConstant.EMP_ID, employee.getId()); String token = JwtUtil.createJWT( jwtProperties.getAdminSecretKey(), jwtProperties.getAdminTtl(), claims); EmployeeLoginVO employeeLoginVO = EmployeeLoginVO.builder() .id(employee.getId()) .userName(employee.getUsername()) .name(employee.getName()) .token(token) .build(); return Result.success(employeeLoginVO); }
2.Service層
在sky-server模塊中,com.sky.service.impl.EmployeeServiceImpl
/** * 員工登錄 * * @param employeeLoginDTO * @return */ public Employee login(EmployeeLoginDTO employeeLoginDTO) { String username = employeeLoginDTO.getUsername(); String password = employeeLoginDTO.getPassword(); //1、根據(jù)用戶名查詢數(shù)據(jù)庫中的數(shù)據(jù) Employee employee = employeeMapper.getByUsername(username); //2、處理各種異常情況(用戶名不存在、密碼不對、賬號被鎖定) if (employee == null) { //賬號不存在 throw new AccountNotFoundException(MessageConstant.ACCOUNT_NOT_FOUND); } //密碼比對 if (!password.equals(employee.getPassword())) { //密碼錯誤 throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR); } if (employee.getStatus() == StatusConstant.DISABLE) { //賬號被鎖定 throw new AccountLockedException(MessageConstant.ACCOUNT_LOCKED); } //3、返回實體對象 return employee; }
3.Mapper層
在sky-server模塊中,com.sky.mapper.EmployeeMapper
package com.sky.mapper; import com.sky.entity.Employee; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; @Mapper public interface EmployeeMapper { /** * 根據(jù)用戶名查詢員工 * @param username * @return */ @Select("select * from employee where username = #{username}") Employee getByUsername(String username); }
注:可以通過斷點調(diào)試跟蹤后端程序的執(zhí)行過程
3.2.5 nginx反向代理和負載均衡
對登錄功能測試完畢后,接下來,我們思考一個問題:前端發(fā)送的請求,是如何請求到后端服務(wù)的?
前端請求地址:http://localhost/api/employee/login 后端接口地址:http://localhost:8080/admin/employee/login
前端請求地址
后端接口地址
很明顯,兩個地址不一致,那是如何請求到后端服務(wù)的呢?
1). nginx反向代理
nginx 反向代理,就是將前端發(fā)送的動態(tài)請求由 nginx 轉(zhuǎn)發(fā)到后端服務(wù)器
那為什么不直接通過瀏覽器直接請求后臺服務(wù)端,需要通過nginx反向代理呢?
nginx 反向代理的好處:
提高訪問速度 因為nginx本身可以進行緩存,如果訪問的同一接口,并且做了數(shù)據(jù)緩存,nginx就直接可把數(shù)據(jù)返回,不需要真正地訪問服務(wù)端,從而提高訪問速度。
進行負載均衡 所謂負載均衡,就是把大量的請求按照我們指定的方式均衡的分配給集群中的每臺服務(wù)器。
保證后端服務(wù)安全 因為一般后臺服務(wù)地址不會暴露,所以使用瀏覽器不能直接訪問,可以把nginx作為請求訪問的入口,請求到達nginx后轉(zhuǎn)發(fā)到具體的服務(wù)中,從而保證后端服務(wù)的安全。
nginx 反向代理的配置方式:
server{ listen 80; server_name localhost; location /api/{ proxy_pass http://localhost:8080/admin/; #反向代理 } }
proxy_pass:該指令是用來設(shè)置代理服務(wù)器的地址,可以是主機名稱,IP地址加端口號等形式。 如上代碼的含義是:監(jiān)聽80端口號, 然后當我們訪問 http://localhost:80/api/../..這樣的接口的時候,它會通過 location /api/ {} 這樣的反向代理到 http://localhost:8080/admin/上來。
接下來,進到nginx-1.20.2\conf
,打開nginx配置
# 反向代理,處理管理端發(fā)送的請求 location /api/ { proxy_pass http://localhost:8080/admin/; #proxy_pass http://webservers/admin/; }
當在訪問http://localhost/api/employee/login,nginx接收到請求后轉(zhuǎn)到http://localhost:8080/admin/,故最終的請求地址為http://localhost:8080/admin/employee/login,和后臺服務(wù)的訪問地址一致。
2). nginx 負載均衡
當如果服務(wù)以集群的方式進行部署時,那nginx在轉(zhuǎn)發(fā)請求到服務(wù)器時就需要做相應(yīng)的負載均衡。其實,負載均衡從本質(zhì)上來說也是基于反向代理來實現(xiàn)的,最終都是轉(zhuǎn)發(fā)請求。
nginx 負載均衡的配置方式:
upstream webservers{ server 192.168.100.128:8080; server 192.168.100.129:8080; } server{ listen 80; server_name localhost; location /api/{ proxy_pass http://webservers/admin;#負載均衡 } }
upstream:如果代理服務(wù)器是一組服務(wù)器的話,我們可以使用upstream指令配置后端服務(wù)器組。
如上代碼的含義是:監(jiān)聽80端口號, 然后當我們訪問 http://localhost:80/api/../..這樣的接口的時候,它會通過 location /api/ {} 這樣的反向代理到 http://webservers/admin,根據(jù)webservers名稱找到一組服務(wù)器,根據(jù)設(shè)置的負載均衡策略(默認是輪詢)轉(zhuǎn)發(fā)到具體的服務(wù)器。
注:upstream后面的名稱可自定義,但要上下保持一致。
nginx 負載均衡策略:
名稱 | 說明 |
---|---|
輪詢 | 默認方式 |
weight | 權(quán)重方式,默認為1,權(quán)重越高,被分配的客戶端請求就越多 |
ip_hash | 依據(jù)ip分配方式,這樣每個訪客可以固定訪問一個后端服務(wù) |
least_conn | 依據(jù)最少連接方式,把請求優(yōu)先分配給連接數(shù)少的后端服務(wù) |
url_hash | 依據(jù)url分配方式,這樣相同的url會被分配到同一個后端服務(wù) |
fair | 依據(jù)響應(yīng)時間方式,響應(yīng)時間短的服務(wù)將會被優(yōu)先分配 |
具體配置方式:
輪詢:
upstream webservers{ server 192.168.100.128:8080; server 192.168.100.129:8080; }
weight:
upstream webservers{ server 192.168.100.128:8080 weight=90; server 192.168.100.129:8080 weight=10; }
ip_hash:
upstream webservers{ ip_hash; server 192.168.100.128:8080; server 192.168.100.129:8080; }
least_conn:
upstream webservers{ least_conn; server 192.168.100.128:8080; server 192.168.100.129:8080; }
url_hash:
upstream webservers{ hash &request_uri; server 192.168.100.128:8080; server 192.168.100.129:8080; }
fair:
upstream webservers{ server 192.168.100.128:8080; server 192.168.100.129:8080; fair; }
3.3 完善登錄功能
問題:員工表中的密碼是明文存儲,安全性太低。
解決思路:
將密碼加密后存儲,提高安全性
使用MD5加密方式對明文密碼加密
實現(xiàn)步驟:
修改數(shù)據(jù)庫中明文密碼,改為MD5加密后的密文 打開employee表,修改密碼
修改Java代碼,前端提交的密碼進行MD5加密后再跟數(shù)據(jù)庫中密碼比對 打開EmployeeServiceImpl.java,修改比對密碼
/** * 員工登錄 * * @param employeeLoginDTO * @return */ public Employee login(EmployeeLoginDTO employeeLoginDTO) { //1、根據(jù)用戶名查詢數(shù)據(jù)庫中的數(shù)據(jù) //2、處理各種異常情況(用戶名不存在、密碼不對、賬號被鎖定) //....... //密碼比對 // TODO 后期需要進行md5加密,然后再進行比對 password = DigestUtils.md5DigestAsHex(password.getBytes()); if (!password.equals(employee.getPassword())) { //密碼錯誤 throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR); } //........ //3、返回實體對象 return employee; }
4. 導(dǎo)入接口文檔
接下來,就要進入到項目的業(yè)務(wù)開發(fā)了,而我們的開發(fā)方式就是基本當前企業(yè)主流的前后端分離開發(fā)方式,那么這種方式就要求我們之前需要先將接口定義好,這樣前后端人員才能并行開發(fā),所以,這個章節(jié)就需要將接口文檔導(dǎo)入到管理平臺,為我們后面業(yè)務(wù)開發(fā)做好準備。其實,在真實的企業(yè)開發(fā)中,接口設(shè)計過程其實是一個非常漫長的過程,可能需要多次開會討論調(diào)整,甚至在開發(fā)的過程中才會發(fā)現(xiàn)某些接口定義還需要再調(diào)整,這種情況其實是非常常見的,但是由于項目時間原因,所以選擇一次性導(dǎo)入所有的接口,在開發(fā)業(yè)務(wù)功能過程當中,也會帶著大家一起來分析一下對應(yīng)的接口是怎么確定下來的,為什么要這樣定義,從而培養(yǎng)同學(xué)們的接口設(shè)計能力。
4.1 前后端分離開發(fā)流程
第一步:定義接口,確定接口的路徑、請求方式、傳入?yún)?shù)、返回參數(shù)。
第二步:前端開發(fā)人員和后端開發(fā)人員并行開發(fā),同時,也可自測。
第三步:前后端人員進行連調(diào)測試。
第四步:提交給測試人員進行最終測試。
4.2 操作步驟
將課程資料中提供的項目接口導(dǎo)入YApi。訪問地址:http://yapi.smart-xwork.cn/
1). 從資料中找到項目接口文件
2). 導(dǎo)入到Y(jié)Api平臺
在YApi平臺創(chuàng)建出兩個項目
選擇蒼穹外賣-管理端接口.json導(dǎo)入 如果接口比較多,這個過程會花一些時間。
導(dǎo)入成功
另一個用戶端json文件也執(zhí)行相同操作。
5. Swagger
5.1 介紹
Swagger是一種API文檔自動生成工具,它可以幫助開發(fā)人員快速生成API文檔,并提供在線API測試功能用于生成、描述、調(diào)用和可視化 RESTful 風(fēng)格的 Web 服務(wù)(https://swagger.io/)。 它的主要作用是:
使得前后端分離開發(fā)更加方便,有利于團隊協(xié)作
接口的文檔在線自動生成,降低后端開發(fā)人員編寫接口文檔的負擔
功能測試 Spring已經(jīng)將Swagger納入自身的標準,建立了Spring-swagger項目,現(xiàn)在叫Springfox。通過在項目中引入Springfox ,即可非常簡單快捷的使用Swagger。
knife4j是為Java MVC框架集成Swagger生成Api文檔的增強解決方案,前身是swagger-bootstrap-ui,取名knife4j是希望它能像一把匕首一樣小巧,輕量,并且功能強悍!
目前,一般都使用knife4j框架。
5.2 使用步驟
導(dǎo)入 knife4j 的maven坐標 在pom.xml中添加依賴
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> </dependency>
在配置類中加入 knife4j 相關(guān)配置 WebMvcConfiguration.java ```java /**
通過knife4j生成接口文檔
@return
*/ @Bean public Docket docket() { ApiInfo apiInfo = new ApiInfoBuilder() .title("蒼穹外賣項目接口文檔") .version("2.0") .description("蒼穹外賣項目接口文檔") .build(); Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo) .select() .apis(RequestHandlerSelectors.basePackage("com.sky.controller")) .paths(PathSelectors.any()) .build(); return docket; }
3. 設(shè)置靜態(tài)資源映射,否則接口文檔頁面無法訪問 WebMvcConfiguration.java ```java /** * 設(shè)置靜態(tài)資源映射 * @param registry */ protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); }
訪問測試 接口文檔訪問路徑為 http://ip:port/doc.html ---> http://localhost:8080/doc.html
接口測試:測試登錄功能
思考:通過 Swagger 就可以生成接口文檔,那么我們就不需要 Yapi 了?
1、Yapi 是設(shè)計階段使用的工具,管理和維護接口 2、Swagger 在開發(fā)階段使用的框架,幫助后端開發(fā)人員做后端的接口測試
5.3 常用注解
通過注解可以控制生成的接口文檔,使接口文檔擁有更好的可讀性,常用注解如下:
注解 | 說明 |
---|---|
@Api | 用在類上,例如Controller,表示對類的說明 |
@ApiModel | 用在類上,例如entity、DTO、VO |
@ApiModelProperty | 用在屬性上,描述屬性信息 |
@ApiOperation | 用在方法上,例如Controller的方法,說明方法的用途、作用 |
接下來,使用上述注解,生成可讀性更好的接口文檔
在sky-pojo模塊中
EmployeeLoginDTO.java
package com.sky.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.io.Serializable; @Data @ApiModel(description = "員工登錄時傳遞的數(shù)據(jù)模型") public class EmployeeLoginDTO implements Serializable { @ApiModelProperty("用戶名") private String username; @ApiModelProperty("密碼") private String password; }
EmployeeLoginVo.java
package com.sky.vo; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.io.Serializable; @Data @Builder @NoArgsConstructor @AllArgsConstructor @ApiModel(description = "員工登錄返回的數(shù)據(jù)格式") public class EmployeeLoginVO implements Serializable { @ApiModelProperty("主鍵值") private Long id; @ApiModelProperty("用戶名") private String userName; @ApiModelProperty("姓名") private String name; @ApiModelProperty("jwt令牌") private String token; }
在sky-server模塊中 EmployeeController.java
package com.sky.controller.admin; import com.sky.constant.JwtClaimsConstant; import com.sky.dto.EmployeeLoginDTO; import com.sky.entity.Employee; import com.sky.properties.JwtProperties; import com.sky.result.Result; import com.sky.service.EmployeeService; import com.sky.utils.JwtUtil; import com.sky.vo.EmployeeLoginVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; /** * 員工管理 */ @RestController @RequestMapping("/admin/employee") @Slf4j @Api(tags = "員工相關(guān)接口") public class EmployeeController { @Autowired private EmployeeService employeeService; @Autowired private JwtProperties jwtProperties; /** * 登錄 * * @param employeeLoginDTO * @return */ @PostMapping("/login") @ApiOperation(value = "員工登錄") public Result<EmployeeLoginVO> login(@RequestBody EmployeeLoginDTO employeeLoginDTO) { //.............. } /** * 退出 * * @return */ @PostMapping("/logout") @ApiOperation("員工退出") public Result<String> logout() { return Result.success(); } }
啟動服務(wù):訪問http://localhost:8080/doc.html文章來源:http://www.zghlxwxcb.cn/news/detail-687005.html
![https://4k-images.oss-cn-beijing.aliyuncs.com/m2img/d2b59285801e8fe253331ea071aa32e0.png)文章來源地址http://www.zghlxwxcb.cn/news/detail-687005.html
到了這里,關(guān)于蒼穹外賣項目開發(fā)指南:項目概述、環(huán)境搭建、Swagger接口文檔生成的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!