'JAVA項目面試總結 電商系統 OA辦公系統 P2P網貸'

"

我叫XX,XX年出生,來自XX,從事Java軟件開發行業4年多了,在這4年裡,我接觸到了一些主流框架並有了深刻的理解,項目開發中,熟悉使用struts2、spring、hibernate、mybatis等並參與搭建過SSH/SSM/SpringMVC+Mybatis等框架。對springBoot也略有研究.關於前臺的框架,使用過基於jquery的esayUI等。

也參與了項目數據庫的選擇以及對數據庫的設計,選擇合適的持久層框架,之前常用的數據庫有關係型數據庫oracle、 mysql,非關係數據庫Mongodb、redis等,特別是redis除了使用外我也做過一些其他的研究,比如說它作為緩存技術的使用、nginx和tomcat以及redis的集群環境搭建等。

考慮到開發項目的高效性,也使用了一些常用的主流java技術,如webservice、httpclient、jsonp、dubbo+zookeeper等技術框架,還有POI導入導出技術、ECharts報表技術等。為了向相關人員定時發送通知,用到了Spring定時器和JavaMail郵件發送、短信發送技術,對項目進行測試使用junit技術。

使用過Eclipse、MyEclipse、Idea等開發工具,為了方便項目的打包部署,還用到了maven進行相關jar包的依賴管理,同時利用業餘時間熟悉了Linux操作系統。也能熟練使用powerdesigner數據庫建模等工具的一些基本操作。

幾年開發,主要涉及的行業項目包括電子商務、OA辦公平臺等。

接下來我給您簡單介紹一下我的上一個項目吧?

【項目一】歡樂購商城電商系統

1:項目簡介

上個項目,我負責的是一個電商項目叫歡樂購購物商城,該商城是採用分佈式架構部署的一箇中小型網上購物商城系統。本系統分前臺系統和後臺管理系統。前臺系統主要負責商城的頁面的顯示功能,這裡採用的面向服務的方式,pc端手機端只負責顯示頁面,業務邏輯都在服務層實現,客戶端調用服務端接口來實現顯示功能。

2:分析

前臺系統主要有: 積分商城、商品展示、商品信息搜索框、購物車、商品秒殺、訂單查詢、瀏覽記錄、商品排行、客服服務、留言評論、商品品牌展示、會員註冊及登錄等;

後臺系統主要有: 商品管理、用戶管理、活動管理、訂單管理、WMS(倉庫管理系統)、財務管理、報表統計、系統管理、運營管理、店鋪管理、支付管理、推廣管理等

其實當時我主要負責的也挺多模塊的,前臺系統裡面有購物車(redis)、商品信息搜索框(solr)、商品秒殺、留言評論(MongoDB);後臺系統這一塊我主要負責WMS(倉庫管理)、商品管理模塊、統計分析模塊、推廣管理模塊、權限的管理、訂單管理(拆單)、財務管理。

本系統前臺界面設計採用的easyUI的設計,後臺採用springMVC、spring、mybatis框架,maven管理的多模塊項目,採用java語言編程。

我在項目中除了主要負責的購物車模塊和訂單模塊之外,對其它模塊也是有一定的瞭解的.接下來我給大家介紹一下.

3:具體實現

3.1:項目的搭建

這裡採用maven多模塊管理整個項目。優勢兩點:1、maven可以管理整個項目工程,方便熱部署項目,項目發佈方便。2、maven管理jar包具有很大的優勢,可以自動下載所需的jar包,只需定義好版本即可,其他maven自動下載。

下面就是利用SSM框架來搭建工程了:利用框架搭建工程主要分兩步:框架所依賴的jar包,框架的配置文件。弄清了這兩點就好辦了。框架主要分三層:mapper層(mybatis)(主要是與數據庫交互)、service層(spring)(主要是負責調用dao/mapper層,實現業務邏輯的編寫)、controller層(springMVC)(這裡主要調用service層,根據jsp頁面的內容,將jsp的內容傳遞到service層,然後將數據顯示到jsp頁面)。所以這裡的配置文件也就有:spring將mybatis整合起來的spring-common.xml(配置數據源,與數據庫的連接),另外配置了jdbc.properties(把鏈接數據庫配置信息提取出來方便管理),spring-base.xml(將service的文件包引入工程,以及配置事務管理器),還有spring-mvc.xml(註解掃描,前端控制器,視圖解析器),還有log4j.properties(日誌記錄)。

框架搭建完成後,利用mybatis的逆向工程(generator)生成各個表的model文件。

3.2具體的功能的實現邏輯

(1)後臺系統功能實現

(這裡主要講商品的查詢、添加)

其實對於功能模塊的分析主要有三點:

從哪個數據表獲取(主要mapper實現);頁面傳遞是否有參數,頁面的url是什麼(controller實現);返回值是什麼(即頁面展示的格式是什麼樣子的,這個根據jsp使用的框架來決定,比如這裡的easyUI,可以查詢它的api文檔,找到其返回值類型);

