controller編碼習(xí)慣

工作中,少不了要定義各種接口除嘹,系統(tǒng)集成要定義接口姨丈,前后臺(tái)掉調(diào)用也要定義接口。接口定義一定程度上能反應(yīng)程序員的編程功底埃难。列舉一下工作中我發(fā)現(xiàn)大家容易出現(xiàn)的問題:

1. 返回格式不統(tǒng)一

同一個(gè)接口莹弊,有時(shí)候返回?cái)?shù)組,有時(shí)候返回單個(gè)涡尘;成功的時(shí)候返回對象忍弛,失敗的時(shí)候返回錯(cuò)誤信息字符串。工作中有個(gè)系統(tǒng)集成就是這樣定義的接口考抄,真是辣眼睛细疚。這個(gè)對應(yīng)代碼上,返回的類型是map川梅,json疯兼,object,都是不應(yīng)該的贫途。實(shí)際工作中吧彪,我們會(huì)定義一個(gè)統(tǒng)一的格式,就是ResultBean潮饱,分頁的有另外一個(gè)PageResultBean

錯(cuò)誤范例:

//返回map可讀性不好,盡量不要

@PostMapping("/delete")

publicMapdelete(longid,Stringlang){

}

// 成功返回boolean诫给,失敗返回string香拉,大忌

@PostMapping("/delete")

publicObjectdelete(longid,Stringlang){

try{

booleanresult=configService.delete(id,local);

returnresult;

}catch(Exceptione){

log.error(e);

returne.toString();

}

}

2. 沒有考慮失敗情況

一開始只考慮成功場景,等后面測試發(fā)現(xiàn)有錯(cuò)誤情況中狂,怎么辦凫碌,改接口唄,前后臺(tái)都改胃榕,勞民傷財(cái)無用功盛险。

錯(cuò)誤范例:

//不返回任何數(shù)據(jù),沒有考慮失敗場景勋又,容易返工

@PostMapping("/update")

publicvoidupdate(longid,xxx){

}

3. 出現(xiàn)和業(yè)務(wù)無關(guān)的輸入?yún)?shù)

如lang語言苦掘,當(dāng)前用戶信息 都不應(yīng)該出現(xiàn)參數(shù)里面,應(yīng)該從當(dāng)前會(huì)話里面獲取楔壤。后面講ThreadLocal會(huì)說到怎么樣去掉鹤啡。除了代碼可讀性不好問題外,尤其是參數(shù)出現(xiàn)當(dāng)前用戶信息的蹲嚣,這是個(gè)嚴(yán)重問題递瑰。

錯(cuò)誤范例:

// (當(dāng)前用戶刪除數(shù)據(jù))參數(shù)出現(xiàn)lang和userid祟牲,尤其是userid,大忌

@PostMapping("/delete")

publicMapdelete(longid,Stringlang,StringuserId){

}

4. 出現(xiàn)復(fù)雜的輸入?yún)?shù)

一般情況下抖部,不允許出現(xiàn)例如json字符串這樣的參數(shù)说贝,這種參數(shù)可讀性極差。應(yīng)該定義對應(yīng)的bean慎颗。

錯(cuò)誤范例:

// 參數(shù)出現(xiàn)json格式乡恕,可讀性不好,代碼也難看

@PostMapping("/update")

publicMapupdate(longid,StringjsonStr){

}

5. 沒有返回應(yīng)該返回的數(shù)據(jù)

例如哗总,新增接口一般情況下應(yīng)該返回新對象的id標(biāo)識(shí)几颜,這需要編程經(jīng)驗(yàn)。新手定義的時(shí)候因?yàn)榍芭_(tái)沒有用就不返回?cái)?shù)據(jù)或者只返回true讯屈,這都是不恰當(dāng)?shù)牡翱蕖e人要不要是別人的事情,你該返回的還是應(yīng)該返回涮母。

錯(cuò)誤范例:

// 約定俗成谆趾,新建應(yīng)該返回新對象的信息,只返回boolean容易導(dǎo)致返工

@PostMapping("/add")

publicbooleanadd(xxx){

//xxx

returnconfigService.add();

}

