Guns系統學習

Guns V3.0

V3.0更新說明

  1. 單模塊拆分紅以下多模塊,guns-parent(maven父項目),guns-core(guns基礎模塊),guns-admin(guns後臺管理系統),guns-rest(rest服務模塊)
  2. 新增REST API服務,用於提供REST接口
  3. GUNS-REST服務基於JWT TOKEN鑑權機制,給予訪問者訪問資源的權限(詳情看readme下側介紹)
  4. GUNS-REST服務對傳輸過程當中的數據進行MD5簽名校驗,防止過程當中的信息被篡改,簽名過程當中利用隨機字符串進行簽名混淆(詳情看readme下側介紹)

管理系統介紹

Guns基於SpringBoot,致力於作更簡潔的後臺管理系統,完美整合springmvc + shiro + mybatis-plus + beetl!Guns項目代碼簡潔,註釋豐富,上手容易,同時Guns包含許多基礎模塊(用戶管理,角色管理,部門管理,字典管理等10個模塊),能夠直接做爲一個後臺管理系統的腳手架.css

在不用寫xml配置(V1.0)的基礎上進一步簡化項目配置,讓您更專一於業務開發!拋棄傳統spring xml的配置方式,利用springboot + javabean方式配置spring,極大簡化了pom.xml配置和spring配置.html

Guns項目代碼簡潔,註釋豐富,上手容易,同時Guns包含許多基礎模塊(用戶管理,角色管理,部門管理,字典管理等10個模塊),能夠直接做爲一個後臺管理系統的腳手架.前端

鳴謝

1.SpringBlade 2.beetl 3.mybatis-plusjava

感謝如下對Guns作出貢獻的人

1.Swifly 2.liujiliang 3.poseidon-ocean 4.扎西多頓 5.ilaotanmysql

技術討論,wiki地址

若是對項目有任何疑問或者建議,歡迎加入Guns技術交流羣:254550081(加以前請先看一遍wiki文檔,再看一遍readme)jquery

若是不喜歡SpringBoot?

若是您不喜歡用SpringBoot,或者您是一個spring初學者,您能夠切換到 Guns V1.0(點擊這裏) 分支, Guns V1.0基於spring的java bean方式配置項目,一樣簡潔易上手.git

注:SpringBoot強大的Auto Config和統一的依賴管理極大的簡化了spring配置和maven依賴,在不瞭解其都配置了哪些東西的基礎上可能會對初學者有必定困擾,因此建議初學者先看Guns V1.0web

功能簡介

  1. 用戶管理
  2. 角色管理
  3. 部門管理
  4. 菜單管理
  5. 字典管理
  6. 業務日誌
  7. 登陸日誌
  8. 監控管理
  9. 通知管理
  10. 代碼生成

使用說明

  1. 導入sql/guns.sql文件到mysql數據庫
  2. 以maven方式導入項目到ide
  3. 修改application.yml中的數據庫相關的配置,改成您本機的數據庫配置
  4. 啓動項目,管理員 帳號admin/密碼111111

如何啓動項目

Guns目前支持三種啓動方式:spring

  1. 在IDE裏運行GunsApplication類中的main方法啓動
  2. 執行以下maven命令
clean package -Dmaven.test.skip=true

並從target目錄中找到guns-1.0.0-SNAPSHOT.jar,並在jar包的目錄下執行以下java命令sql

java -jar guns-1.0.0-SNAPSHOT.jar
  1. 修改pom.xml中以下片斷
<packaging>jar</packaging>

改成

<packaging>war</packaging>

並打包放入到tomcat中執行

注意

最新版項目最低支持jdk1.8

所用框架

前端

  1. Bootstrap v3.3.6
  2. jQuery v2.1.4
  3. bootstrap-table v1.11.1
  4. layer v2.1
  5. zTree core v3.5.28
  6. WebUploader 0.1.5

