springboot 快速開發的定製補充

加強 SpringBoot 快速開發工具

項目地址:https://gitee.com/sanri/web-ui
優勢:這是一個 web 通用配置的組件,即插即用,可用於新項目或私活。是對 SpringBoot 快速開發的一種補充,它內置了大量的配置來簡化開發,遵循約定高於配置原則。前端

它解決的問題:java

  • 固定了輸入輸出格式
  • 不用像公司的返回結構同樣,須要本身包裝類型,直接返回原始類型,若是須要能夠返回 void
  • 支持樹結構數據返回,能夠一個註解就轉換結構爲樹形結構
  • 若是項目中出現業務操做不符合或調用第三方出錯,可以使用異常或斷言拋出,咱們將攔截成統一格式返回
  • 自帶參數空格過濾功能,還能夠定義特殊字符和諧
  • 支持校驗器,添加了大量經常使用驗證器
  • 支持大文件分片上傳,已內置 Controller
  • 支持方法日誌參數記錄

發現BUG能夠提Issue,能夠給我發郵件,能夠加我QQ,能夠進9420技術羣討論.git

做者QQ: 2441719087web

做者郵箱: ningxiangsanri@163.comspring

9420 技術交流羣: 645576465mongodb

做者微信:sanri1993-
在這裏插入圖片描述json

項目功能