A、商品的查詢邏輯分析:其實對於商品的查詢主要就是從數據庫中將所有商品查詢出來。這簡單的查詢很簡單,可是在頁面分頁顯示出來這就是一個問題了。這裡到了mybatis的分頁插件pageHelper來實現。

傳入參數:Easyui頁面默認有page、rows參數傳遞。

返回值:easyui的格式即datagrid的格式,專門編寫一個對應的pojo類放入專門工具類中使用,返回格式即這個pojo。

邏輯:mapper層:mapper層用mybatis的逆向工程

Service調用mapper的查詢和分頁實現邏輯。

Controller即將參數傳遞過去,url寫好

B、商品添加:商品添加即將商品信息寫入數據庫,頁面傳遞的內容當點擊提交按鈕時直接寫入數據庫,只需補全沒有的字段即可。

這裡涉及到商品的類目選擇、上面的圖片上傳、商品的描述信息。

類目選擇首先得將類目展示出來,這裡使用的異步樹的格式。查詢api發現異步樹的返回值的格式。主要思路是:根據parentId來查詢類目表,默認從0開始,異步樹有個特點,就是每次獲取到的id,如果有子節點,會發送url再次請求,如果沒有子節點則不發送請求,所以可以都遍歷到所有節點。(這個是tree的特點,自動請求)

異步樹的特點:從最頂層開始讀取,先讀頂層節點,如果是閉合狀態,發送請求給服務器讀取子節點,子節點的狀態依賴於父節點,當展開一個封閉的節點時,如果節點沒有加載子節點,它將會把節點的id的值作為http請求參數並命名為id,通過url發送到服務器上檢索子節點。所以遍歷一次後,如果父節點還是父節點(即存在子節點)則檢索下面的子節點的內容,將子節點的id作為parentId來檢索下面的節點。如果不是父節點了,則打開下面列表。也就是說這些實現都是 異步樹自動實現的,我們只需要判斷父節點的狀態即可,下面的檢索根據這個狀態進行。

圖片上傳功能:因為商城的圖片非常多,所以我們將這麼多的圖片保存在圖片服務器中,然後將圖片在服務器中的具體url寫入數據庫,供前臺調用。前臺獲取到這個url既可獲取到這個圖片。這裡圖片上傳到服務器的功能:先生成圖片的名稱,然後生成圖片保存的格式,然後利用ftpUtil將圖片上傳到服務器,返回一個url鏈接。

(2)前臺功能實現

首頁大廣告位的實現:這裡是從數據庫中獲取廣告位的圖片,然後展示在頁面。但是前臺跟後臺是不一樣的端口,如何從前臺訪問後臺呢,可以使用jsonp的形式。但是我們這裡系統是採用面向服務的編程,所以採用rest風格調用後臺接口,這裡用的dubbo+zookeeper來調用接口。

(3)SSO單點登錄系統:

​ 這裡是利用了sso的接口文檔,即校驗接口、註冊、登錄接口、根據token查詢用戶接口、安全退出接口。

這個的調用服務層是利用jsonp的形式訪問的服務接口,實現跨域訪問。客戶端全部在jsp頁面實現的。

具體流程:

​ 當用戶點擊註冊的時候,跳轉到註冊頁面,即用戶信息的保存功能。檢驗用戶名是否存在、手機號和郵箱不能為空。

​ 當用戶點擊登錄按鈕的時候,用戶輸入用戶名和密碼,檢驗用戶名是否在數據庫中存在,然後用戶名密碼是否正確。這裡的密碼是用了spring的MD5加密技術。當全部成功後,給用戶頒發一個token令牌(利用uuid實現),然後將token存入到redis中(token的key是它生成的號,值是用戶的名字),然後設置在redis的過期時間。這相當於用戶的session。

然後將token寫入cookie中,前臺頁面利用jsonp調用,根據cookie中的token的值,調用sso的根據token查詢用戶的服務,查看用戶是否有效,如果有效則將用戶返回前臺頁面,前臺頁面獲取用戶的用戶名顯示在首頁,表示***已登陸。

這裡的cookie是設置了共享域,即全部子系統都可以訪問到cookie。

當用戶登錄其他子系統時,先從從cookie中獲取token信息,根據token信息獲取用戶信息,判斷用戶信息是否有效,如果有效則放行,如果無效,則利用攔截器攔截跳轉到登錄頁面。用戶再次登錄的時候刷新redis的時間,重新設置有效期。

(4)購物車功能:

將商品加入到購物車,當用戶沒有登錄的時候,也可以將商品加入到購物車,是將商品信息加入到客戶端瀏覽器的cookie當中,當用戶點擊加入購物車按鈕的時候,會向後臺提交一個請求把商品的ID和要加入的數量傳遞過去,首先獲取到cookie當中購物車商品的信息,判斷是否有商品,如果有,在根據商品ID和前臺傳入的商品ID進行比較,看是否有同一商品,如果有則直接在原有的數量少加上傳遞的數量即可,如果沒有,則設置商品數量並將商品加入到list集合當中,然後把list集合轉化為json數據放入cookie當中,並設置cookie的有效時間,

