問(wèn)答平臺(tái)實(shí)習(xí)項(xiàng)目

從八月底到昨天属提,整整三個(gè)月,邊看視頻學(xué)技術(shù)棧邊寫(xiě)代碼美尸,每天晚上擠時(shí)間完成了這個(gè)項(xiàng)目冤议,還是想為明年實(shí)習(xí)做一個(gè)項(xiàng)目上的準(zhǔn)備。最初是想做一個(gè)深度學(xué)習(xí)方面的項(xiàng)目师坎,當(dāng)時(shí)對(duì)這方面基礎(chǔ)知識(shí)的儲(chǔ)備還不夠恕酸,如今也還在看視頻和文檔學(xué)習(xí),因此選擇了web項(xiàng)目胯陋。其實(shí)對(duì)于以后工作的方向到底是算法還是研發(fā)現(xiàn)在也說(shuō)不清楚蕊温,等明年初根據(jù)自己的學(xué)習(xí)情況再做進(jìn)一步的打算袱箱。

接下來(lái)學(xué)校的課越來(lái)越集中,各種考試也陸續(xù)而至义矛,深度學(xué)習(xí)也還在繼續(xù)學(xué)習(xí)发笔,因此留給項(xiàng)目上的準(zhǔn)備時(shí)間也捉襟見(jiàn)肘,但每天還是會(huì)堅(jiān)持寫(xiě)算法題凉翻,相信明年會(huì)越來(lái)越好了讨。

這個(gè)項(xiàng)目是以現(xiàn)在的知乎、旁朊客網(wǎng)這類(lèi)問(wèn)答平臺(tái)為原型量蕊,基于springboot的SSM框架的Java web應(yīng)用項(xiàng)目。數(shù)據(jù)庫(kù)使用了redis和mysql艇挨,同時(shí)通過(guò)一個(gè)異步消息框架來(lái)實(shí)現(xiàn)事件的異步處理残炮,并使用爬蟲(chóng)對(duì)網(wǎng)站進(jìn)行數(shù)據(jù)填充。

目錄

  • 項(xiàng)目的基本框架及配置
  • AOP和IOC
  • MySQL+MyBatis
  • 注冊(cè)與登錄的實(shí)現(xiàn)
  • 發(fā)表問(wèn)題+敏感詞過(guò)濾
  • 發(fā)表評(píng)論和站內(nèi)信
  • Redis實(shí)現(xiàn)點(diǎn)贊和點(diǎn)踩功能
  • 異步消息機(jī)制
  • 關(guān)注+粉絲列表的實(shí)現(xiàn)
  • Timeline與新鮮事缩滨,推拉模式下的Feed流
  • 使用爬蟲(chóng)爬取數(shù)據(jù)势就,對(duì)網(wǎng)站進(jìn)行數(shù)據(jù)填充
  • 功能擴(kuò)展以及深度擴(kuò)展

項(xiàng)目的基本框架及配置

創(chuàng)建git倉(cāng)庫(kù),本地配置idea并測(cè)試pull和push脉漏。

創(chuàng)建springboot工程苞冯,導(dǎo)入web,velocity和aop的包侧巨。

生成maven項(xiàng)目舅锄,pom.xml包含上述依賴(lài)。

controller中使用注解配置司忱,requestmapping皇忿,responsebody基本可以解決請(qǐng)求轉(zhuǎn)發(fā)以及響應(yīng)內(nèi)容的渲染。responsebody自動(dòng)選擇viewresolver進(jìn)行解析坦仍。

使用pathvariable和requestparam傳遞參數(shù)鳍烁,使用velocity編寫(xiě)頁(yè)面模板,注意其中的語(yǔ)法使用繁扎。常用!{}和{}幔荒。

使用http規(guī)范下的httpservletrequest和httpservletresponse來(lái)封裝請(qǐng)求和相響應(yīng),使用封裝好的session和cookie對(duì)象梳玫。

使用重定向的redirectview和統(tǒng)一異常處理器exceptionhandler爹梁。

AOP和IOC

IOC解決對(duì)象實(shí)例化以及依賴(lài)傳遞問(wèn)題,解耦提澎。

AOP解決縱向切面問(wèn)題卫键,主要實(shí)現(xiàn)日志和權(quán)限控制功能。