很多人看了我的這篇文章程序員你為什么這么累叛本?沪蓬,都覺得里面的技術(shù)也很簡單,沒有什么特別的地方来候,但是跷叉,實(shí)現(xiàn)這個(gè)代碼框架之前,就是要你的接口的統(tǒng)一的格式ResultBean营搅,aop才好做云挟。有些人誤解了,我那篇文章說的都不是技術(shù)转质,重點(diǎn)說的是編碼習(xí)慣工作方式园欣,如果你重點(diǎn)還是放在什么技術(shù)上,那我也幫不了你了休蟹。同樣沸枯,如果我后面的關(guān)于習(xí)慣和規(guī)范的帖子,你重點(diǎn)還是放在技術(shù)上的話赂弓,那是丟了西瓜撿芝麻绑榴,有很多貼還是沒有任何技術(shù)點(diǎn)呢。

附上ResultBean盈魁,沒有任何技術(shù)含量:

@Data

publicclassResultBeanimplementsSerializable{

privatestaticfinallongserialVersionUID=1L;

publicstaticfinalintSUCCESS=0;

publicstaticfinalintFAIL=1;

publicstaticfinalintNO_PERMISSION=2;

privateStringmsg="success";

privateintcode=SUCCESS;

privateT data;

publicResultBean(){

super();

}

publicResultBean(T data){

super();

this.data=data;

}

publicResultBean(Throwablee){

super();

this.msg=e.toString();

this.code=FAIL;

}

}

統(tǒng)一的接口規(guī)范彭沼,能幫忙規(guī)避很多無用的返工修改和可能出現(xiàn)的問題。能使代碼可讀性更加好备埃,利于進(jìn)行aop和自動(dòng)化測試這些額外工作姓惑。大家一定要重視褐奴。

第一篇文章中,我貼了2段代碼于毙,第一個(gè)是原生態(tài)的敦冬,第2段是我指定了接口定義規(guī)范,使用AOP技術(shù)之后最終交付的代碼唯沮,從15行到一行脖旱,自己感受一下。今天來說說大家關(guān)注的AOP如何實(shí)現(xiàn)介蛉。

先說說Controller規(guī)范萌庆,主要的內(nèi)容是就是接口定義里面的內(nèi)容,你只要遵循里面的規(guī)范币旧,controller就問題不大践险,除了這些,還有另外的幾點(diǎn):

所有函數(shù)返回統(tǒng)一的ResultBean/PageResultBean格式

原因見我的接口定義這個(gè)貼吹菱。沒有統(tǒng)一格式巍虫,AOP無法玩。

ResultBean/PageResultBean是controller專用的鳍刷,不允許往后傳占遥!

Controller做參數(shù)格式的轉(zhuǎn)換,不允許把json输瓜,map這類對象傳到services去瓦胎,也不允許services返回json、map尤揣。

一般情況下搔啊!寫過代碼都知道,map芹缔,json這種格式靈活坯癣,但是可讀性差瓶盛,如果放業(yè)務(wù)數(shù)據(jù)最欠,每次閱讀起來都比較困難。定義一個(gè)bean看著工作量多了惩猫,但代碼清晰多了芝硬。

參數(shù)中一般情況不允許出現(xiàn)Request,Response這些對象

主要是可讀性問題轧房。一般情況下拌阴。

不需要打印日志

日志在AOP里面會(huì)打印,而且我的建議是大部分日志在Services這層打印奶镶。

規(guī)范里面大部分是 不要做的項(xiàng)多迟赃,要做的比較少陪拘,落地比較容易。

ResultBean定義帶泛型纤壁,使用了lombok左刽。

AOP代碼,主要就是打印日志和捕獲異常酌媒,異常要區(qū)分已知異常和未知異常欠痴,其中未知的異常是我們重點(diǎn)關(guān)注的,可以做一些郵件通知啥的秒咨,已知異忱桑可以再細(xì)分一下,可以不同的異常返回不同的返回碼:

publicclassControllerAOP{

privatestaticfinalLoggerlogger=LoggerFactory.getLogger(ControllerAOP.class);

publicObjecthandlerControllerMethod(ProceedingJoinPointpjp){

longstartTime=System.currentTimeMillis();

ResultBeanresult;

try{

result=(ResultBean)pjp.proceed();

logger.info(pjp.getSignature()+"use time:"+(System.currentTimeMillis()-startTime));

}catch(Throwablee){

result=handlerException(pjp,e);

}

returnresult;

}

privateResultBeanhandlerException(ProceedingJoinPointpjp,Throwablee){

ResultBeanresult=newResultBean();

// 已知異常

if(einstanceofCheckException){

result.setMsg(e.getLocalizedMessage());

result.setCode(ResultBean.FAIL);

}else{

logger.error(pjp.getSignature()+" error ",e);

result.setMsg(e.toString());

result.setCode(ResultBean.FAIL);

// 未知異常是應(yīng)該重點(diǎn)關(guān)注的雨席,這里可以做其他操作菩咨,如通知郵件,單獨(dú)寫到某個(gè)文件等等舅世。

}

returnresult;

}

}