cookie數據是存在客戶端瀏覽器上,cookie也可以存放一些信息,用到的時候直接從cookie當中取,可以減輕服務器的壓力。

使用cookie的好處:1、實現簡單 ,2、不需要佔用服務端存儲空間。

缺點:1、存儲容量有限, 2、更換設備購車信息不能同步 3、Cookie禁用,不提供保存。

項目採用的是maven的多模塊構建,各個模塊之間調用就需要用到中間件,我們採用的是dubbo+zookeeper作為中間件,Dubbo是alibaba開源的分佈式服務框架,它最大的優點可以使各層之間解耦,提高項目的拓展性,dubbo中有:Provider: 暴露服務的服務提供方。Consumer: 調用遠程服務的服務消費方。Registry: 服務註冊與發現的註冊中心。Monitor: 統計服務的調用次數和調用時間的監控中心。Container: 服務運行容器。服務容器負責啟動,加載,運行服務提供者,服務提供者在啟動時,向註冊中心註冊自己提供的服務,註冊中心採用的是zookeeper,需要在配置文件中配置服務,分別有服務註冊者名稱,服務提供者的地址,暴露的端口號,以及提供服務的接口和實現類,服務消費者在啟動時,向註冊中心訂閱自己所需的服務,註冊中心返回服務提供者地址列表給消費者,服務消費者根據地址列表找到對應的服務提供者完成相應的調用。

當用戶登錄賬號之後,會將cookie當中購物車中的商品同步到該賬號中,把cookie當中的商品信息傳入到後臺,與原有的購物車中商品信息進行比對,有相同的商品的話直接在原有的數量上加上cookie中該商品的數量,如果沒有則直接加入,購物車中的信息可以存放在數據庫中也可以放在redis緩存中,這裡採用了redis緩存,因為用戶可能會頻繁的更新購物車信息,如果將購物車商品數據放在數據庫中的話會增加數據庫的壓力,所以採用了redis緩存,redis是一個高性能的key/value分佈式內存數據庫,基於內存運行,還支持數據的持久化,redis不僅僅支持簡單的key/value類型的數據,同時還提供了String、list、set、zset、hash等數據結構的存儲,還支持數據的備份,主從同步等。

redis提供了兩種持久化方式,一種是rdb,一種是aof:RDB方式是一種快照式的持久化方法,將某一時刻的數據持久化到磁盤中redis在進行數據持久化的過程中,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,才會用這個臨時文件替換上次持久化好的文件。正是這種特性,讓我們可以隨時來進行備份,因為快照文件總是完整可用的。對於RDB方式,redis會單獨創建(fork)一個子進程來進行持久化,而主進程是不會進行任何IO操作的,這樣就確保了redis極高的性能。如果需要進行大規模數據的恢復,且對於數據恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。。aof:AOF方式是將執行過的寫指令記錄下來,在數據恢復時按照叢前到後的順序再將指令執行一遍。AOF命令以redis協議追加保存每次寫的操作到文件末尾.Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大.默認的AOF持久化策略是每秒鐘fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中),因為在這種情況下,redis仍然可以保持很好的處理性能,即使redis故障,也只會丟失最近1秒鐘的數據。如果在追加日誌時,恰好遇到磁盤空間滿、inode滿或斷電等情況導致日誌寫入不完整,也沒有關係,redis提供了redis-check-aof工具,可以用來進行日誌修復

rdb優點:1.RDB是一個單一的緊湊文件,它保存了某個時間點得數據集,非常適用於數據集的備份,比如你可以在每個小時報保存一下過去24小時內的數據,同時每天保過去30天的數據,這樣即使出了問題你也可以根據需求恢復到不同版本的數據集.2.RDB是一個緊湊的單一文件,方便傳送,適用於災難恢復.3.RDB在保存RDB文件時父進程唯一需要做的就是fork出一個子進程,接下來的工作全部由子進程來做,父進程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.4.與AOF相比,在恢復大的數據集的時候,RDB方式會更快一些.

缺點:1.Redis意外宕機,可能會丟失幾分鐘的數據(取決於配置的save時間點)。RDB方式需要保存整個數據集,是一個比較繁重的工作,通常需要設置5分鐘或者更久做一次完整的保存。2.RDB 需要經常fork子進程來保存數據集到硬盤上,當數據集比較大的時候,fork的過程是非常耗時的,可能會導致Redis在一些毫秒級內不能響應客戶端的請求.如果數據集巨大並且CPU性能不是很好的情況下,這種情況會持續更久。