aspect實(shí)現(xiàn)切面虱朵,并且使用logger來(lái)記錄日志莉炉,用該切面的切面方法來(lái)監(jiān)聽(tīng)controller钓账。

MySQL+MyBatis

使用mysql創(chuàng)建數(shù)據(jù)庫(kù)和表。

加入mybatis和mysql的maven倉(cāng)庫(kù)絮宁,注意梆暮,由于現(xiàn)在版本的springboot不再支持velocity進(jìn)而導(dǎo)致我使用較早版本的springboot,所以這里提供一可以正常運(yùn)行的版本設(shè)置绍昂。

springboot使用1.4.0啦粹,mybatis-spring-boot-starter使用1.2.1,mysql-connector-java使用8.0.12窘游。

注意mybatis的注解語(yǔ)法以及xml的配置要求唠椭,xml要求放在resource中并且與dao接口在相同的包路徑下。

application.properties增加spring配置數(shù)據(jù)庫(kù)鏈接地址忍饰。

兩個(gè)小工具:

  • ViewObject:方便傳遞任何數(shù)據(jù)到
  • VelocityDateTool:velocity自帶工具類(lèi)

寫(xiě)好靜態(tài)文件html css和js贪嫂,并且注意配置。

  • spring.velocity.suffix=.html 保證跳轉(zhuǎn)請(qǐng)求轉(zhuǎn)發(fā)到html上
  • spring.velocity.toolbox-config-location=toolbox.xml

注冊(cè)與登錄的實(shí)現(xiàn)

新建數(shù)據(jù)表login_ticket用來(lái)存儲(chǔ)ticket字段艾蓝。該字段在用戶(hù)登錄成功時(shí)被生成并存入數(shù)據(jù)庫(kù)力崇,并被設(shè)置為cookie,下次用戶(hù)登錄時(shí)會(huì)帶上這個(gè)ticket赢织,ticket是隨機(jī)的UUID字符串亮靴,有過(guò)期時(shí)間以及有效狀態(tài)。

使用攔截器interceptor來(lái)攔截所有用戶(hù)請(qǐng)求于置,判斷請(qǐng)求中是否存在有效的ticket茧吊,如果有就將用戶(hù)信息寫(xiě)入Threadlocal。所有線(xiàn)程的threadlocal都被存在一個(gè)叫做hostholder的實(shí)例中八毯,根據(jù)該實(shí)例就可以在全局任意位置獲取用戶(hù)的信息搓侄。

該ticket的功能類(lèi)似session,也是通過(guò)cookie寫(xiě)回瀏覽器宪彩,瀏覽器請(qǐng)求時(shí)再通過(guò)cookie傳遞休讳,區(qū)別是該字段是存在數(shù)據(jù)庫(kù)中的讲婚,并且可以用于移動(dòng)端尿孔。

通過(guò)用戶(hù)訪(fǎng)問(wèn)權(quán)限攔截器來(lái)攔截用戶(hù)的越界訪(fǎng)問(wèn),比如用戶(hù)沒(méi)有管理員權(quán)限就不能訪(fǎng)問(wèn)管理員頁(yè)面筹麸。

配置了json工具類(lèi)以及md5工具類(lèi)活合,并且使用Java自帶的鹽生成api將用戶(hù)密碼加密為密文。保證密碼安全物赶。

數(shù)據(jù)安全性的保障手段:https使用公鑰加密私鑰解密白指,比如支付寶的密碼加密,單點(diǎn)登錄驗(yàn)證酵紫,驗(yàn)證碼機(jī)制等告嘲。

發(fā)表問(wèn)題+敏感詞過(guò)濾

發(fā)布問(wèn)題時(shí)檢查標(biāo)題和內(nèi)容错维,防止xss注入,并且過(guò)濾敏感詞橄唬。

防止xss注入直接使用HTMLutils的方法即可實(shí)現(xiàn)赋焕。

過(guò)濾敏感詞首先需要建立一個(gè)字典樹(shù),并且讀取一份保存敏感詞的文本文件仰楚,然后初始化字典樹(shù)隆判。最后將過(guò)濾器作為一個(gè)服務(wù),讓需要過(guò)濾敏感詞的服務(wù)進(jìn)行調(diào)用即可僧界。

發(fā)表評(píng)論和站內(nèi)信

首先建立表comment和message分別代表評(píng)論和站內(nèi)信侨嘀。

