日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

一个基于 Spring Boot 的项目骨架,拿走即用

發布時間:2025/3/20 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一个基于 Spring Boot 的项目骨架,拿走即用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??點擊上方?好好學java?,選擇?星標?公眾號

重磅資訊、干貨,第一時間送達 今日推薦:程序員入職國企,1周上班5小時,曬出薪資感嘆:騰訊當CEO也不去個人原創+1博客:點擊前往,查看更多

作者:簡單的土豆

最近使用Spring Boot 配合 MyBatis 、通用Mapper插件、PageHelper分頁插件 連做了幾個中小型API項目,做下來覺得這套框架、工具搭配起來開發這種項目確實非常舒服,團隊的反響也不錯。在項目搭建和開發的過程中也總結了一些小經驗,與大家分享一下。

在開發一個API項目之前,搭建項目、引入依賴、配置框架這些基礎活自然不用多說,通常為了加快項目的開發進度(早點回家)還需要封裝一些常用的類和工具,比如統一的響應結果封裝、統一的異常處理、接口簽名認證、基礎的增刪改差方法封裝、基礎代碼生成工具等等,有了這些項目才能開工。

然而,下次再做類似的項目上述那些步驟可能還要搞一遍,雖然通常是拿過來改改,但是還是比較浪費時間。所以,可以利用面向對象抽象、封裝的思想,抽取這類項目的共同之處封裝成了一個種子項目(估計大部分公司都會有很多類似的種子項目),這樣的話下次再開發類似的項目直接在該種子項目上迭代就可以了,減少無意義的重復工作。

在相關項目上線之后,我花了點時間對該種子項目做了一些精簡,并且已經把該項目分享到GitHub上面了,如果你正準備做類似項目的話,可以去克隆下來試試。

附上我歷時三個月總結的?Java 面試 + Java 后端技術學習指南,這是本人這幾年及春招的總結,目前,已經拿到了大廠offer,拿去不謝!

下載方式

1.?首先掃描下方二維碼

2.?后臺回復「Java面試」即可獲取

項目地址&使用文檔:https://github.com/lihengming/spring-boot-api-project-seed 。

如果在使用中發現問題或者有什么好建議的話歡迎提issue或pr一起來完善它。

特征&提供

最佳實踐的項目結構、配置文件、精簡的POM

注:使用代碼生成器生成代碼后會創建model、dao、service、web等包。

統一響應結果封裝及生成工具