後端

  1. SpringBoot 1.5.3.RELEASE
  2. MyBatis-Plus 2.0.8
  3. MyBatis 3.4.4
  4. Spring 4.3.8.RELEASE
  5. Beetl 2.7.15
  6. hibernate-validator 5.3.5.Final
  7. Ehcache 3.3.1
  8. Kaptcha 2.3.2
  9. Fastjson 1.2.31
  10. Shiro 1.4.0
  11. Druid 1.0.31

項目包結構說明

├─main
│  │  
│  ├─java
│  │   │
│  │   ├─com.stylefeng.guns----------------項目主代碼
│  │   │          │
│  │   │          ├─common----------------項目公用的部分(業務中常常調用的類,例如常量,異常,實體,註解,分頁類,節點類)
│  │   │          │
│  │   │          ├─config----------------項目配置代碼(例如mybtais-plus配置,ehcache配置等)
│  │   │          │
│  │   │          ├─core----------------項目運行的核心依靠(例如aop日誌記錄,攔截器,監聽器,guns模板引擎,shiro權限檢查等)
│  │   │          │
│  │   │          ├─modular----------------項目業務代碼
│  │   │          │
│  │   │          ├─GunsApplication類----------------以main方法啓動springboot的類
│  │   │          │
│  │   │          └─GunsServletInitializer類----------------用servlet容器啓動springboot的核心類
│  │   │
│  │   └─generator----------------mybatis-plus Entity生成器
│  │
│  ├─resources----------------項目資源文件
│  │     │
│  │     ├─gunsTemplate----------------guns代碼生成模板
│  │     │ 
│  │     ├─application.yml----------------springboot項目配置
│  │     │ 
│  │     └─ehcache.xml----------------ehcache緩存配置
│  │
│  └─webapp----------------web頁面和靜態資源存放的目錄
│

注:SpringBoot項目默認不支持將靜態資源和模板(web頁面)放到webapp目錄,可是我的感受resources目錄只放項目的配置更加簡潔,因此就將web頁面繼續放到webapp目錄了.

項目特色

  1. 基於SpringBoot,簡化了大量項目配置和maven依賴,讓您更專一於業務開發,獨特的分包方式,代碼多而不亂。
  2. 完善的日誌記錄體系,可記錄登陸日誌,業務操做日誌(可記錄操做前和操做後的數據),異常日誌到數據庫,經過@BussinessLog註解和LogObjectHolder.me().set()方法,業務操做日誌可具體記錄哪一個用戶,執行了哪些業務,修改了哪些數據,而且日誌記錄爲異步執行,詳情請見@BussinessLog註解和LogObjectHolder,LogManager,LogAop類。
  3. 利用beetl模板引擎對前臺頁面進行封裝和拆分,使臃腫的html代碼變得簡潔,更加易維護。
  4. 對經常使用js插件進行二次封裝,使js代碼變得簡潔,更加易維護,具體請見webapp/static/js/common文件夾內js代碼。
  5. 利用ehcache框架對常常調用的查詢進行緩存,提高運行速度,具體請見ConstantFactory類中@Cacheable標記的方法。
  6. controller層採用map + warpper方式的返回結果,返回給前端更爲靈活的數據,具體參見com.stylefeng.guns.modular.system.warpper包中具體類。
  7. 防止XSS攻擊,經過XssFilter類對全部的輸入的非法字符串進行過濾以及替換。
  8. 簡單可用的代碼生成體系,經過SimpleTemplateEngine可生成帶有主頁跳轉和增刪改查的通用控制器、html頁面以及相關的js,還能夠生成Service和Dao,而且這些生成項都爲可選的,經過ContextConfig下的一些列xxxSwitch開關,可靈活控制生成模板代碼,讓您把時間放在真正的業務上。
  9. 控制器層統一的異常攔截機制,利用@ControllerAdvice統一對異常攔截,具體見com.stylefeng.guns.core.aop.GlobalExceptionHandler類。
  10. 頁面統一的js key-value單例模式寫法,每一個頁面生成一個惟一的全局變量,提升js的利用效率,而且有效防止多我的員開發引發的函數名/類名衝突,而且能夠更好地去維護代碼。

