項目整體功能概述
- 本項目是基於SSM、RPC框架實現的旅游后台管理系統,可對自由行、跟團游、套餐游等進行相關的CRUD操作,有着用戶角色的權限控制、運營數據的統計分析、文件的上傳下載、數據導入、百度地圖定位公司地址等功能。
一.SSM
1.springMVC
概述MVC與三層架構的關系:
(1) Model:數據模型層
用於處理數據,進行業務邏輯判斷,數據庫存取。其分為兩類:
一類稱為數據承載 Bean:實體類,專門用戶承載業務數據的,如 本項目中的旅游訂單Order、旅游會員User 等。
一類稱為業務處理 Bean:指 Service 或 Dao 對象,專門用於處理用戶提交請求的。
其中在service層中需要的配置
-(1)配置事務管理器transactionManager
-(2)開啟事務控制的注解,其中配置proxy-target-class="true",其作用是使用cglib代理方式為Service類創建代理對象。那為什么需要用cglib的代理方式呢?
因為Dubbo需要將Service發布為服務,配置文件掃描的包為com.luochenggui.service,假如默認使用jdk的動態代理,創建的代理對象完整類名為com.sun.proxy.$Proxy35,導致Dubbo在進行包匹配時沒有成功,服務發布失敗,所以要求必須使用cglib創建代理對象
另外需要在Service注解中加入interfaceClass屬性,否則會導致發布的服務接口為SpringProxy,而不是我們定義的Service接口
-(3)jedisPoolConfig相關參數配置與jedisPool
-(4)spring整合dubbo的相關配置,指定發布服務的名稱、暴露服務的接口(一般在服務提供者一方配置,可以指定使用的協議名稱和端口號)、指定服務注冊中心的地址、批量掃描,發布服務
-(5)最后在web.xml中配置ContextLoaderListener,當web容器啟動的時候,自動加載spring容器
(2) view:視圖層
為用戶提供使用界面,與用戶直接進行交互。本項目所用到的技術為:
- vue,其核心是數據驅動、組件化
使用該框架能夠使我們專注於View 層。省去了操作DOM的過程,只需要改變數據。Vue會通過Dircetives指令,對DOM做一層封裝,當數據發生改變會通知指令去修改對應的DOM,數據驅動DOM變化,DOM是數據的一種自然映射。 - ElementUI,是一套基於VUE2.0的桌面端組件庫。本項目的后台就是使用它來構建頁面。
(3) controller:控制層
控制器,用於將用戶請求轉發給相應的 Model 進行處理,並根據 Model 的計算結果向用戶提供相應響應。
其中在controller層中需要的配置
- 配置mvc的注解驅動:mvc:annotation-driven
- 配置文件上傳組件multipartResolver
- spring整合dubbo的相關配置,指定服務的名稱、指定服務注冊中心地址、批量掃描、是否檢查服務提供方。
- 在web.xml中配置dispatchservlet,這是springmvc的核心控制器,當web容器啟動的時候,會自動加載springmvc.xml。配置字符過濾器解決請求亂碼問題。
2.spring
作為管理組件,管理整個應用中所有 Bean 的生命周期行為。
即整個應用中所有對象的創建、初始化、銷毀,及對象間關聯關系的維護,均由 Spring 進行管理。
- IOC控制反轉,把對象創建和對象之間的調用過程,交給Spring進行管理。而IOC容器,就是 IOC 思想的一個落地的產品實現。
- 面向切面編程AOP
(1)使用jdk動態代理,創建接口實現類的對象,增強類的方法
(2)使用CGLIB動態代理,繼承父類方法,創建子類的代理對象,增強類的方法
3.mybatis
(1) 使用Druid連接池配置數據源
(2)使用pagehelper作為分頁插件
(3)使用sqlsessionfactory來執行SQL語句
在這個bean中將數據源、分頁插件的配置、給包取別名配置進來
(4)掃描mapper接口生成代理對象
二.dubbo遠程過程調用
Apache Dubbo是一款高性能的Java RPC框架。Dubbo提供了三大核心能力:面向接口的遠程方法調用,智能容錯和負載均衡,以及服務自動注冊和發現。
1.Dubbo各節點之間的調用關系
節點 | 角色描述 |
---|---|
Consumer | 調用遠程服務的服務消費方 |
Provider | 暴露服務的服務提供方 |
Registry | 服務注冊與發現的注冊中心 |
Monitor | 統計服務的調用次數和調用時間的監控中心 |
Container | 服務運行容器 |
- (1)Container負責啟動,加載,運行服務提供者
- (2)Provider在啟動時,向注冊中心注冊自己提供的服務
- (3)Consumer在啟動時,向注冊中心訂閱自己所需的服務
- (4)注冊中心Registry返回Provider的地址列表給消費者,如果有變更,注冊中心將基於長連接推送變更數據給消費者
- (5)Consumer從Provider地址列表中,基於負載均衡算法(隨機、輪詢、一致性hash、主備master-slave)選一台提供者進行調用,如果調用失敗,再選另一台調用
- (6)Consumer和Provider在內存中累計調用次數和調用時間,定時每分鍾發送一次統計數據到監控中心Registry
2.服務注冊中心Zookeeper
在上面的調用關系可以看出,Registry(服務注冊中心)在其中起着至關重要的作用,Dubbo官方推薦使用Zookeeper作為服務注冊中心。那如何防止Zookeeper單點故障?Zookeeper其實是支持集群模式的,可以配置Zookeeper集群來達到Zookeeper服務的高可用,防止出現單點故障
三.fileupload文件上傳
在 SpringMVC 的配置文件中加入 multipart 類型數據的解析器
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 設定文件上傳的最大值為100MB,10*1024*1024 -->
<property name="maxUploadSize" value="104857600" />
<!-- 設定文件上傳時寫入內存的最大值,如果小於這個參數不會生成臨時文件,默認為10240 -->
<property name="maxInMemorySize" value="4096" />
<!-- 設定默認編碼 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
利用MultipartFile接口中的方法,getOriginalFilename()方法獲取文件的原始名,再對原始名進行字符串操作,使用UUID隨機產生文件名稱,防止同名覆蓋。getBytes()方法獲取文件的字節數組。將兩個參數傳到七牛雲文件上傳的方法,執行上傳。
四.quartz-scheduler任務調度
Quartz是Job scheduling(作業調度)領域的一個開源項目,Quartz既可以單獨使用也可以跟spring框架整合使用,在實際開發中一般會使用后者。使用Quartz可以開發一個或者多個定時任務,每個定時任務可以單獨指定執行的時間,例如每隔1小時執行一次、每個月第一天上午10點執行一次、每個月最后一天下午5點執行一次等。
1.Quartz整合spring
<!--注冊自定義Job-->
<bean id="clearImgJob" class="com.atguigu.job.ClearImgJob"/>
<!--注冊JobDetail,作用:負責通過反射調用指定的Job-->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!--注入目標對象-->
<property name="targetObject" ref="clearImgJob"/>
<!--注入目標方法-->
<property name="targetMethod" value="clearImg"/>
</bean>
<!--注冊一個觸發器,指定任務的觸發時間-->
<bean id="clearImgTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!--注入jobDetail-->
<property name="jobDetail" ref="jobDetail"/>
<!-- 指定觸發的時間,基於Cron表達式(0 0 2 * * ?表示凌晨2點執行) -->
<property name="cronExpression">
<value>0 0 2 * * ?</value>
</property>
</bean>
<!--注冊一個統一的調度工廠,通過這個調度工廠調度任務-->
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!--注入多個觸發器-->
<property name="triggers">
<ref bean="clearImgTrigger"/>
</property>
</bean>
在定時任務的方法里,先用sdiff()方法計算Redis中兩個集合的差集,獲取垃圾圖片名稱,在調用七牛雲中刪除文件的方法,完成定時刪除垃圾圖片。
2.cron表達式
五.七牛雲服務平台(圖片上傳)
圖片上傳整體流程如下:
圖片上傳的具體方法可以參照官網提供的API文檔https://developer.qiniu.com/kodo/sdk/1239/java
七牛雲操作對象存儲服務。
六.POI報表(EXCEL)
Apache POI 該鏈接提供相關操作excel表的api。如導出Excel,導入Excel到數據庫中。在本項目中,有兩個模塊的功能需要用到Excel操作:
(1)從excel中讀取預約設置信息,批量導入到數據庫,controller層實現方法:使用poi工具類解析excel文件,讀取里面的內容,即POIUtils.readExcel(excelFile),然后將對應表格中的數據,用相應實體類進行封裝。
(2)將旅游的整體運營統計數據導出,controller層實現方法:
- 先獲得Excel模板文件絕對路徑temlateRealPath
- 讀取模板文件創建Excel表格對象:new XSSFWorkbook(new FileInputStream(new File(temlateRealPath)));
- 逐行逐列寫入數據:
讀行:XSSFRow row = sheet.getRow(2);
讀列:row.getCell(5).setCellValue(reportDate) - 通過輸出流進行文件下載,設置下載的數據類型(excel類型,以及下載形式(通過附件的形式下載)
七.redis
配置
在service層,controller層(web層),定時任務的jobs層都需要配置jedisPoolConfig相關參數配置與jedisPool
前面我們已經完成了文件上傳,將圖片存儲在了七牛雲服務器中。但是這個過程存在一個問題,就是如果用戶只上傳了圖片而沒有最終保存套餐信息到我們的數據庫,這時我們上傳的圖片就變為了垃圾圖片。對於這些垃圾圖片我們需要定時清理來釋放磁盤空間。這就需要我們能夠區分出來哪些是垃圾圖片,哪些不是垃圾圖片。如何實現呢?
方案就是利用redis來保存圖片名稱,具體做法為:
1、當用戶上傳圖片后,將圖片名稱保存到redis的一個Set集合中,例如集合名稱為 setmealPicResources
2、當用戶添加套餐后,將圖片名稱保存到redis的另一個Set集合中,例如集合名稱為setmealPicDbResources
3、用sdiff()方法計算 setmealPicResources集合與 setmealPicDbResources集合的差值,結果就是垃圾圖片的名稱集合,清理這些圖片即可
八.spring security安全框架
- 配置spring-security.xml
1:定義哪些鏈接可以放行
2:定義哪些鏈接不可以放行,即需要有角色、權限才可以放行
3:認證管理,定義登錄賬號名和密碼,並授予訪問的角色、權限 - 在Controller的方法上加入權限控制注解:@PreAuthorize("hasAuthority('TRAVELITEM_EDIT')")
九.圖形報表ECharts
(1) 概述:
- ECharts縮寫來自Enterprise Charts,商業級數據圖表,是百度的一個開源的使用JavaScript實現的數據可視化工具。可繪制柱狀圖、折線圖、餅圖等各種用於數據展示的效果圖
(2) 使用方法
- 使用ECharts展示圖表效果,關鍵點在於確定此圖表所需的數據格式,然后按照此數據格式提供數據就可以了,我們無須關注效果是如何渲染出來的。在實際應用中,我們要展示的數據往往存儲在數據庫中,所以我們可以發送ajax請求獲取數據庫中的數據並轉為圖表所需的數據即可。
這一步對我們List、Map等集合容器的使用,以及如何從數據庫查詢響應的數據,並把數據封裝到合適的集合容器中去,就有了更高的要求。
例:
十.阿里雲短信發送
用於用戶注冊時,進行發送驗證碼進行短信驗證