接上文
d1.framework.webapi
庫(kù)是基礎(chǔ)封裝炭序,每個(gè) webapi 項(xiàng)目都必須使用,里面包含功能很多粘室。
1. BaseApplication
所有業(yè)務(wù)項(xiàng)目的主入口 Application 類都需繼承此類
@SpringBootApplication
public class DemoApplication extends BaseApplication{
}
這個(gè)類主要是增加幾個(gè)缺省注解,比如激活 Swagger圣蝎,確保對(duì)包進(jìn)行掃描是從 d1 開始触幼。
所以約定我們所有的業(yè)務(wù)項(xiàng)目的 package 都是 d1 開頭,比如
d1.project.xxxx
@EnableSwagger2
@ComponentScan("d1")
@EntityScan("d1")
@EnableJpaRepositories("d1")
public class BaseApplication {
}
2. 封裝 webapi 接口的返回 Result
所有 controller 返回的值都是一個(gè) Result 對(duì)象瞳抓,基本結(jié)構(gòu)是
{
"code": 1,
"msg": "返回的消息,通常是字符串",
"data": "返回的數(shù)據(jù),通常又是一個(gè)json對(duì)象"
}
使用方式:
return ResultUtil.result(10001,"自定義的消息",數(shù)據(jù)對(duì)象);
return ResultUtil.fail("自定義的消息",數(shù)據(jù)對(duì)象);
return ResultUtil.success("自定義的消息",數(shù)據(jù)對(duì)象);
3. ControllerAdvice
利用注解 @ControllerAdvice 實(shí)現(xiàn)統(tǒng)一攔截處理所有 controller 沒(méi)有 catch 的錯(cuò)誤
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public Result all(Exception e) {
return ResultUtil.result(ResultCode.UN_CATCH_ERROR.code, e.getMessage(), e);
}
4. 封裝Swagger自動(dòng)生成API文檔
只需要在 application.properties 配置文件里添加以下幾個(gè)配置伏恐,業(yè)務(wù)項(xiàng)目的 API 文檔就可以自動(dòng)生成并以服務(wù)的方式來(lái)訪問(wèn)孩哑,訪問(wèn)的url是http://域名或地址/swagger-ui.html#/
#application.properties
d1.framework.webapi.swagger.enable=true #生產(chǎn)環(huán)境下通常改成false
d1.framework.webapi.swagger.title=項(xiàng)目的標(biāo)題
d1.framework.webapi.swagger.desc=項(xiàng)目的描述
d1.framework.webapi.swagger.version=項(xiàng)目API的版本
d1.framework.webapi.swagger.host=www.xxxx.com:8089
在 contorller 里使用注解標(biāo)記 API 的方法參考文檔
4. 跨域設(shè)置
只需要在 application.properties 配置文件里添加以下配置,業(yè)務(wù)項(xiàng)目的前端頁(yè)面可以實(shí)現(xiàn)跨域訪問(wèn)翠桦,當(dāng)然生產(chǎn)環(huán)境的時(shí)候需要嚴(yán)格控制可跨域的域名横蜒。
#application.properties
#生成環(huán)境需要把*換成真實(shí)的域名胳蛮,多個(gè)域名可以用逗號(hào)隔開
d1.framework.webapi.cors=*
5. BaseEntity
這是所有 Entity 的基類,主要是強(qiáng)行設(shè)置一個(gè)字段叫 Id丛晌,這個(gè) Id 缺省是32位 uuid仅炊,在業(yè)務(wù)系統(tǒng)上建議所有 entity 都繼承它。
6. User相關(guān)封裝
DoUserBaseEntity 定義了用戶表的常用字段澎蛛,業(yè)務(wù)系統(tǒng)直接繼承做一些擴(kuò)展就可以了抚垄。
DoUserServiceImplBase 實(shí)現(xiàn)用戶相關(guān)的 service,主要是創(chuàng)建 token谋逻,登錄驗(yàn)證 token呆馁,缺省 token 都是用 d1.framework.cache
來(lái)緩存。
7. Auth相關(guān)
這里也是基于團(tuán)隊(duì)內(nèi)部的一個(gè)約定毁兆,所有 webapi 接口如果需要驗(yàn)證權(quán)限浙滤,都需要在 http 請(qǐng)求的 header 里設(shè)置 Authorization 屬性,屬性的值有2種情況:
Authorization = token xxxxxxx 表示是通過(guò)用戶登錄后返回的 token 來(lái)驗(yàn)證
Authorization = sign xxxxxxx 表示服務(wù)間通過(guò) HMAC 簽名來(lái)校驗(yàn)
定義AuthFilter(繼承Filter)來(lái)驗(yàn)證用戶的請(qǐng)求Header里的Authoriztion對(duì)應(yīng)的值如果是token的話气堕,從d1.framework.cache里對(duì)應(yīng)的緩存里查詢token是否存在并是否沒(méi)有過(guò)期纺腊。
另外通過(guò)定義一個(gè)自定義的注解Auth來(lái)設(shè)定web api接口是屬于某種特定的用戶。
@Auth("webadmin")
@RestController
@RequestMapping("/webadmin/user")
@Api(value = "/webadmin/user", description = "管理用戶管理")
public class WebAdminUserController extends DoBaseController<WebAdminUser> {
......
}
@Auth("webadmin")標(biāo)識(shí)這個(gè)controller里所有方法都必須是webadmin用戶登錄后才可以訪問(wèn)茎芭,這個(gè)注解也可以單獨(dú)給特定方法使用
8. DestroyEhcacheBean
JVM 退出時(shí)先 shutdown ehcache摹菠,確保內(nèi)存里的 cache 內(nèi)容正確寫入本地文件
public class DestroyEhcacheBean implements DisposableBean, ExitCodeGenerator {
......
@Override
public void destroy() throws Exception {
if (cache != null)
cache.shutDown();
}
}
9. DoServiceImpBase
包含 service 常用方法,其它 service 都繼承這個(gè)方法,里面主要包括基本的增刪改查骗爆,這是一個(gè) abstract 方法,最主要是需要子類繼承的時(shí)候返回一個(gè)實(shí)際的 dao 類蔽介。
這個(gè)基類還實(shí)現(xiàn)了根據(jù) token 查詢對(duì)應(yīng)的用戶對(duì)象摘投。
public abstract class DoServiceImpBase<T> {
......
protected abstract JpaRepository<T, String> getDao();
......
}
10. DoBaseController類
controller 基類,封裝了最基本的增刪改查虹蓄,子類只需要繼承犀呼,常見的接口都已定義。
11. 日志
在項(xiàng)目的resource下有一個(gè) logback.xml薇组,沒(méi)有特殊的需求的話外臂,所有業(yè)務(wù)系統(tǒng)都可以用這個(gè)默認(rèn)的日志配置。
另外定義了一個(gè) LoggerController 實(shí)現(xiàn)通過(guò) webapi 接口查看日志和下載日志文件律胀,這樣遠(yuǎn)程就可以查看日志宋光。
12. HMACSignService
添加HMAC校驗(yàn)簽名的基類service, 實(shí)現(xiàn)了服務(wù)間HMAC接口驗(yàn)證方式,規(guī)則參考微信的服務(wù)校驗(yàn)
13. SignInRetryLimitService
封裝用戶登錄重試次數(shù)校驗(yàn)炭菌,超過(guò)一定次數(shù)將被鎖住不能再試了罪佳。
需要在application.properties里添加2個(gè)配置:
#登錄密碼錯(cuò)誤重試的次數(shù),沒(méi)有這個(gè)值或值為0表示不限制
d1.framework.webapi.sign-in.retry-count=5
#登錄密碼錯(cuò)誤重試到一定次數(shù)后黑低,鎖住用戶一段時(shí)間赘艳,單位是分鐘
d1.framework.webapi.sign-in.lock-period=60
使用這個(gè)服務(wù)通過(guò)3個(gè)函數(shù):
if (user == null) throw new Exception("用戶:" + username + "不存在");
if (retryService.verifyIsLocked(username)) throw new Exception("用戶重試錯(cuò)誤密碼多次,導(dǎo)致用戶被鎖");
if (!user.getPassword().equals(password)) {
retryService.signInWithWrongPwd(username);
throw new Exception("密碼不對(duì)");
}
retryService.signInSuccess(username);
以上是 d1.framework.webapi
的基本功能,很多功能都是在開發(fā)實(shí)際項(xiàng)目的過(guò)程中逐漸添加上去的蕾管,包含的功能是雜七雜八的需求枷踏。
其它庫(kù)都是針對(duì)特定的功能,這里不一一詳述了掰曾。大家可以參考github旭蠕。