/***?統一API響應結果封裝*/ publicclass?Result?{privateint?code;private?String?message;private?Object?data;public?Result?setCode(ResultCode?resultCode)?{this.code?=?resultCode.code;returnthis;}//省略getter、setter方法 } /***?響應碼枚舉,參考HTTP狀態碼的語義*/ publicenum?ResultCode?{SUCCESS(200),//成功FAIL(400),//失敗UNAUTHORIZED(401),//未認證(簽名錯誤)NOT_FOUND(404),//接口不存在INTERNAL_SERVER_ERROR(500);//服務器內部錯誤publicint?code;ResultCode(int?code)?{this.code?=?code;} } /***?響應結果生成工具*/ publicclass?ResultGenerator?{privatestaticfinal?String?DEFAULT_SUCCESS_MESSAGE?=?"SUCCESS";public?static?Result?genSuccessResult()?{returnnew?Result().setCode(ResultCode.SUCCESS).setMessage(DEFAULT_SUCCESS_MESSAGE);}public?static?Result?genSuccessResult(Object?data)?{returnnew?Result().setCode(ResultCode.SUCCESS).setMessage(DEFAULT_SUCCESS_MESSAGE).setData(data);}public?static?Result?genFailResult(String?message)?{returnnew?Result().setCode(ResultCode.FAIL).setMessage(message);} }

統一異常處理

public?void?configureHandlerExceptionResolvers(List<HandlerExceptionResolver>?exceptionResolvers)?{exceptionResolvers.add(new?HandlerExceptionResolver()?{public?ModelAndView?resolveException(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler,?Exception?e)?{Result?result?=?new?Result();if?(e?instanceof?ServiceException)?{//業務失敗的異常,如“賬號或密碼錯誤”result.setCode(ResultCode.FAIL).setMessage(e.getMessage());logger.info(e.getMessage());}?elseif?(e?instanceof?NoHandlerFoundException)?{result.setCode(ResultCode.NOT_FOUND).setMessage("接口?["?+?request.getRequestURI()?+?"]?不存在");}?elseif?(e?instanceof?ServletException)?{result.setCode(ResultCode.FAIL).setMessage(e.getMessage());}?else?{result.setCode(ResultCode.INTERNAL_SERVER_ERROR).setMessage("接口?["?+?request.getRequestURI()?+?"]?內部錯誤,請聯系管理員");String?message;if?(handler?instanceof?HandlerMethod)?{HandlerMethod?handlerMethod?=?(HandlerMethod)?handler;message?=?String.format("接口?[%s]?出現異常,方法:%s.%s,異常摘要:%s",request.getRequestURI(),handlerMethod.getBean().getClass().getName(),handlerMethod.getMethod().getName(),e.getMessage());}?else?{message?=?e.getMessage();}logger.error(message,?e);}responseResult(response,?result);returnnew?ModelAndView();}});}

常用基礎方法抽象封裝

publicinterface?Service<T>?{void?save(T?model);//持久化void?save(List<T>?models);//批量持久化void?deleteById(Integer?id);//通過主鍵刪除void?deleteByIds(String?ids);//批量刪除 eg:ids ->?“1,2,3,4”void?update(T?model);//更新T?findById(Integer?id);//通過ID查找T?findBy(String?fieldName,?Object?value)?throws?TooManyResultsException;?//通過Model中某個成員變量名稱(非數據表中column的名稱)查找,value需符合unique約束List<T>?findByIds(String?ids);//通過多個ID查找//eg:ids ->?“1,2,3,4”List<T>?findByCondition(Condition?condition);//根據條件查找List<T>?findAll();//獲取所有 }

提供代碼生成器來生成基礎代碼

publicabstractclass?CodeGenerator?{...public?static?void?main(String[]?args)?{genCode("輸入表名");}public?static?void?genCode(String...?tableNames)?{for?(String?tableName?:?tableNames)?{//根據需求生成,不需要的注掉,模板有問題的話可以自己修改。genModelAndMapper(tableName);genService(tableName);genController(tableName);}}... }

CodeGenerator

可根據表名生成對應的Model、Mapper、MapperXML、Service、ServiceImpl、Controller(默認提供POST和RESTful兩套Controller模板,根據需要在 genController(tableName)方法中自己選擇,默認是純POST的),代碼模板可根據實際項目的需求來定制,以便漸少重復勞動。由于每個公司業務都不太一樣,所以只提供了一些簡單的通用方法模板,主要是提供一個思路來減少重復代碼的編寫。在我們公司的實際使用中,其實根據業務的抽象編寫了大量的代碼模板。提供簡單的接口簽名認證

public?void?addInterceptors(InterceptorRegistry?registry)?{//接口簽名認證攔截器,該簽名認證比較簡單,實際項目中可以使用Json Web Token或其他更好的方式替代。if?(!"dev".equals(env))?{?//開發環境忽略簽名認證registry.addInterceptor(new?HandlerInterceptorAdapter()?{@Overridepublic?boolean?preHandle(HttpServletRequest?request,?HttpServletResponse?response,?Object?handler)?throws?Exception?{//驗證簽名boolean?pass?=?validateSign(request);if?(pass)?{returntrue;}?else?{logger.warn("簽名認證失敗,請求接口:{},請求IP:{},請求參數:{}",request.getRequestURI(),?getIpAddress(request),?JSON.toJSONString(request.getParameterMap()));Result?result?=?new?Result();result.setCode(ResultCode.UNAUTHORIZED).setMessage("簽名認證失敗");responseResult(response,?result);returnfalse;}}});} } /***?一個簡單的簽名認證,規則:*?1.?將請求參數按ascii碼排序*?2.?拼接為a=value&b=value...這樣的字符串(不包含sign)*?3.?混合密鑰(secret)進行md5獲得簽名,與請求的簽名進行比較*/ private?boolean?validateSign(HttpServletRequest?request)?{String?requestSign?=?request.getParameter("sign");//獲得請求簽名,如sign=19e907700db7ad91318424a97c54ed57if?(StringUtils.isEmpty(requestSign))?{returnfalse;}List<String>?keys?=?new?ArrayList<String>(request.getParameterMap().keySet());keys.remove("sign");//排除sign參數Collections.sort(keys);//排序StringBuilder?sb?=?new?StringBuilder();for?(String?key?:?keys)?{sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串}String?linkString?=?sb.toString();linkString?=?StringUtils.substring(linkString,?0,?linkString.length()?-?1);//去除最后一個'&'String?secret?=?"Potato";//密鑰,自己修改String?sign?=?DigestUtils.md5Hex(linkString?+?secret);//混合密鑰md5return?StringUtils.equals(sign,?requestSign);//比較 }

集成MyBatis、通用Mapper插件、PageHelper分頁插件,實現單表業務零SQL使用Druid Spring Boot Starter 集成Druid數據庫連接池與監控使用FastJsonHttpMessageConverter,提高JSON序列化速度

技術選型&文檔

Spring Boot:https://www.jianshu.com/p/1a9fd8936bd8MyBatis:http://www.mybatis.org/mybatis-3/zh/index.htmlMyBatisb通用Mapper插件:https://mapperhelper.github.io/docs/MyBatis PageHelper分頁插件:https://pagehelper.github.io/Druid Spring Boot Starter:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter/Fastjson:https://github.com/Alibaba/fastjson/wiki/%E9%A6%96%E9%A1%B5

最后,再附上我歷時三個月總結的?Java 面試 + Java 后端技術學習指南,這是本人這幾年及春招的總結,目前,已經拿到了大廠offer,拿去不謝!

下載方式

1.?首先掃描下方二維碼

2.?后臺回復「Java面試」即可獲取

總結

以上是生活随笔為你收集整理的一个基于 Spring Boot 的项目骨架,拿走即用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。