国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

基于SpringBoot的后臺管理系統(異常、注解、node、page)(二)

paulli3 / 2385人閱讀

摘要:序列化的類可顯式聲明的值,這個中定義異常和中定義方式幾乎一樣。工具類初始化是為每個序列化類產生的版本標識,可用來保證在反序列時,發送方發送的和接受方接收的是可兼容的對象。

common.exception、annotation、node、page 說明

如果您有幸能看到,請認閱讀以下內容;

1、本項目臨摹自abel533的Guns,他的項目 fork 自 stylefeng 的 Guns!開源的世界真好,可以學到很多知識。

2、版權歸原作者所有,自己只是學習使用。跟著大佬的思路,希望自己也能變成大佬。gogogo》。。

3、目前只是一個后臺模塊,希望自己技能增強到一定時,可以把stylefeng 的 [Guns]融合進來。

4、note里面是自己的學習過程,菜鳥寫的,不是大佬寫的。內容都是大佬的。

異常

1、首先來看所有業務異常的枚舉類,看異常大概就能知道這個系統主要完成那些業務邏輯。

/**
 * 所有業務異常的枚舉
 */
public enum BizExceptionEnum {

    /**
     * 字典
     */
    DICT_EXISTED(400,"字典已經存在"),
    ERROR_CREATE_DICT(500,"創建字典失敗"),
    ERROR_WRAPPER_FIELD(500,"包裝字典屬性失敗"),

    /**
     * 文件上傳
     */
    FILE_READING_ERROR(400,"FILE_READING_ERROR!"),
    FILE_NOT_FOUND(400,"FILE_NOT_FOUND!"),
    UPLOAD_ERROR(500,"上傳圖片出錯"),

    /**
     * 權限和數據問題
     */
    DB_RESOURCE_NULL(400,"數據庫中沒有該資源"),
    NO_PERMITION(405, "權限異常"),
    REQUEST_INVALIDATE(400,"請求數據格式不正確"),
    INVALID_KAPTCHA(400,"驗證碼不正確"),
    CANT_DELETE_ADMIN(600,"不能刪除超級管理員"),
    CANT_FREEZE_ADMIN(600,"不能凍結超級管理員"),
    CANT_CHANGE_ADMIN(600,"不能修改超級管理員角色"),

    /**
     * 賬戶問題
     */
    USER_ALREADY_REG(401,"該用戶已經注冊"),
    NO_THIS_USER(400,"沒有此用戶"),
    USER_NOT_EXISTED(400, "沒有此用戶"),
    ACCOUNT_FREEZED(401, "賬號被凍結"),
    OLD_PWD_NOT_RIGHT(402, "原密碼不正確"),
    TWO_PWD_NOT_MATCH(405, "兩次輸入密碼不一致"),

    /**
     * 錯誤的請求
     */
    MENU_PCODE_COINCIDENCE(400,"菜單編號和副編號不能一致"),
    EXISTED_THE_MENU(400,"菜單編號重復,不能添加"),
    DICT_MUST_BE_NUMBER(400,"字典的值必須為數字"),
    REQUEST_NULL(400, "請求有錯誤"),
    SESSION_TIMEOUT(400, "會話超時"),
    SERVER_ERROR(500, "服務器異常");

    BizExceptionEnum(int code, String message) {
        this.friendlyCode = code;
        this.friendlyMsg = message;
    }

    private int friendlyCode;
    private String friendlyMsg;
    private String urlPath;
    //Setter,Getter,Constractor略
    BizExceptionEnum(int code, String message) {
        this.friendlyCode = code;
        this.friendlyMsg = message;
    }
}

2、對業務異常的封裝,首先需要注意的是繼承自RuntimeException,之前講過了點這里

/**
 * 業務異常的封裝
 */
public class BussinessException extends RuntimeException {

    //友好提示的code碼
    private int friendlyCode;

    //友好提示
    private String friendlyMsg;

    //業務異常調整頁面
    private String urlPath;

    public BussinessException(BizExceptionEnum bizExceptionEnum) {
        this.friendlyCode = bizExceptionEnum.getCode();
        this.friendlyMsg = bizExceptionEnum.getMessage();
        this.urlPath = bizExceptionEnum.getUrlPath();
    }
}

3、接下來是工具類初始化異常,需要注意serialVersionUID的作用:

1、serialVersionUID 是 Java 為每個序列化類產生的版本標識,可用來保證在反序列時,發送方發送的和接受方接收的是可兼容的對象。

2、如果接收方接收的類的 serialVersionUID 與發送方發送的 serialVersionUID 不一致,進行反序列時會拋出 InvalidClassException。

3、序列化的類可顯式聲明 serialVersionUID 的值,