aof優點:1.使用AOF 會讓Redis數據更加耐久: 你可以使用不同的fsync策略:無fsync,每秒fsync,每次寫的時候fsync.使用默認的每秒fsync策略,Redis的性能依然很好(fsync是由後臺線程進行處理的,主線程會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的數據.2.AOF文件是一個只進行追加的日誌文件,所以不需要寫入seek,即使由於某些原因(磁盤空間已滿,寫的過程中宕機等等)未執行完整的寫入命令,你也也可使用redis-check-aof工具修復這些問題.3.Redis 可以在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫: 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。 整個重寫操作是絕對安全的,因為 Redis 在創建新 AOF 文件的過程中,會繼續將命令追加到現有的 AOF 文件裡面,即使重寫過程中發生停機,現有的 AOF 文件也不會丟失。 而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。4.AOF 文件有序地保存了對數據庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式保存, 因此 AOF 文件的內容非常容易被人讀懂, 對文件進行分析也很輕鬆

缺點:1.對於相同的數據集來說,AOF 文件的體積通常要大於 RDB 文件的體積。2.根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。 在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間。

aof同步策略有三種,分別為always everysec no 重寫機制相同數據集的數據而言aof文件要遠大於rdb文件,恢復速度慢與rdb;Aof運行效率要慢與rdb,每秒同步策略效率較好,

在項目當中用jedis鏈接redis,配置IP和端口號,通過redis命令來操作完成相應的功能。

(5)訂單模塊:

訂單的創建需要用戶登錄,這裡用到了攔截器在springMVC中配置下攔截方式即可。

去購物車結算,判斷是否登陸,使用攔截器攔截,實現HandlerInterceptor,從cookie中獲取token,如果沒有token,跳轉到登陸頁面,並拼接url傳遞到登陸頁面,如果有token,通過token查詢redis中有沒有用戶信息,如果沒有,或過期,都返回登陸頁面,否則,則登陸跳轉到訂單頁面

1)訂單創建邏輯:

當點擊去購物車結算時,顯示購物車的列表,當選中購物車的商品點擊去結算的時候,顯示商品的提交訂單之前的一系列信息(也就是結算頁):針對數據庫三張表:訂單基本信息表、訂單明細表(購買的商品信息)、訂單配送(收貨人的地址電話信息)

傳入參數:因為創建訂單也就是向數據庫中插入一系列的信息,而對應的是數據庫中的三個表,所以根據頁面的內容,傳入的參數也就是三個pojo類,然後頁面填寫的+補全頁面上在數據庫中沒有的字段。所以主要是對數據庫中的三個表進行插入操作。服務接口是負責接收這三個pojo類,所以客戶端要想辦法將這三個pojo類傳遞過來。

根據接口文檔,返回的是一個json格式的數據,即這三張表的數據是在一個json串中,所以這裡要想辦法將這三個表單獨建立一個pojo來保存這個返回值。這樣就將三個表放到了一個pojo類中

接下來就是數據的插入操作了,這個在service層實現:逐個表的插入數據庫即可,然後返回一個訂單號即訂單的id。

controller層傳遞的就是這個pojo類,然後返回給客戶端。

客戶端也是將這個pojo類傳遞給服務接口,返回一個訂單號給客戶端。提交訂單的時候顯示訂單提交成功頁面時候,看下jsp頁面顯示哪些字段,然後用ModelMap傳遞給頁面

2)攔截器配置使用:

<!--攔截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--攔截所有order請求-->
<mvc:mapping path="/order/**"/>
<!--配置攔截器的實現類-->
<bean class="com.mr.order.interceptor.OrderInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>

去購物車結算,判斷是否登陸,使用攔截器攔截,實現HandlerInterceptor,從cookie中獲取token,如果沒有token,跳轉到登陸頁面,並拼接url傳遞到登陸頁面,如果有token,通過token查詢用戶信息,如果未登陸,或過期,都返回登陸頁面,否則,則登陸跳轉到訂單頁面

(6)秒殺系統

因為秒殺活動只是我們網站營銷的一個附加活動,這個活動具有短時間、高併發的特點,如果和原有的網站部署在一起的話,必然會對現有的業務造成衝擊,稍有不慎有可能會導致整個網站崩潰,所以我們會將這個模塊獨立部署。用戶在秒殺開始前,為了保證不錯過秒殺的機會,會不停的刷新瀏覽器頁面,這樣會不停的訪問應用服務器、和數據庫,從而對服務器和數據庫造成一定的壓力,所以我們不使用原來商品的詳情頁面,重新設計了秒殺商品的頁面,並將頁面靜態化,這樣用戶的請求就不會經過應用服務。我們還需要租賃服務器寬帶,然後再秒殺活動開始之前,用戶只能瀏覽秒殺的商品不能購買,我們可以將購買按鈕設置成灰色,無法點擊,為了避免用戶直接訪問下單頁面,我們可以在下單頁面URL前加入由服務端生成的隨機數作為參數,只有在秒殺活動開始時才會生成,這樣即使是秒殺系統的開發者也無法在秒殺活動開始前訪問下單頁面。然後利用springMVC定時器來控制秒殺時間.

