摘要:序列化的類可顯式聲明的值,這個(gè)中定義異常和中定義方式幾乎一樣。工具類初始化是為每個(gè)序列化類產(chǎn)生的版本標(biāo)識(shí),可用來保證在反序列時(shí),發(fā)送方發(fā)送的和接受方接收的是可兼容的對(duì)象。
common.exception、annotation、node、page 說明
如果您有幸能看到,請(qǐng)認(rèn)閱讀以下內(nèi)容;
1、本項(xiàng)目臨摹自abel533的Guns,他的項(xiàng)目 fork 自 stylefeng 的 Guns!開源的世界真好,可以學(xué)到很多知識(shí)。
2、版權(quán)歸原作者所有,自己只是學(xué)習(xí)使用。跟著大佬的思路,希望自己也能變成大佬。gogogo》。。
3、目前只是一個(gè)后臺(tái)模塊,希望自己技能增強(qiáng)到一定時(shí),可以把stylefeng 的 [Guns]融合進(jìn)來。
4、note里面是自己的學(xué)習(xí)過程,菜鳥寫的,不是大佬寫的。內(nèi)容都是大佬的。
異常1、首先來看所有業(yè)務(wù)異常的枚舉類,看異常大概就能知道這個(gè)系統(tǒng)主要完成那些業(yè)務(wù)邏輯。
/** * 所有業(yè)務(wù)異常的枚舉 */ public enum BizExceptionEnum { /** * 字典 */ DICT_EXISTED(400,"字典已經(jīng)存在"), ERROR_CREATE_DICT(500,"創(chuàng)建字典失敗"), ERROR_WRAPPER_FIELD(500,"包裝字典屬性失敗"), /** * 文件上傳 */ FILE_READING_ERROR(400,"FILE_READING_ERROR!"), FILE_NOT_FOUND(400,"FILE_NOT_FOUND!"), UPLOAD_ERROR(500,"上傳圖片出錯(cuò)"), /** * 權(quán)限和數(shù)據(jù)問題 */ DB_RESOURCE_NULL(400,"數(shù)據(jù)庫(kù)中沒有該資源"), NO_PERMITION(405, "權(quán)限異常"), REQUEST_INVALIDATE(400,"請(qǐng)求數(shù)據(jù)格式不正確"), INVALID_KAPTCHA(400,"驗(yàn)證碼不正確"), CANT_DELETE_ADMIN(600,"不能刪除超級(jí)管理員"), CANT_FREEZE_ADMIN(600,"不能凍結(jié)超級(jí)管理員"), CANT_CHANGE_ADMIN(600,"不能修改超級(jí)管理員角色"), /** * 賬戶問題 */ USER_ALREADY_REG(401,"該用戶已經(jīng)注冊(cè)"), NO_THIS_USER(400,"沒有此用戶"), USER_NOT_EXISTED(400, "沒有此用戶"), ACCOUNT_FREEZED(401, "賬號(hào)被凍結(jié)"), OLD_PWD_NOT_RIGHT(402, "原密碼不正確"), TWO_PWD_NOT_MATCH(405, "兩次輸入密碼不一致"), /** * 錯(cuò)誤的請(qǐng)求 */ MENU_PCODE_COINCIDENCE(400,"菜單編號(hào)和副編號(hào)不能一致"), EXISTED_THE_MENU(400,"菜單編號(hào)重復(fù),不能添加"), DICT_MUST_BE_NUMBER(400,"字典的值必須為數(shù)字"), REQUEST_NULL(400, "請(qǐng)求有錯(cuò)誤"), SESSION_TIMEOUT(400, "會(huì)話超時(shí)"), SERVER_ERROR(500, "服務(wù)器異常"); 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、對(duì)業(yè)務(wù)異常的封裝,首先需要注意的是繼承自RuntimeException,之前講過了點(diǎn)這里
/** * 業(yè)務(wù)異常的封裝 */ public class BussinessException extends RuntimeException { //友好提示的code碼 private int friendlyCode; //友好提示 private String friendlyMsg; //業(yè)務(wù)異常調(diào)整頁(yè)面 private String urlPath; public BussinessException(BizExceptionEnum bizExceptionEnum) { this.friendlyCode = bizExceptionEnum.getCode(); this.friendlyMsg = bizExceptionEnum.getMessage(); this.urlPath = bizExceptionEnum.getUrlPath(); } }
3、接下來是工具類初始化異常,需要注意serialVersionUID的作用:
1、serialVersionUID 是 Java 為每個(gè)序列化類產(chǎn)生的版本標(biāo)識(shí),可用來保證在反序列時(shí),發(fā)送方發(fā)送的和接受方接收的是可兼容的對(duì)象。
2、如果接收方接收的類的 serialVersionUID 與發(fā)送方發(fā)送的 serialVersionUID 不一致,進(jìn)行反序列時(shí)會(huì)拋出 InvalidClassException。
3、序列化的類可顯式聲明 serialVersionUID 的值,
這個(gè)中定義異常和PayMap中定義方式幾乎一樣。
/** * 工具類初始化 */ public class ToolBoxException extends RuntimeException { //serialVersionUID 是 Java 為每個(gè)序列化類產(chǎn)生的版本標(biāo)識(shí),可用來保證在反序列時(shí),發(fā)送方發(fā)送的和接受方接收的是可兼容的對(duì)象。 // 如果接收方接收的類的 serialVersionUID 與發(fā)送方發(fā)送的 serialVersionUID 不一致,進(jìn)行反序列時(shí)會(huì)拋出 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)); } } -------------------------------------------------------------------------------- /** * 驗(yàn)證碼錯(cuò)誤異常 * * @Author guo //這個(gè)模板不錯(cuò) * @Date 2018-03-04 12:04. */ public class InvalidKaptchaException extends RuntimeException { }注解
4、最后在看下自定義注解
元注解:
元注解的作用就是負(fù)責(zé)注解其他注解。Java5.0定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation類型,它們被用提供對(duì)其他annotation類型的說明。
1、@Target
2、@Retention
3、@Documented
4、@Inherited
-
@Target
作用:用于描述注解的使用范圍(即:被描述的注解可以用在什么地方)
取值(ElementType)有:
1.CONSTRUCTOR:用于描述構(gòu)造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部變量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述參數(shù)
7.TYPE:用于描述類、接口(包括注解類型) 或enum聲明
@Retention
作用:表示需要在什么級(jí)別保存該注釋信息,用于描述注解的生命周期(即:被描述的注解在什么范圍內(nèi)有效)
取值(RetentionPoicy)有:
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留)
@Documented
作用:用于描述其它類型的annotation應(yīng)該被作為被標(biāo)注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。
@Inherited
@Inherited元注解是一個(gè)標(biāo)記注解,@Inherited闡述了某個(gè)被標(biāo)注的類型是被繼承的。如果一個(gè)使用了@Inherited修飾的annotation類型被用于一個(gè)class,則這個(gè)annotation將被用于該class的子類。
接下來,我們?cè)诳醋远x注解
/** * 權(quán)限注解,用于檢查權(quán)限 規(guī)定訪問權(quán)限 */ @Inherited @Retention(RetentionPolicy.RUNTIME) //運(yùn)行時(shí)有效 @Target({ElementType.METHOD}) //方法范圍 public @interface Permission { String[] value() default {}; } ------------------------------------------------------- /** * 多數(shù)據(jù)源標(biāo)識(shí) */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) public @interface DataSource { } --------------------------------------------------------- /** * 標(biāo)記需要做業(yè)務(wù)日志的方法 */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @interface BussinessLog { /** * 業(yè)務(wù)的名稱,例如:"修改菜單" */ String value() default ""; /** * 被修改的實(shí)體的唯一標(biāo)識(shí),例如:菜單實(shí)體的唯一標(biāo)識(shí)為"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 插件的節(jié)點(diǎn) */ public class ZTreeNode { /** * 節(jié)點(diǎn)id */ private Integer id; /** * 父節(jié)點(diǎn)id */ private Integer pId; /** * 節(jié)點(diǎn)名稱 */ private String name; /** * 是否打開節(jié)點(diǎn) */ private Boolean open; /** * 是否被選中 */ private Boolean checked; //Setter、Getter、Constructor、toString忽略 }
MenuNode實(shí)現(xiàn)了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); }
/** * * 菜單的節(jié)點(diǎn) */ public class MenuNode implements Comparable { /** * 節(jié)點(diǎn)id */ private Integer id; /** * 父節(jié)點(diǎn) */ private Integer parentId; /** * 節(jié)點(diǎn)名稱 */ private String name; /** * 按鈕級(jí)別 */ private Integer levels; /** * 按鈕級(jí)別 */ private Integer ismenu; /** * 按鈕的排序 */ private Integer num; /** * 節(jié)點(diǎn)的url */ private String url; /** * 節(jié)點(diǎn)圖標(biāo) */ private String icon; /** * 子節(jié)點(diǎn)的集合 */ private Listchildren; /** * 查詢子節(jié)點(diǎn)時(shí)候的臨時(shí)集合 */ private List linkedList = new ArrayList (); }
為了方便以后查看,方法多帶帶提出來。
/** * 構(gòu)建整個(gè)菜單樹 */ public void buildNodeTree(ListzTree簡(jiǎn)單使用nodeList) { for (MenuNode treeNode : nodeList) { List linkedList = treeNode.findChildNodes(nodeList, treeNode.getId()); if (linkedList.size() > 0) { treeNode.setChildren(linkedList); } } } /** * 查詢子節(jié)點(diǎn)的集合 */ 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(); // 根據(jù)傳入的某個(gè)父節(jié)點(diǎn)ID,遍歷該父節(jié)點(diǎn)的所有子節(jié)點(diǎn) if (node.getParentId() != 0 && parentId.equals(node.getParentId())) { recursionFn(nodeList, node, parentId); } } return linkedList; } -------------------------------------------------------------------------------- /** * 遍歷一個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn) */ public void recursionFn(List nodeList, MenuNode node, Integer pId) { List childList = getChildList(nodeList, node);// 得到子節(jié)點(diǎn)列表 if (childList.size() > 0) {// 判斷是否有子節(jié)點(diǎn) 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); } } } /** * 得到子節(jié)點(diǎn)列表 */ 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; } -------------------------------------------------------------------------------- /** * 清除掉按鈕級(jí)別的資源 * * @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; } /** * 清除所有二級(jí)菜單 * * @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; } -------------------------------------------------------------------------------- /** * 構(gòu)建菜單列表 */ public static List buildTitle(List nodes) { List clearBtn = clearBtn(nodes); new MenuNode().buildNodeTree(clearBtn); List menuNodes = clearLevelTwo(clearBtn); //對(duì)菜單排序 Collections.sort(menuNodes); //對(duì)菜單的子菜單進(jìn)行排序 for (MenuNode menuNode : menuNodes) { if (menuNode.getChildren() != null && menuNode.getChildren().size() > 0) { Collections.sort(menuNode.getChildren()); } } //如果關(guān)閉了接口文檔,則不顯示接口文檔菜單 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; }
獲取所有的選擇節(jié)點(diǎn)、獲取子節(jié)點(diǎn)
// 通過id號(hào)來獲取這個(gè)樹 var treeObj2 = $.fn.zTree.getZTreeObj("treeDemo"); // 獲取所有已經(jīng)選擇了的節(jié)點(diǎn),獲得一個(gè)node列表 var nodes2 = treeObj2.getCheckedNodes(true); // 如果是葉子節(jié)點(diǎn)就把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通用分頁(yè)插件這個(gè)插件也是本項(xiàng)目大佬寫的。如果非要自己封裝也可以,但是你用過的話就不會(huì)在自己封裝了。主要是PageInfo類。
package com.guo.guns.common.page; import com.github.pagehelper.Page; import java.util.List; /** * 分頁(yè)結(jié)果的封裝(for Bootstrap Table) * * @Author guo * @Date 2018-03-04 13:47 */ public class PageInfoBTPageHelper簡(jiǎn)單使用{ /** * 結(jié)果集 */ private List rows; /** * 總數(shù) */ 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略 }
(1)1、查出第一頁(yè)的數(shù)據(jù),每頁(yè)5條:
PageHelper.offsetPage(0, 5);
(2)、獲取總數(shù):
PageInfo pageInfo = new PageInfo<>(cs); System.out.println("總數(shù):"+pageInfo.getTotal()); System.out.println(pageInfo);
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/68651.html
摘要:因?yàn)槌橄箢愄焐褪怯脕肀焕^承的。由于不支多繼承,子類不能夠繼承多個(gè)類,但可以實(shí)現(xiàn)多個(gè)接口如果基本功能在不斷改變,那么就需要使用抽象類。全局異常處理接下來,我們?cè)诳纯纯刂平y(tǒng)一的異常攔截機(jī)制。 3、Spring Boot 緩存配置、全局異常處理 說明 如果您有幸能看到,請(qǐng)認(rèn)閱讀以下內(nèi)容; 1、本項(xiàng)目臨摹自abel533的Guns,他的項(xiàng)目 fork 自 stylefeng 的 Guns!...
摘要:目前只是一個(gè)后臺(tái)模塊,希望自己技能增強(qiáng)到一定時(shí),可以把的融合進(jìn)來。目錄第一站,分析了啟動(dòng)類。看見沒,這個(gè)也是配置類,它聲明了視圖解析器地域解析器以及靜態(tài)資源的位置,想起來沒,就是前置,后置。程序啟動(dòng)類我們點(diǎn)擊源碼看看。 Guns基于SpringBoot,致力于做更簡(jiǎn)潔的后臺(tái)管理系統(tǒng),完美整合springmvc + shiro + 分頁(yè)插件PageHelper + 通用Mapper + ...
摘要:基于最新的,是你學(xué)習(xí)的最佳指南。驅(qū)動(dòng)程序通過自動(dòng)注冊(cè),手動(dòng)加載類通常是不必要。由于加上了注解,如果轉(zhuǎn)賬中途出了意外和的錢都不會(huì)改變。三的方式項(xiàng)目結(jié)構(gòu)相比于注解的方式主要有以下幾點(diǎn)改變,非常容易實(shí)現(xiàn)。公眾號(hào)多篇文章被各大技術(shù)社區(qū)轉(zhuǎn)載。 Github 地址:https://github.com/Snailclimb/springboot-integration-examples(Sprin...
摘要:也是自帶的一個(gè)基于線程池設(shè)計(jì)的定時(shí)任務(wù)類。其每個(gè)調(diào)度任務(wù)都會(huì)分配到線程池中的一個(gè)線程執(zhí)行,所以其任務(wù)是并發(fā)執(zhí)行的,互不影響。 原創(chuàng)不易,如需轉(zhuǎn)載,請(qǐng)注明出處https://www.cnblogs.com/baixianlong/p/10659045.html,否則將追究法律責(zé)任!!! 一、在JAVA開發(fā)領(lǐng)域,目前可以通過以下幾種方式進(jìn)行定時(shí)任務(wù) 1、單機(jī)部署模式 Timer:jdk中...
摘要:前言估計(jì)很多朋友都認(rèn)為參數(shù)校驗(yàn)是客戶端的職責(zé),不關(guān)服務(wù)端的事。輕則導(dǎo)致服務(wù)器宕機(jī),重則泄露數(shù)據(jù)。所以,這時(shí)就需要設(shè)置第二道關(guān)卡,服務(wù)端驗(yàn)證了。老項(xiàng)目的服務(wù)端校驗(yàn)不能為空不能為空看以上代碼,就一個(gè)的校驗(yàn)就如此麻煩。 前言 估計(jì)很多朋友都認(rèn)為參數(shù)校驗(yàn)是客戶端的職責(zé),不關(guān)服務(wù)端的事。其實(shí)這是錯(cuò)誤的,學(xué)過 Web 安全的都知道,客戶端的驗(yàn)證只是第一道關(guān)卡。它的參數(shù)驗(yàn)證并不是安全的,一旦被有心人...
閱讀 2406·2021-11-18 10:02
閱讀 1922·2021-10-13 09:40
閱讀 2999·2021-09-07 10:07
閱讀 2106·2021-09-04 16:48
閱讀 1005·2019-08-30 13:18
閱讀 2452·2019-08-29 14:03
閱讀 2922·2019-08-29 12:54
閱讀 3155·2019-08-26 11:41