評(píng)論的邏輯是每一個(gè)問(wèn)題下面都有評(píng)論,顯示評(píng)論數(shù)量捂襟,具體內(nèi)容咬腕,評(píng)論人等信息。

消息的邏輯是笆豁,兩個(gè)用戶(hù)之間發(fā)送一條消息郎汪,有一個(gè)唯一的會(huì)話(huà)id,這個(gè)會(huì)話(huà)里可以有多條這兩個(gè)用戶(hù)的交互信息闯狱。通過(guò)一個(gè)用戶(hù)id獲取該用戶(hù)的會(huì)話(huà)列表煞赢,再根據(jù)會(huì)話(huà)id再獲取具體的會(huì)話(huà)內(nèi)的多條消息。

邏輯清楚之后哄孤,再加上一些附加功能照筑,比如顯示未讀消息數(shù)量,根據(jù)時(shí)間順序排列會(huì)話(huà)和消息瘦陈。

本節(jié)內(nèi)容基本就是業(yè)務(wù)邏輯的開(kāi)發(fā)凝危,沒(méi)有新增什么技術(shù)點(diǎn),主要是前后端交互的邏輯比較復(fù)雜晨逝,前端的開(kāi)發(fā)量也比較大蛾默。

Redis實(shí)現(xiàn)點(diǎn)贊和點(diǎn)踩功能

首先了解一下redis的基礎(chǔ)知識(shí),數(shù)據(jù)結(jié)構(gòu)捉貌,jedis使用等支鸡。

編寫(xiě)list,string趁窃,hashmap牧挣,set,sortset的測(cè)試用例醒陆,熟悉jedis api瀑构。

開(kāi)發(fā)點(diǎn)踩和點(diǎn)贊功能,在此之前根據(jù)業(yè)務(wù)封裝好jedis的增刪改查操作刨摩,放在util包中寺晌。

根據(jù)需求確定key字段世吨,格式是 like:實(shí)體類(lèi)型:實(shí)體id 和 dislike:實(shí)體類(lèi)型:實(shí)體id 這樣可以將喜歡一條新聞的人存在一個(gè)集合,不喜歡的存在另一個(gè)集合呻征。通過(guò)統(tǒng)計(jì)數(shù)量可以獲得點(diǎn)贊和點(diǎn)踩數(shù)另假。

一般點(diǎn)贊點(diǎn)踩操作是先修改redis的值并獲取返回值,然后再異步修改mysql數(shù)據(jù)庫(kù)的likecount數(shù)值怕犁。這樣既可以保證點(diǎn)贊操作快速完成边篮,也可保證數(shù)據(jù)一致性。

異步消息機(jī)制

在之前的功能中有一些不需要實(shí)時(shí)執(zhí)行的操作或者任務(wù)奏甫,我們可以把它們改造成異步消息來(lái)進(jìn)行發(fā)送戈轿。

具體操作就是使用redis來(lái)實(shí)現(xiàn)異步消息隊(duì)列。代碼中使用事件event來(lái)包裝一個(gè)事件阵子,事件需要記錄事件實(shí)體的各種信息:一個(gè)異步工具類(lèi)(事件生產(chǎn)者+事件消費(fèi)者+eventHandler接口)思杯,讓以后各種事件的實(shí)現(xiàn)類(lèi)來(lái)實(shí)現(xiàn)這個(gè)接口。

事件生產(chǎn)者一般作為一個(gè)服務(wù)挠进,由Controller中的業(yè)務(wù)邏輯調(diào)用并產(chǎn)生一個(gè)事件色乾,將事件序列化存入redis隊(duì)列中,事件消費(fèi)者則通過(guò)一個(gè)線(xiàn)程循環(huán)獲取隊(duì)列里的事件领突,并且尋找對(duì)應(yīng)的handler進(jìn)行處理暖璧。

整個(gè)異步事件的框架開(kāi)發(fā)完成,后面新加入的登錄君旦,點(diǎn)贊等事件都可以這么實(shí)現(xiàn)澎办。

關(guān)注+粉絲列表的實(shí)現(xiàn)