(7)商品信息搜索框(solr):

我當時做商品信息查詢搜索框的時候,因為我們是電商項目考慮到商品的數據量比較大,普通的搜索查詢需要到數據庫進行查詢,加大了數據庫的壓力,所以我採用的是solr搜索引擎,solr是一個基於Lucene的全文搜索服務器,相比Lucene更高效、使用更便捷,在進行模糊匹配的時候,他可以 用來替代數據庫中的like ,從而在匹配準確性以及性能進行大幅度的提高。在建立索引的時候我們通過在schema.xml配置IK分詞器來完成中文分詞。 從而實現了高亮顯示關鍵詞,分頁,排序,多字段,多條件的高性能搜索。在從數據中取數據生成索引的時候,因為表中的數據量比較大,防止一次取出所導致內存溢出問題,我採用了分段批量提取的方式進行,除此之外我們對後續增加的數據根據優先級的不同採取不同的策略,對於那些需要及時顯示的數據我們通過spring定時器 在短時間內(30分鐘)進行增量索引的生成,對於那些不需要及時展示的數據,我們通過spring定時器在服務器相對空閒的時候(比如每天晚上凌晨)進行索引的重新生成。

此外我們為了提高solr搜索的性能對其進行了主從配置。

被動說:

1.我們solr使用的是solr4.7版本
2.通過修改schema.xml來添加要進行索引的字段以及增加ik分詞器
3.通過solrj將數據庫中的數據生成solr中的索引文件,注:solrj是java程序調用solr服務所用的jar包。
4.通過在solrconfig.xml中配置requestHandler name=“/Replication”來進行主從同步的配置,在從solr中通過masterUrl指明要從哪些主solr服務器中同步數據

(8)留言評論

評論這一塊其實也挺重要的,他主要是指的顧客在網站上購買過該產品後,對該產品撰寫的產品評論,主要內容其實就是購買過程和使用過程的體現,還有產品本身的評價,還有物流速度,服務態度等。其實整個電商平臺很多模塊主要是圍繞著營銷來運營的,好多用戶現在就是買商品的同時,先會看一下商品評論。

商品評論這一塊主要涉及到的內容有,屬性集,產品和屬性集關聯,產品評論,另外就是和產品、產品sku關聯,評論屬性評分,產品評論和客戶,評論回覆,產品統計;另外還有就是標籤(或稱為話題),附件,匿名評論。

因為訂單交易完成後需要評論,考慮到評論不斷增加,後期評論數據比較大,所以評論這塊我們採用了mongodb數據庫,之所以採用mongodb是因為:MongoDB是NoSQL的非關係型數據庫,易於擴展,可以進行分佈式文件存儲,適用於大數據量、高併發、弱事務的互聯網應用,因此我在項目中使用它來存儲電商產品詳情頁的評論信息(評論id,商品id,標題,評分,內容,評論人信息,評論的發佈時間,評論標籤組)並且為了提高可用性和高併發用了3臺服務器做了mongodb的副本集,其中一臺作為主節點,另外兩臺作為副本節點,這樣在任何一臺mongodb服務器宕機時就會自動進行故障轉移,不會影響應用程序對mongodb的操作,為了減輕主節點的讀寫壓力過大的問題,我還對mongodb副本集做了讀寫分離,使寫操作在主節點進行,讀取操作在副本節點進行。為了控制留言,我們留言的界面設置在了訂單狀態,只有狀態為5,也就是交易成功收貨後才能評論,並在評論成功後將訂單狀態改為6。

【項目二】OA辦公系統

項目說明 :hroms人力資源外包管理系統

技術選型:

核心框架:Spring Boot

安全框架:Apache Shiro 1.3

視圖框架:Spring MVC 4.3

持久層框架:MyBatis 3.3

數據庫連接池:Druid 1.0

日誌管理:SLF4J 1.7、Log4j

頁面交互:Vue2.x

1:Shiro

Shiro簡介

apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼學和會話管理。使用Shiro的易於理解的API,您可以快速、輕鬆地獲得任何應用程序,從最小的移動應用程序到最大的網絡和企業應用程序。

主要功能

三個核心組件:Subject, SecurityManager 和 Realms.

Subject:即“當前操作用戶”。但是,在Shiro中,Subject這一概念並不僅僅指人,也可以是第三方進程、後臺帳戶(Daemon Account)或其他類似事物。它僅僅意味著“當前跟軟件交互的東西”。但考慮到大多數目的和用途,你可以把它認為是Shiro的“用戶”概念。Subject代表了當前用戶的安全操作,SecurityManager則管理所有用戶的安全操作。

SecurityManager:它是Shiro框架的核心,典型的Facade模式,Shiro通過SecurityManager來管理內部組件實例,並通過它來提供安全管理的各種服務。