我新開的一個項目,總結了多年的開發經驗所得,它具備的功能有後端

  • 固定了輸入輸出格式前端框架

    // 普通輸出格式
    @Data
    public class ResponseDto<T> implements Serializable {
        // 0 字符串表示成功,不然失敗
        private String code = "0";
        private String message;
        private T data;
    }
    // 分頁輸出格式,是包裹在普通輸出格式中的,PageResponseDto 作爲 data 屬性
    @Data
    public class PageResponseDto<T> {
        private List<T> rows;
        private Integer total;
    }
    
    // 分頁輸入格式 
    @Setter
    public class PageParam {
        private String pageNo;
        private String pageSize;
    }
  • 對於 Controller 中的返回不用關心包裝類型,返回你所須要的類型就能夠了,對於 insert 單表操做能夠直接返回 void 微信

    示例一:

    @PostMapping("/insertUser")
    public void insertUser(User user){
        xxxService.insert(user);
    }

    它將會返回這樣的數據結構

    {
        "code":"0",
        "message":"ok",
        "data":null
    }

    示例二:

    @GetMapping("/queryUserById")
    public User queryUserById(Integer userId){
        xxxService.queryUserById(userId);
    }

    它將會返回這樣的數據結構

    {
        "code":"0",
        "message":"ok",
        "data":{
            "userId":1,
            "username":"9420"
        }
    }

    示例三:

    對於分頁數據的處理

    @GetMapping("/queryUserPage")
    public PageResponseDto<User> pageQuery(PageParam pageParam,Map<String,String> queryParams){
        PageHelper.startPage(pageParam.getPageNo(),pageParam.getPageSize());
        Page page = (Page) xxxService.pageQuery(queryParams);
        List result = page.getResult();
        long total = page.getTotal();
        return new PageResponseDto(result,total);
    }

    它將會返回這樣的數據結構

    {
        "code":"0",
        "message":"ok",
        "data":{
            "total":100,
            "rows":[{...},{...}]
        }
    }

    示例四: 樹結構返回

    對於樹型結構數據,你能夠用簡單數據返回,即原來的 List<Dto> 也能夠添加一個註解,使其成爲樹狀結構

    //rootId 指定爲根結點 id 
    @GetMapping("/treeShowMenu")
    @TreeResponse(type = MenuDto.class,rootId = "1")
    public List<Menu> treeShowMenu(){
        List<Menu> menus = new ArrayList<>();
        menus.add(new Menu(1,"全國",-1));
        menus.add(new Menu(2,"湖南",1));
        menus.add(new Menu(3,"長沙",2));
        menus.add(new Menu(4,"深圳",1));
        return menus;
    }
    // 樹狀結構消息類
    public class MenuDto extends RootTreeResponseDto<Menu> {
        public MenuDto(Menu origin) {
            super(origin);
        }
        
        @Override
        public String getId() {return origin.getId()+"";}
    
        @Override
        public String getParentId() {return origin.getPid()+"";}
    
        @Override
        public String getLabel() {return origin.getText();}
    
        @Override
        public Menu getOrigin() {return origin;}
    }

    它將返回以下數據結構

    {
        "code": "0",
        "message": "ok",
        "data": [{
            "origin": {
                "id": 1,
                "text": "全國",
                "pid": -1
            },
            "childrens": [{
                "origin": {
                    "id": 2,
                    "text": "湖南",
                    "pid": 1
                },
                "childrens": [{
                    "origin": {
                        "id": 3,
                        "text": "長沙",
                        "pid": 2
                    },
                    "childrens": [],
                    "id": "3",
                    "label": "長沙",
                    "parentId": "2"
                }],
                "id": "2",
                "label": "湖南",
                "parentId": "1"
            }, {
                "origin": {
                    "id": 4,
                    "text": "深圳",
                    "pid": 1
                },
                "childrens": [],
                "id": "4",
                "label": "深圳",
                "parentId": "1"
            }],
            "id": "1",
            "label": "全國",
            "parentId": "-1"
        }]
    }
  • 若是項目中出現業務操做不符合或調用第三方出錯,可以使用異常拋出,咱們將攔截成統一格式返回

    示例一:

    if(業務條件不知足){
        throw BusinessException.create("業務提示信息");
    }

    它將會返回這樣的數據結構,code 是隨機生成的

    {
        "code":"234234",
        "message":"業務提示信息",
        "data":null
    }

    示例二:

    自定義 code 示例方法一

    if(業務條件不知足){
        throw BusinessException.create("E007","業務提示信息");
    }

    它將會返回這樣的數據結構

    {
        "code":"E007",
        "message":"業務提示信息",
        "data":null
    }

    示例三:

    自定義 code 示例方法二

    // 配置異常代碼 
    public enum  SystemMessage implements ExceptionCause<BusinessException> {
        SIGN_ERROR(4005,"簽名錯誤,你的簽名串爲 [%s]"),;
        ResponseDto responseDto = new ResponseDto();
    
        private SystemMessage(int returnCode,String message){
            responseDto.setCode(returnCode+"");
            responseDto.setMessage(message);
        }
    
        public BusinessException exception(Object...args) {
            return BusinessException.create(this,args);
        }
    }

    使用異常

    if(業務條件不知足){
        throw SystemMessage.SIGN_ERROR.exception("簽名串");
    }

    它將會返回這樣的數據結構

    {
        "code":"4005",
        "message":"簽名錯誤,你的簽名串爲 [簽名串]",
        "data":null
    }
  • 你覺得它就這麼點能耐嗎,它還自帶參數空格過濾功能,還能夠定義特殊字符和諧

    你只須要注入一個處理器,它就能工做,注入方式以下

    @Bean("paramHandler")
    public Function paramHandler(){
        return param -> param.replace("<","《");
    }
  • 自帶了日期轉化(輸入)功能,能夠支持的日期格式有

    final String[] parsePatterns = new String[]{"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm:ss.S"};

    如今是固定這三種格式 ,後面會放開讓使用者本身配置

  • 支持校驗器,已經幫你設置好了兩個 group ,直接使用便可

    public interface Insert {
    }
    public interface Update {
    }
  • 支持大文件上傳,文件秒傳,文件驗證;你只須要配置幾個選項便可使用

    # 文件上傳的位置
     sanri.webui.upload.basePath=d:/test/
     # 臨時文件路徑 
     spring.servlet.multipart.location=d:/tmp

    或者你想上傳到別的地方,那就須要本身實現 com.sanri.web.bigfile.BigFileStorage而後注入 IOC 到容器

    @Bean
    public BigFileStorage bigFileStorage(){
        return new LocalBigFileStorage();
    }

大文件上傳的幾個接口說明