這個中定義異常和PayMap中定義方式幾乎一樣。

/**
 * 工具類初始化
 */
public class ToolBoxException extends RuntimeException {
    //serialVersionUID 是 Java 為每個序列化類產生的版本標識,可用來保證在反序列時,發送方發送的和接受方接收的是可兼容的對象。
    // 如果接收方接收的類的 serialVersionUID 與發送方發送的 serialVersionUID 不一致,進行反序列時會拋出 InvalidClassException。序列化的類可顯式聲明 serialVersionUID 的值,
    private static final long serialVersionUID = 8247610319171014183L;

    public ToolBoxException(Throwable e) {
        super(e.getMessage(),e);
    }

    public ToolBoxException(String message) {
        super(message);
    }

    public ToolBoxException(String message, Throwable throwable) {
        super(message,throwable);
    }
    public ToolBoxException(String messageTemplate, Object...params) {
        super(StrKit.format(messageTemplate,params));
    }
}
--------------------------------------------------------------------------------
/**
 * 驗證碼錯誤異常
 *
 * @Author guo             //這個模板不錯
 * @Date 2018-03-04 12:04.
 */
public class InvalidKaptchaException extends RuntimeException {
}
注解

4、最后在看下自定義注解

元注解:

元注解的作用就是負責注解其他注解。Java5.0定義了4個標準的meta-annotation類型,它們被用提供對其他annotation類型的說明。

1、@Target

2、@Retention

3、@Documented

4、@Inherited

-
@Target

作用:用于描述注解的使用范圍(即:被描述的注解可以用在什么地方)

取值(ElementType)有:

1.CONSTRUCTOR:用于描述構造器

2.FIELD:用于描述域

3.LOCAL_VARIABLE:用于描述局部變量

4.METHOD:用于描述方法

5.PACKAGE:用于描述包

6.PARAMETER:用于描述參數

7.TYPE:用于描述類、接口(包括注解類型) 或enum聲明

@Retention

作用:表示需要在什么級別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內有效)

取值(RetentionPoicy)有:

1.SOURCE:在源文件中有效(即源文件保留)

2.CLASS:在class文件中有效(即class保留)

3.RUNTIME:在運行時有效(即運行時保留)

@Documented

作用:用于描述其它類型的annotation應該被作為被標注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。

@Inherited

@Inherited元注解是一個標記注解,@Inherited闡述了某個被標注的類型是被繼承的。如果一個使用了@Inherited修飾的annotation類型被用于一個class,則這個annotation將被用于該class的子類。

接下來,我們在看自定義注解

/**
 * 權限注解,用于檢查權限 規定訪問權限
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)   //運行時有效
@Target({ElementType.METHOD})         //方法范圍
public @interface Permission {
    String[] value() default {};
}
-------------------------------------------------------
/**
 * 多數據源標識
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface DataSource {
}
---------------------------------------------------------
/**
 * 標記需要做業務日志的方法
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BussinessLog {

    /**
     * 業務的名稱,例如:"修改菜單"
     */
    String value() default "";

    /**
     * 被修改的實體的唯一標識,例如:菜單實體的唯一標識為"id"
     */
    String key() default "id";

    /**
     * 字典(用于查找key的中文名稱和字段的中文名稱)
     */
    String dict() default "SystemDict";
}


5、先來看Node類的定義吧,

ZTree is an advanced jQuery "tree plug-in". The performance is excellent, it is easy to configurw (with a full set of options), and has many advanced features (that usually only come with paid software).

zTree is open source and uses the MIT license.

Supports JSON data.

Supports both static and asynchronous (Ajax) data loading.

Supports multiple instances of zTree in one page.

zTree3.0 can use lazy loading for large data, it can easily load tens of thousands of nodes in seconds even in the IE6 browser.

...

The most important is the official document to the very full(English is very important, important and important.)

ZTreeNode定義:

/**
 * jquery ztree 插件的節點
 */
public class ZTreeNode {
    /**
     * 節點id
     */
    private Integer id;
    /**
     * 父節點id
     */
    private Integer pId;
    /**
     * 節點名稱
     */
    private String name;
    /**
     * 是否打開節點
     */
    private Boolean open;
    /**
     * 是否被選中
     */
    private Boolean checked;
    //Setter、Getter、Constructor、toString忽略
}

MenuNode實現了Compareable接口,重寫了compareTo()方法完整代碼在這

@Override
public int compareTo(Object o) {
    MenuNode menuNode = (MenuNode) o;
    Integer num = menuNode.getNum();
    if (num == null) {
        num = 0;
    }
    return this.num.compareTo(num);
}
/**
 *
 * 菜單的節點
 */