基於javabean方式的spring配置

Guns以簡潔爲核心,拋棄了傳統的易錯,臃腫xml配置,採用javabean的方式配置spring,簡化了項目的配置,以下示例爲配置mybatis-plus和數據源:

@Configuration
@MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao", "com.stylefeng.guns.common.persistence.dao"})
public class MybatisPlusConfig {


    @Autowired
    DruidProperties druidProperties;


    /**
     * mybatis-plus分頁插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDialectType(DBType.MYSQL.getDb());
        return paginationInterceptor;
    }


    /**
     * druid數據庫鏈接池
     */
    @Bean(initMethod = "init")
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.coinfig(dataSource);
        return dataSource;
    }
}

業務日誌記錄原理

日誌記錄採用aop(LogAop類)方式對全部包含@BussinessLog註解的方法進行aop切入,會記錄下當前用戶執行了哪些操做(即@BussinessLog value屬性的內容),若是涉及到數據修改,會取當前http請求的全部requestParameters與LogObjectHolder類中緩存的Object對象的全部字段做比較(因此在編輯以前的獲取詳情接口中須要緩存被修改對象以前的字段信息),日誌內容會異步存入數據庫中(經過ScheduledThreadPoolExecutor類)。

beetl對前臺頁面的拆分與包裝

例如,把主頁拆分紅三部分,每一個部分單獨一個頁面,更加便於維護

<!--左側導航開始-->
    @include("/common/_tab.html"){}
<!--左側導航結束-->


<!--右側部分開始-->
    @include("/common/_right.html"){}
<!--右側部分結束-->


<!--右側邊欄開始-->
    @include("/common/_theme.html"){}
<!--右側邊欄結束-->

以及對重複的html進行包裝,使前端頁面更加專一於業務實現,例如,把全部頁面引用包進行提取

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="renderer" content="webkit" /><!-- 讓360瀏覽器默認選擇webkit內核 -->


<!-- 全局css -->
<link rel="shortcut icon" href="${ctxPath}/static/favicon.ico">
<!-- 全局js -->
<script src="${ctxPath}/static/js/jquery.min.js?v=2.1.4"></script>
<body class="gray-bg">
	<div class="wrapper wrapper-content animated fadeInRight">
		${layoutContent}
	</div>
	<script src="${ctxPath}/static/js/content.js?v=1.0.0"></script>
</body>
</html>

開發頁面時,只需編寫以下代碼便可

@layout("/common/_container.html"){
<div class="row">
    <div class="col-sm-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>部門管理</h5>
            </div>
            <div class="ibox-content">
               //自定義內容
            </div>
        </div>
    </div>
</div>
<script src="${ctxPath}/static/modular/system/dept/dept.js"></script>
@}

以上beetl的用法請參考beetl說明文檔。

對js經常使用代碼的封裝

在webapp/static/js/common目錄中,有對經常使用js代碼的封裝,例如Feng.js,其中Feng.info(),Feng.success(),Feng.error()三個方法,分別封裝了普通提示,成功提示,錯誤提示的代碼,簡化了layer提示層插件的使用。

極簡的圖片上傳方法

guns對web-upload進行二次封裝,讓圖片的上傳功能呢只用2行代碼便可實現,以下

var avatarUp = new $WebUpload("avatar");
avatarUp.init();

具體實現請參考static/js/common/web-upload-object.js

首創controller層,map+warpper返回方式

map+warpper方式即爲把controller層的返回結果使用BeanKit工具類把原有bean轉化爲Map的的形式(或者原有bean直接是map的形式),再用單獨寫的一個包裝類再包裝一次這個map,使裏面的參數更加具體,更加有含義,下面舉一個例子,例如,在返回給前臺一個性別時,數據庫查出來1是男2是女,假如直接返回給前臺,那麼前臺顯示的時候還須要增長一次判斷,而且先後端分離開發時又增長了一次交流和文檔的成本,可是採用warpper包裝的形式,能夠直接把返回結果包裝一下,例如動態增長一個字段sexName直接返回給前臺性別的中文名稱便可。