AOP配置:(關(guān)于用java代碼還是xml配置旦委,這里我傾向于xml配置,因?yàn)檫@個(gè)會(huì)不定期改動(dòng))


expression="execution(public xxx.common.beans.ResultBean *(..))"/>

現(xiàn)在知道為什么要返回統(tǒng)一的一個(gè)ResultBean了:

為了統(tǒng)一格式

為了應(yīng)用AOP

為了包裝異常信息

分頁的PageResultBean大同小異雏亚,大家自己依葫蘆畫瓢自己完成就好了缨硝。

貼一個(gè)簡單的controller(左邊的箭頭表示AOP攔截了)。請對比程序員你為什么這么累罢低?里面原來的代碼查看查辩,沒有對比就沒有傷害。

最后說一句网持,先有統(tǒng)一的接口定義規(guī)范宜岛,然后有AOP實(shí)現(xiàn)。先有思想再有技術(shù)功舀。技術(shù)不是關(guān)鍵萍倡,AOP技術(shù)也很簡單,這個(gè)帖子的關(guān)鍵點(diǎn)不是技術(shù)辟汰,而是習(xí)慣和思想列敲,不要撿了芝麻丟了西瓜。網(wǎng)絡(luò)上講技術(shù)的貼多帖汞,講習(xí)慣戴而、風(fēng)格的少,這些都是我工作多年的行之有效的經(jīng)驗(yàn)之談翩蘸,望有緣人珍惜所意。

覺得有用請點(diǎn)贊加關(guān)注,接下來再繼續(xù)其他規(guī)范。敬請期待扶踊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末泄鹏,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子秧耗,更是在濱河造成了極大的恐慌命满,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绣版,死亡現(xiàn)場離奇詭異谒拴,居然都是意外死亡款票,警方通過查閱死者的電腦和手機(jī)哪痰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門生音,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人缩麸,你說我怎么就攤上這事铸磅。” “怎么了杭朱?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵阅仔,是天一觀的道長。 經(jīng)常有香客問我弧械,道長八酒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任刃唐,我火速辦了婚禮羞迷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘画饥。我一直安慰自己衔瓮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布抖甘。 她就那樣靜靜地躺著热鞍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪衔彻。 梳的紋絲不亂的頭發(fā)上薇宠,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音米奸,去河邊找鬼昼接。 笑死爽篷,一個(gè)胖子當(dāng)著我的面吹牛悴晰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼铡溪,長吁一口氣:“原來是場噩夢啊……” “哼漂辐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棕硫,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤髓涯,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哈扮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纬纪,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年滑肉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了包各。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡靶庙,死狀恐怖问畅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情六荒,我是刑警寧澤护姆,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站掏击,受9級(jí)特大地震影響卵皂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砚亭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一渐裂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧钠惩,春花似錦柒凉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至愧沟,卻和暖如春蔬咬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沐寺。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工林艘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人混坞。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓狐援,卻偏偏與公主長得像钢坦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子啥酱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,163評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理爹凹,服務(wù)發(fā)現(xiàn),斷路器镶殷,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • 今天是兒子上班的第一天禾酱,晚飯后夫妻倆破例沒去散步,等著兒子回家绘趋。 “第一天上班感覺咋樣颤陶?” “今天沒出過差錯(cuò)吧,多...
    聽雨軒清秋閱讀 240評(píng)論 3 4
  • 喝茶可以致富陷遮? 今年有部青春劇指郁,叫《那年青春我們正好》。 里面一段小視頻被人截了出來拷呆,傳到各個(gè)茶友群里的效果是這樣...
    青羽谷閱讀 958評(píng)論 0 48
  • 時(shí)間管理名人堂 — 16 大天使 入選時(shí)間:2015年12月12日 入選級(jí)別:季級(jí) 入選理由:大天使闲坎,男,中學(xué)化學(xué)...
    V5特湘葉葉閱讀 360評(píng)論 0 0