public class MenuNode implements Comparable {
    /**
     * 節點id
     */
    private Integer id;
    /**
     * 父節點
     */
    private Integer parentId;
    /**
     * 節點名稱
     */
    private String name;
    /**
     * 按鈕級別
     */
    private Integer levels;
    /**
     * 按鈕級別
     */
    private Integer ismenu;
    /**
     * 按鈕的排序
     */
    private Integer num;
    /**
     * 節點的url
     */
    private String url;
    /**
     * 節點圖標
     */
    private String icon;
    /**
     * 子節點的集合
     */
    private List children;
    /**
     * 查詢子節點時候的臨時集合
     */
    private List linkedList = new ArrayList();
}

為了方便以后查看,方法多帶帶提出來。

    /**
     * 構建整個菜單樹
     */
    public void buildNodeTree(List nodeList) {
        for (MenuNode treeNode : nodeList) {
            List linkedList = treeNode.findChildNodes(nodeList, treeNode.getId());
            if (linkedList.size() > 0) {
                treeNode.setChildren(linkedList);
            }
        }
    }
    /**
     * 查詢子節點的集合
     */
    public List findChildNodes(List nodeList, Integer parentId) {
        if (nodeList == null && parentId == null)
            return null;
        for (Iterator iterator = nodeList.iterator(); iterator.hasNext(); ) {
            MenuNode node = (MenuNode) iterator.next();
            // 根據傳入的某個父節點ID,遍歷該父節點的所有子節點
            if (node.getParentId() != 0 && parentId.equals(node.getParentId())) {
                recursionFn(nodeList, node, parentId);
            }
        }
        return linkedList;
    }
--------------------------------------------------------------------------------
    /**
     * 遍歷一個節點的子節點
     */
    public void recursionFn(List nodeList, MenuNode node, Integer pId) {
        List childList = getChildList(nodeList, node);// 得到子節點列表
        if (childList.size() > 0) {// 判斷是否有子節點
            if (node.getParentId().equals(pId)) {
                linkedList.add(node);
            }
            Iterator it = childList.iterator();
            while (it.hasNext()) {
                MenuNode n = (MenuNode) it.next();
                recursionFn(nodeList, n, pId);
            }
        } else {
            if (node.getParentId().equals(pId)) {
                linkedList.add(node);
            }
        }
    }

    /**
     * 得到子節點列表
     */
    private List getChildList(List list, MenuNode node) {
        List nodeList = new ArrayList();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            MenuNode n = (MenuNode) it.next();
            if (n.getParentId().equals(node.getId())) {
                nodeList.add(n);
            }
        }
        return nodeList;
    }
--------------------------------------------------------------------------------
    /**
     * 清除掉按鈕級別的資源
     *
     * @param nodes
     * @return
     */
    public static List clearBtn(List nodes) {
        ArrayList noBtns = new ArrayList();
        for (MenuNode node : nodes) {
            if(node.getIsmenu() == IsMenu.YES.getCode()){
                noBtns.add(node);
            }
        }
        return noBtns;
    }

    /**
     * 清除所有二級菜單
     *
     * @param nodes
     * @return
     */
    public static List clearLevelTwo(List nodes) {
        ArrayList results = new ArrayList();
        for (MenuNode node : nodes) {
            Integer levels = node.getLevels();
            if (levels.equals(1)) {
                results.add(node);
            }
        }
        return results;
    }
--------------------------------------------------------------------------------
    /**
     * 構建菜單列表
     */
    public static List buildTitle(List nodes) {

        List clearBtn = clearBtn(nodes);

        new MenuNode().buildNodeTree(clearBtn);

        List menuNodes = clearLevelTwo(clearBtn);

        //對菜單排序
        Collections.sort(menuNodes);

        //對菜單的子菜單進行排序
        for (MenuNode menuNode : menuNodes) {
            if (menuNode.getChildren() != null && menuNode.getChildren().size() > 0) {
                Collections.sort(menuNode.getChildren());
            }
        }

        //如果關閉了接口文檔,則不顯示接口文檔菜單
        GunsProperties gunsProperties = SpringContextHolder.getBean(GunsProperties.class);
        if (!gunsProperties.getSwaggerOpen()) {
            List menuNodesCopy = new ArrayList<>();
            for (MenuNode menuNode : menuNodes) {
                if (Const.API_MENU_NAME.equals(menuNode.getName())) {
                    continue;
                } else {
                    menuNodesCopy.add(menuNode);
                }
            }
            menuNodes = menuNodesCopy;
        }

        return menuNodes;
    }
zTree簡單使用

獲取所有的選擇節點、獲取子節點