首創mybatis數據範圍攔截器,實現對數據權限的過濾

Guns的數據範圍控制是指,對擁有相同角色的用戶,根據部門的不一樣進行相應的數據篩選,若是部門不相同,那麼有可能展現出的具體數據是不一致的.因此說Guns對數據範圍控制是以部門id爲單位來標識的,如何增長數據範圍攔截呢?只需在相關的mapper接口的參數中增長一個DataScope對象便可,DataScope中有兩個字段,scopeName用來標識sql語句中部門id的字段名稱,例如deptiid或者id,另外一個字段deptIds就是具體須要過濾的部門id的集合.攔截器原理以下:攔截mapper中包含DataScope對象的方法,獲取其原始sql,並作一個包裝限制部門id在deptIds範圍內的數據進行展現.

swagger api管理使用說明

swagger會管理全部包含@ApiOperation註解的控制器方法,同時,可利用@ApiImplicitParams註解標記接口中的參數,具體用法請參考CodeController類中的用法。

@ApiOperation("生成代碼")
 @ApiImplicitParams({
         @ApiImplicitParam(name = "moduleName", value = "模塊名稱", required = true, dataType = "String"),
         @ApiImplicitParam(name = "bizChName", value = "業務名稱", required = true, dataType = "String"),
         @ApiImplicitParam(name = "bizEnName", value = "業務英文名稱", required = true, dataType = "String"),
         @ApiImplicitParam(name = "path", value = "項目生成類路徑", required = true, dataType = "String")
 })
 @RequestMapping(value = "/generate", method = RequestMethod.POST)

jwt token鑑權機制

jwt token鑑權機制是指若須要請求服務器接口,必須經過AuthController獲取一個請求令牌(jwt token),持有jwt token的用戶才能夠訪問服務器的其餘資源,若是沒有此令牌,則訪問接口會直接忽略,請求獲取jwt token時,須要攜帶credenceName和credenceCode(能夠是帳號密碼,能夠是手機號驗證碼等等),校驗credenceName和credenceCode成功後,會頒發給客戶端一個jwt token還有一個隨機字符串,用於傳輸過程當中對數據進行簽名用,簽名機制請見下面介紹.基於token的鑑權機制相似於http協議也是無狀態的,它不須要在服務端去保留用戶的認證信息或者會話信息.這就意味着基於token認證機制的應用不須要去考慮用戶在哪一臺服務器登陸了,這就爲應用的擴展提供了便利.

簽名機制

簽名機制是指客戶端向服務端傳輸數據中,對傳輸數據進行md5加密,而且加密過程當中利用Auth接口返回的隨機字符串進行混淆加密,並把md5值同時附帶給服務端,服務端通獲取數據以後對數據再進行一次md5加密,若加密結果和客戶端傳來的數據一致,則認定客戶端請求的數據是沒有被篡改的,若不一致,則認爲被加密的數據是被篡改的

常見問題答疑

  1. 爲什麼有的業務沒有service層: 部分業務比較簡單,因此就沒寫service層,寫service是爲了讓複雜業務更有條理,更清晰.
  2. 爲什麼既有dao,又有mapper: mapper是mybatis-plus自動生成的,裏邊有許多mybatis-plus加強的方法,dao是本身寫的業務,mybatis-plus自動生成代碼時會覆蓋mapper,因此就把本身寫的dao分開了,生成代碼的時候不影響
  3. 爲什麼分頁是前端實現:部分頁面由於數據量比較少,就直接用客戶端分頁了,日誌頁面的分頁是採用服務端分頁的,若是其餘業務有特別須要,能夠參考日誌的寫法

效果圖

輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明 輸入圖片說明

相關文章
相關標籤/搜索