新增關(guān)注功能,使用redis實(shí)現(xiàn)每一個(gè)關(guān)注對(duì)象的粉絲列表以及每一個(gè)用戶(hù)的關(guān)注對(duì)象列表金砍。通過(guò)該列表的crud操作可以對(duì)應(yīng)獲取粉絲列表和關(guān)注列表局蚀,并且實(shí)現(xiàn)關(guān)注和取關(guān)功能。

由于關(guān)注成功和添加粉絲成功時(shí)同一個(gè)事務(wù)里的兩個(gè)操作恕稠,可以使用redis的事務(wù)multi來(lái)包裝事務(wù)并進(jìn)行提交琅绅。

除此之外,關(guān)注成功或者被關(guān)注還可以通過(guò)事件機(jī)制來(lái)生成發(fā)送郵件的事件鹅巍,由異步的隊(duì)列處理器來(lái)完成事件響應(yīng)千扶,同樣是根據(jù)redis來(lái)實(shí)現(xiàn)。

對(duì)于粉絲列表昆著,除了顯示粉絲的基本信息之外县貌,還要顯示當(dāng)前用戶(hù)是否關(guān)注了這個(gè)粉絲术陶,以便前端顯示凑懂。

對(duì)于關(guān)注列表來(lái)說(shuō),如果被關(guān)注對(duì)象是用戶(hù)的話(huà)梧宫,除了顯示用戶(hù)的基本信息之外接谨,還要顯示當(dāng)前用戶(hù)是被這個(gè)用戶(hù)關(guān)注摆碉,以便前端顯示。

Timeline與新鮮事脓豪,推拉模式下的Feed流

微博的新鮮事功能介紹:關(guān)注好友的動(dòng)態(tài)(好友的點(diǎn)贊和發(fā)表的問(wèn)題等)巷帝,關(guān)注了某個(gè)問(wèn)題,這些都是feed流的一部分扫夜。

在知乎中的feed流主要體現(xiàn)于:關(guān)注用戶(hù)的評(píng)論行為楞泼,關(guān)注用戶(hù)的關(guān)注問(wèn)題行為。

feed流主要分為兩種笤闯,推模式和拉模式堕阔。推模式主要是把新鮮事推送給關(guān)注該用戶(hù)的粉絲,本例使用redis來(lái)存儲(chǔ)某個(gè)用戶(hù)接受的新鮮事id列表颗味,這個(gè)信息流又稱(chēng)為timeline超陆,根據(jù)用戶(hù)的唯一key來(lái)存儲(chǔ);拉模式主要是用戶(hù)直接找尋自己所有關(guān)注的人浦马,并且到數(shù)據(jù)庫(kù)去查找這些關(guān)注對(duì)象的新鮮事时呀,直接返回。

推模式主要適合粉絲較少的小用戶(hù)晶默,因?yàn)樗麄兊姆劢z量少谨娜,使用推模式產(chǎn)生的冗余副本也比較少,并且可以減少用戶(hù)訪(fǎng)問(wèn)的壓力磺陡。

拉模式主要適合大v瞧预,因?yàn)楹芏嘟┦酆头腔钴S用戶(hù)根本不需要推送信息,用推模式發(fā)給這些僵尸粉或者非活躍用戶(hù)就是浪費(fèi)資源仅政。所以讓用戶(hù)通過(guò)拉模式請(qǐng)求垢油,只需要一個(gè)數(shù)據(jù)副本即可。同時(shí)如果是熱點(diǎn)信息圆丹,這些信息也可以放在緩存滩愁,讓用戶(hù)首先拉取這些信息,提高查詢(xún)效率辫封。

使用feedhandler異步處理上述的兩個(gè)事件硝枉,當(dāng)事件發(fā)生時(shí),根據(jù)事件實(shí)體進(jìn)行重新包裝倦微,構(gòu)造一個(gè)新鮮事妻味,因?yàn)樗行迈r事的格式是一樣的。需要包括:日期欣福,新鮮事類(lèi)型责球,發(fā)起者,新鮮事內(nèi)容,然后把該數(shù)據(jù)存入數(shù)據(jù)庫(kù)雏逾,以便用戶(hù)使用pull模式拉出嘉裤。

為了適配推送模式,此時(shí)也要把新鮮事放到該用戶(hù)所有粉絲的timeline里栖博,這樣的話(huà)就同時(shí)實(shí)現(xiàn)了推和拉的操作了屑宠。

使用爬蟲(chóng)爬取數(shù)據(jù),對(duì)網(wǎng)站進(jìn)行數(shù)據(jù)填充