已經幫你添加了一個 controller ,用於大文件上傳,下面是接口說明

  • GET /upload/file/fileMetaData?originFileName=原始文件名&fileSize=文件大小&md5=文件 md5

返回 FileMetaData 數據,重要的數據是那個相對路徑 relativePath 由於它是接下來全部接口的入參

  • GET /upload/file/filePosition?relativePath=相對路徑

返回 文件當前上傳的大小,用於斷點續傳

  • POST /upload/file/uploadPart?relativePath=相對路徑

body 中添加 form-data 參數,file=文件
返回上傳文件位置

  • GET /upload/file/validateFile?relativePath=相對路徑&fileSize=文件大小&md5=文件 md5 值

返回文件是否正常上傳,無損壞

使用說明

引入包或下載 jar 包文件

<dependency>
    <groupId>com.sanri.web</groupId>
    <artifactId>web-ui</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

開啓快速開發

@EnableWebUI

若是想開啓大文件上傳

@EnableBigFileUpload

更新列表

update 2019/10/24 增長日誌組件

能夠爲方法標記記錄日誌功能,這是很常見的一個功能,感謝網友 東莞-隊長(qq: 1178130627) 的朋友提出

由於日誌每一個系統有各自的作法,有的可能還須要把日誌存儲到 mongodb 中去,因此不可能所有統一塊兒來,註解也是不支持繼承的;因此個人解決辦法是,我能夠幫你儘量的解析出一些參數來,但具體的實現邏輯還須要你本身來弄,框架默認會給你注入一個把日誌打印到控制檯的功能。

使用方法爲使用註解標記當前方法,它將默認使用 com.sanri.web.logmark.Slf4jLogInfoHandler 來記錄日誌

@GetMapping("/testParamTrim")
@SysLogMark
public void testParamTrim(TestParam testParam){}

兼容性說明 :

  1. 兼容 application/x-www-form-urlencoded 類型參數
  2. 兼容 application/form-data 類型參數
  3. 兼容 application/json 類型參數

固然,我會排除文件類型的參數,它太龐大了,不可能打印在日誌裏面

實現本身的日誌記錄方法:注入一個 LogInfoHandler 的 Bean 到 IOC 容器中

新增配置

# 日誌參數打印,可支持的項有 base,param,header,body
sanri.webui.logmark.showInfos=base,param,header,body

update 2019/10/25 增長經常使用驗證器和部分工具

一些經常使用校驗器和通用預覽和下載功能,比較經常使用,這裏給所有集成了

參數校驗器使用方法

// 必須爲強密碼
@NotNull
@Password(strength = Password.Strength.STRONG)
private String password;

其它經常使用驗證器

  • @UserName 驗證參數是否爲用戶名
  • @Password 驗證參數是否爲密碼
  • @IdCard18 驗證參數是否爲 18 位身份證

    能夠在 resources 目錄下放置一個區域代碼,作更強的驗證,文件名爲 areaCodes,文件內容以逗號分隔全部的區域代碼

  • @EnumIntValue@EnumStringValue 驗證參數是否爲枚舉值

增長一些文件下載,預覽方法,和 request 請求信息的獲取

@Autowired
RequestInfoHelper requestInfoHelper;
@Autowired
StreamHelper streamHelper;

修改處理器注入方式 ,使用本身的接口 ParamHandler,不使用 Function

@Bean("paramHandler")
public ParamHandler paramHandler(){
    return param -> param.replace("<","《");
}

update 2019/10/27 增長樹形數據返回

爲解決前端 mm 須要後端人員返回樹形結構數據問題,其實大部分框架已經支持簡單樹形數據,像 ztree ,但也有的前端框架是須要後端幫忙轉化一下數據結構的,因此特加此功能

這個樹形結構的轉換使用了一個快速轉換的機制,充分利用了對象在內存中地址的原理,實測在萬條數據轉換爲 10ms 左右,使用方法是先實現一個 TreeResponseDto 的類,而後在 Controller 中添加一個註解

@TreeResponse(type = MenuDto.class,rootId = "1")
相關文章
相關標籤/搜索