// 通過id號來獲取這個樹
var treeObj2 = $.fn.zTree.getZTreeObj("treeDemo");
// 獲取所有已經選擇了的節點,獲得一個node列表
var nodes2 = treeObj2.getCheckedNodes(true);
// 如果是葉子節點就把id拿出來
var idlist = [];
$.each(nodes2, function (i, item) {
    if (!item.isParent) {
        //alert(item.id + ","  + item.name);
        idlist.push(item.id);
    }
});
console.log(idlist);

6、接下來,我們看看pagehelper,Mybatis通用分頁插件這個插件也是本項目大佬寫的。如果非要自己封裝也可以,但是你用過的話就不會在自己封裝了。主要是PageInfo類。

package com.guo.guns.common.page;

import com.github.pagehelper.Page;

import java.util.List;

/**
 * 分頁結果的封裝(for Bootstrap Table)
 *
 * @Author guo
 * @Date 2018-03-04 13:47
 */
public class PageInfoBT {

    /**
     *  結果集
     */
    private List rows;

    /**
     * 總數
     */
    private long total;

    public PageInfoBT(List page) {
        this.rows = page;
        if (page instanceof Page) {
            this.total = ((Page) page).getTotal();
        } else {
            this.total = page.size();
        }
    }
  //Setter、Getter略
}
PageHelper簡單使用

(1)1、查出第一頁的數據,每頁5條:

 PageHelper.offsetPage(0, 5);

(2)、獲取總數:

PageInfo pageInfo = new PageInfo<>(cs);
System.out.println("總數:"+pageInfo.getTotal());
System.out.println(pageInfo);

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/68651.html

相關文章

  • 基于SpringBoot后臺管理系統(Encache配置、全局異常處理(重點))(四)

    摘要:因為抽象類天生就是用來被繼承的。由于不支多繼承,子類不能夠繼承多個類,但可以實現多個接口如果基本功能在不斷改變,那么就需要使用抽象類。全局異常處理接下來,我們在看看控制統一的異常攔截機制。 3、Spring Boot 緩存配置、全局異常處理 說明 如果您有幸能看到,請認閱讀以下內容; 1、本項目臨摹自abel533的Guns,他的項目 fork 自 stylefeng 的 Guns!...

    Benedict Evans 評論0 收藏0
  • 基于SpringBoot后臺管理系統(啟動類解析,開源世界真好)(一)

    摘要:目前只是一個后臺模塊,希望自己技能增強到一定時,可以把的融合進來。目錄第一站,分析了啟動類。看見沒,這個也是配置類,它聲明了視圖解析器地域解析器以及靜態資源的位置,想起來沒,就是前置,后置。程序啟動類我們點擊源碼看看。 Guns基于SpringBoot,致力于做更簡潔的后臺管理系統,完美整合springmvc + shiro + 分頁插件PageHelper + 通用Mapper + ...

    SwordFly 評論0 收藏0
  • 基于 SpringBoot2.0+優雅整合 SpringBoot+Mybatis

    摘要:基于最新的,是你學習的最佳指南。驅動程序通過自動注冊,手動加載類通常是不必要。由于加上了注解,如果轉賬中途出了意外和的錢都不會改變。三的方式項目結構相比于注解的方式主要有以下幾點改變,非常容易實現。公眾號多篇文章被各大技術社區轉載。 Github 地址:https://github.com/Snailclimb/springboot-integration-examples(Sprin...

    gghyoo 評論0 收藏0
  • SpringBoot中并發定時任務實現、動態定時任務實現(看這一篇就夠了)

    摘要:也是自帶的一個基于線程池設計的定時任務類。其每個調度任務都會分配到線程池中的一個線程執行,所以其任務是并發執行的,互不影響。 原創不易,如需轉載,請注明出處https://www.cnblogs.com/baixianlong/p/10659045.html,否則將追究法律責任!!! 一、在JAVA開發領域,目前可以通過以下幾種方式進行定時任務 1、單機部署模式 Timer:jdk中...

    BWrong 評論0 收藏0
  • SpringBoot 實戰 (十五) | 服務端參數校驗之一

    摘要:前言估計很多朋友都認為參數校驗是客戶端的職責,不關服務端的事。輕則導致服務器宕機,重則泄露數據。所以,這時就需要設置第二道關卡,服務端驗證了。老項目的服務端校驗不能為空不能為空看以上代碼,就一個的校驗就如此麻煩。 前言 估計很多朋友都認為參數校驗是客戶端的職責,不關服務端的事。其實這是錯誤的,學過 Web 安全的都知道,客戶端的驗證只是第一道關卡。它的參數驗證并不是安全的,一旦被有心人...

    QiShare 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<