Realm: Realm充當了Shiro與應用安全數據間的“橋樑”或者“連接器”。也就是說,當對用戶執行認證(登錄)和授權(訪問控制)驗證時,Shiro會從應用配置的Realm中查找用戶及其權限信息。

從這個意義上講,Realm實質上是一個安全相關的DAO:它封裝了數據源的連接細節,並在需要時將相關數據提供給Shiro。當配置Shiro時,你必須至少指定一個Realm,用於認證和(或)授權。配置多個Realm是可以的,但是至少需要一個。

Shiro內置了可以連接大量安全數據源(又名目錄)的Realm,如LDAP、關係數據庫(JDBC)、類似INI的文本配置資源以及屬性文件等。如果缺省的Realm不能滿足需求,你還可以插入代表自定義數據源的自己的Realm實現。

在項目中使用

1:導入座標

shiro-core shiro-web shiro-spring三個jar包

2:在web.xml文件中添加shiroFilter

shiro過濾器,DelegatingFilterProxy會從spring容器中找shiroFilter

filter名字叫shiroFilter,攔截所有路徑

3:自定義realm類

(1)繼承 AuthorizingRealm

​(2)重寫三個方法

getName() 獲取當前realm的名

doGetAuthorizationInfo(PrincipalCollection principals) 授權

doGetAuthenticationInfo(AuthenticationToken token) 認證

4:創建 applicationContext-shiro.xml 配置文件

1)在spring中注入自定義的realm

2)在spring中注入securityManager

在securityManager中通過property引入自定義的realm類

3)在spring中注入定義的ShiroFilter

id必須和web.xml中定義的 shiroFilter 一致

在ShiroFilter中通過property引入securityManager

定義登錄方法的訪問路徑

定義沒有授權的方法跳轉的路徑,通常是提示用戶沒有權限訪問

定義攔截的規則

anon:匿名攔截器,即不需要登錄即可訪問;一般用於靜態資源過濾;