安裝python3.x并且配置環(huán)境變量仇让。同時(shí)安裝pycharm,安裝pip典奉。

安裝好以后,先熟悉python的語(yǔ)法丧叽,寫(xiě)一些例子秋柄,比如數(shù)據(jù)類(lèi)型,操作符蠢正,方法調(diào)用骇笔,以及面向?qū)ο蟮募夹g(shù)。

因?yàn)閿?shù)據(jù)是要導(dǎo)入數(shù)據(jù)庫(kù)的嚣崭,所以這里安裝MySQLdb的一個(gè)庫(kù)笨触,并且寫(xiě)一下連接數(shù)據(jù)庫(kù)的代碼,寫(xiě)一下簡(jiǎn)單的crud進(jìn)行測(cè)試雹舀。

使用requests庫(kù)作為解析http請(qǐng)求的工具芦劣,使用beautifulsoup作為解析html代碼的工具,請(qǐng)求之后直接使用css選擇器匹配说榆。即可獲得內(nèi)容虚吟。

當(dāng)然現(xiàn)在我們有更方便的工具pyspider,可以方便解析請(qǐng)求并且可以設(shè)置代理签财,偽裝身份等串慰,直接傳入url并且寫(xiě)好多級(jí)的解析函數(shù),程序便會(huì)迭代執(zhí)行唱蒸,直到把所有頁(yè)面的內(nèi)容解析出來(lái)邦鲫。這里我們直接啟動(dòng)pyspider的web應(yīng)用并且寫(xiě)好python代碼,就可以執(zhí)行爬蟲(chóng)了神汹。

知乎:先找到問(wèn)題庆捺,再把問(wèn)題下所有的回答進(jìn)行爬取,最后把問(wèn)題和評(píng)論一起處理屁魏。

功能擴(kuò)展以及深度擴(kuò)展

功能擴(kuò)展

  • 用戶(hù)注冊(cè)滔以,郵箱激活流程
  • 管理員后臺(tái)管理
  • timeline推拉結(jié)合
  • 個(gè)性化首頁(yè),timeline更多事件

深度擴(kuò)展

  • 搜索結(jié)果排序打分
  • 爬蟲(chóng)覆蓋用戶(hù)氓拼,評(píng)論你画,內(nèi)容去html標(biāo)簽
  • 個(gè)性化推薦
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末抵碟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子撬即,更是在濱河造成了極大的恐慌,老刑警劉巖呈队,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件剥槐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡宪摧,警方通過(guò)查閱死者的電腦和手機(jī)粒竖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)几于,“玉大人蕊苗,你說(shuō)我怎么就攤上這事⊙嘏恚” “怎么了朽砰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)喉刘。 經(jīng)常有香客問(wèn)我瞧柔,道長(zhǎng),這世上最難降的妖魔是什么睦裳? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任造锅,我火速辦了婚禮,結(jié)果婚禮上廉邑,老公的妹妹穿的比我還像新娘哥蔚。我一直安慰自己,他們只是感情好蛛蒙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布糙箍。 她就那樣靜靜地躺著,像睡著了一般牵祟。 火紅的嫁衣襯著肌膚如雪覆旱。 梳的紋絲不亂的頭發(fā)上司蔬,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼湃望。 笑死,一個(gè)胖子當(dāng)著我的面吹牛丙唧,可吹牛的內(nèi)容都是我干的凡蜻。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼筹淫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼站辉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤饰剥,失蹤者是張志新(化名)和其女友劉穎殊霞,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體汰蓉,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绷蹲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了顾孽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祝钢。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖若厚,靈堂內(nèi)的尸體忽然破棺而出拦英,到底是詐尸還是另有隱情,我是刑警寧澤测秸,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布疤估,位于F島的核電站,受9級(jí)特大地震影響霎冯,放射性物質(zhì)發(fā)生泄漏做裙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一肃晚、第九天 我趴在偏房一處隱蔽的房頂上張望锚贱。 院中可真熱鬧,春花似錦关串、人聲如沸拧廊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)吧碾。三九已至,卻和暖如春墓卦,著一層夾襖步出監(jiān)牢的瞬間倦春,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工落剪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留睁本,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓忠怖,卻偏偏與公主長(zhǎng)得像呢堰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凡泣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355