authc:表示需要認證(登錄)才能使用; /** = authc表示所有的請求都會被shiroFilter攔截認證

logout:退出攔截器,主要屬性:redirectUrl:退出成功後重定向的地址(/);示例“/logout=logout”

5:在自定義realm中添加認證

1)從token中獲取到用戶名

2)通過用戶名去數據庫中查詢對象

3)如果不存在則返回null

4)如果存在,則將信息存放在SimpleAuthenticationInfo(當前對象、查詢的密碼、當前realm的名) ,然後將info返回;

6:登錄失敗的異常信息

1>UnknownAccountException:代表賬戶不存在

​ 2>IncorrectCredentialsException:代表密碼錯誤

7:登出

logout:退出攔截器,主要屬性:redirectUrl:退出成功後重定向的地址(/);示例“/logout=logout”

8:授權

分析三種方式

​ 1)編程式,缺點:必須進入請求方法中才能判斷是否有權限,放棄

​ 2)jsp標籤方式, 缺點:雖然在頁面上沒有顯式請求按鈕,但是可以通過瀏覽器地址欄中輸入請求訪問, 放棄

​ 3)註解方式:優點,可以在請求進入方法之前進行權限控制。 推薦

​ jsp標籤+註解結合使用

jsp標籤

首先tglib定義shiro的標籤

<shiro:authenticated> 登錄之後
<shiro:notAuthenticated> 不在登錄狀態時
<shiro:guest> 用戶在沒有RememberMe時
<shiro:user> 用戶在RememberMe時
<shiro:hasAnyRoles name="abc,123" > 在有abc或者123角色時
<shiro:hasRole name="abc"> 擁有角色abc
<shiro:lacksRole name="abc"> 沒有角色abc
<shiro:hasPermission name="abc"> 擁有權限資源abc
<shiro:lacksPermission name="abc"> 沒有abc權限資源
<shiro:principal> 顯示用戶身份名稱
<shiro:principal property="username"/> 顯示用戶身份中的屬性值

查詢sql

(1)通過用戶id查詢角色的sql

<select id="selectRolesByUserId" resultType="String">
select sn from role where id in
(select role_id from user_role where user_id = #{id})
</select>

​ (2)通過用戶id查詢權限的sql

<select id="selectPermissionByUserId" resultType="String">
select resource from permission where id in (
select permission_id from role_permission where role_id in(
select id from role where id in (
select role_id from user_role where user_id = #{id}
)))
</select>

MyRealm中的授權

獲取當前對象getPrimaryPrincipal()

通過用戶查詢相對應的權限、角色

將權限和角色放入SimpleAuthorizationInfo中

9:緩存

授權完畢之後,每次訪問都會調用授權的方法,查詢數據庫,我們可以將權限存放在緩存中,授權一次之後,再次查詢就不會再次進入授權。

1)導入jar包 ehcache-core shiro-ehcache

2)配置緩存管理器 引入了shiro-ehcache.xml

3)securityManager中添加緩存管理器

4)添加 shiro-ehcache.xml 緩存的配置

清空緩存:

如果用戶正常退出,緩存自動清空。

如果用戶非正常退出,緩存自動清空。

如果修改了用戶的權限,而用戶不退出系統,修改的權限無法立即生效。

當用戶權限修改後,用戶再次登陸shiro會自動調用realm從數據庫獲取權限數據,如果在修改權限後想立即清除緩存則可以調用realm的 clearCache 方法清除緩存。

10:加密

1:先修改數據庫中的密碼為密文

使用md5加密,加上鹽值,還有加密的次數,防止暴力破解

2:在配置文件中添加加密器

3:在自定義realm的bean中引入加密器

4:認證方法中添加鹽值

11:shiro框架與springboot整合

1.Pom.xml中導入shiro-spring依賴。

2.在Application能掃描到的包下創建一個配置類(@Configuration),在該類中分別聲明1.(@Bean)ShiroFilterFactoryBean(shiro過濾器工廠,

filterChainDefinitionMap.put來寫入需要被攔截的路徑(key)及訪問所需權限(value).

配置不被攔截的路徑(util/**,anon),

登錄路徑shiroFilterFactoryBean.setLoginUrl(/login),

登錄成功後跳轉路徑shiroFilterFactoryBean.setSuccessUrl(/index)等等

),

myShiroRealm(自定義的Realm類)

hashedCredentialsMatcher憑證匹配器(散列方法,次數)

securityManager(安全管理器)

開啟shiro aop註解支持。

3.自定義myShiroRealm類。與Spring整合的寫法一致,繼承AuthorizingRealm抽象類,重載doGetAuthenticationInfo(),重寫獲取用戶信息的方法(用token的username信息到數據庫取出User對象,拿該對象的username,userpwd,solt,及該realm的name進行認證)以及獲取用戶權限的方法(將用戶保存在數據庫中的角色信息及權限信息加到用戶信息中)。

【項目三】P2P網貸

我最近做了一個P2P網貸的項目。這個項目主要目的是針對個體(個人、企業或組織)和個體之間通過互聯網平臺實現的直接借貸。整個項目分為前臺系統(用戶訪問平臺)與後臺管理系統兩個項目。

前臺項目主要涉及的模塊:是債券模塊(展示債券以及用戶購買時生成訂單)、出借模塊、借款模塊、推廣模塊、信息披露模塊、用戶管理模塊(登錄註冊、個人中心)。判斷如果為新用戶還涉及到一個新手引導流程。

後臺系統的模塊:則分為用戶管理模塊,業務管理模塊(債券的發佈、上下架及調整、合同的POI導出),推廣管理模塊、統計管理模塊(HighCharts報表完成用戶登錄及註冊次數的統計、每日購買量的統計、資金統計等等)基本設置(前臺信息披露模塊中展示的公司基本信息)、財務管理(主要涉及到用戶充值管理,線下充值,提現管理,用戶信用管理,用戶擔保管理,不良債權轉讓管理,商城的退款管理,平臺調賬管理)等等。

我在項目中主要負責的是前臺的債券模塊、出借模塊、借款模塊、業務管理、財務管理模塊。

2.1債券模塊:

首先是將後臺上架的債權信息展示給前臺,購買流程為當用戶點擊購買某個債權時首先判斷債券剩餘的數量是否足夠,如果足夠則生成訂單(此時訂單狀態為0未付款)並在庫存中減去相應的數量,該訂單如果在15分鐘內未完成付款操作,則自動取消。生成訂單後根據用戶錄入的銀行卡信息調出相應的銀行接口讓用戶進行付款(這裡也可以添加新的銀行卡)。用戶這邊付款後再通過銀行接口返回的流水號查詢是否付款成功。付款成功則將訂單狀態修改為1已付款,購買成功並通知用戶,同時通知後臺客服對訂單做出處理。

如果兩個用戶同時購買了100份庫存只有100的債權?

如果兩個用戶同時購買了100份庫存只有100的債權。則只會有一個用戶購買成功。因為此處使用RabbitMQ消息隊列的原因。消息隊列是根據日誌信息從左到右執行的。所以即使是同時發出了生成訂單的請求,在執行完左側生成的訂單消息之後,因為數據庫中庫存已經不夠了,所以第二個訂單生成是不會成功的。

業務管理模塊中主要涉及的有債券管理,催收管理,合同管理,借款管理。

2.2 債券管理:

比如債券的發佈、上下架及調整,當債權信息有了更新以後。在業務邏輯層直接調用前臺項目中重新生成靜態化頁面(freemarker)的方法將之前的債券展示信息替換掉。替換成功後才會提交事務,避免前臺展示的數據與後臺數據庫中的數據出現偏差。

催收管理模塊:主要是根據用戶還款的時間來及時給用戶提醒。通過定時器來每天進行一次判斷。比如說在距離還款還有一週的時候,調用短信接口(httpclient)來給用戶發送提示短信進行通知,在還款當天再次提醒用戶逾期將會產生違約金等。在逾期三天之後會提醒客服對客戶進行催收以及對催收情況的統計。逾期一個月以上的用戶可添加至黑名單。

訂單生成後會自動添加到合同列表中。在合同管理中可以進行詳情查看以及直接將合同導出為Word文檔進行打印。

借款管理:首先用戶選擇相應的借款類型,在用戶發出了借款申請後。首先是由審核部門對該用戶信用級別(黑名單中的用戶無法發出申請/信用等級越高的用戶可申請的額度就越高,同時也根據抵押物來判斷申請借款的金額)以及抵押物的一個審核。(此時默認狀態為審核中),在審核通過後狀態變更為已審核未發佈,此時業務部門可以進行該借款的發佈。發佈以後前臺用戶就可以看到該信息並且借貸給該用戶。當金額足夠以後將狀態變更為“已滿標”。同時由財務部門將錢打給申請借款的用戶。

2.3 財務管理:

我在這個模塊中主要負責充值管理,線下充值,提現管理這幾個模塊。

充值管理與線下充值管理:主要是對用戶充值到此平臺上的金額的一個記錄的展示。考慮到安全問題,在該平臺中只能對它進行查詢而不能進行更改操作。且在該用戶餘額進行購買債券或借出操作時會有一個審核。

提現管理:用戶在前臺系統發出提現申請後,該條信息就會在提現管理中展示出來(狀態為:申請提現),首先由業務部門核實後更改狀態為(已審核,未打款),然後由財務部門進行打款。將狀態更改為已提現。

後臺管理系統包括:會員管理,業務管理,系統管理,財務管理,統計管理,推廣管理等主要模塊

2.4會員管理:

是對會員信息統計和管理(包括個人信息,企業信息,機構信息),會員的認證管理,留言管理等。

會員認證管理:通過該功能新註冊用戶可以通過必要的用戶認證後獲得非0的借款信用額度而擁有有效的借款申請權限,在通過非必須、額外的用戶認證來更進一步提高用戶的借款信用額度,使用戶可以在同一時間取得更大額度的借款。

必要的用戶認證:主要包括:身份證認證,工作認證,收入認證,芝麻信用報告認證等。

額外的用戶認證:主要包括:學歷認證,房產認證,技術職稱認證,購車證明等。

留言管理:主要是針對會員在“幫助中心”的留言,及時進行恢復。

2.5 業務管理:

是我們網貸的核心模塊,主要有理財管理,借款管理,催收管理,合同管理等

2.6 理財管理:

有在線債券的管理和線上債券的轉讓管理。

2.7 借款管理:

有借款管理、個人借款意向管理和企業借款意向管理。借款管理中主要是負責對借款申請的審批(主要負責審查用戶的借款類型和抵押物以及其他申請是否合理),並負責在前臺展示借款信息的頁面進行招標。招收到的資金已滿的話,後臺進行審核後,做放款處理。

2.8 催收管理:

代還款列表,催收記錄,黑名單。

代還款列表展示的是借貸用戶的信息,便於後臺人員的統計和催收的通知,催收的實現使用的是定時器+Webservice來實現的,正常還款的用戶通過使用定時器,在還款期限前三天通過調用Webservice短信接口,發送短信給用戶,提醒用戶還款。對於逾期3—7天用戶,通過定時器實現線上的催收(發送短信,還款期限已逾期),對於逾期7天以上的用戶,通過定時器通知後臺管理人員,通過Poi技術導出相對應的逾期用戶信息,通過線下催款的方式催收貸款。對於嚴重逾期的用戶,線下催收的同時加入黑名單,不在提供服務給該用戶。

2.9 系統管理:

主要有後臺賬號,系統日誌,業務推廣等,需要使用shiro權限框架.

後臺賬號主要分為業務員賬號管理,管理員賬號管理,用戶賬號管理等,在這模塊中要實現登錄用戶的權限限制。

因為涉及到資金的安全,所以我們做了日誌記錄的統計,所有增刪改的操作都要生成相應的日誌,做一個日誌的統計,方便責任到人。

業務推廣板塊主要是對一些活動的推廣,發送郵件和站內推廣信給用戶。

2.10 財務管理:

主要有資金管理,資金明細等。

資金管理中包括:充值管理,線下充值管理,提現管理,放款管理,用戶信用管理,用戶擔保管理等

資金的明細主要是對平臺資金的流向做相應的統計,通過Poi導出到做線下的會議使用。

2.11 統計管理:

主要有用戶統計,資金統計,業務統計,統計報表等(使用highcharts技術),主要用於業務的推廣方式。

用戶統計:主要是針對用戶註冊的方式的統計,方便後期的業務推廣。

資金統計:是看平臺的資金的流動情況和盈虧情況。

業務統計:平臺業務情況的查看,以及業務後期的推廣重心。

2.12 推廣管理:

推廣獎勵,獎勵金管理,活動管理等。

"

相關推薦

推薦中...