項(xiàng)目4 基于Node-RED 的物聯(lián)網(wǎng)前后端設(shè)計(jì)_第1頁(yè)
項(xiàng)目4 基于Node-RED 的物聯(lián)網(wǎng)前后端設(shè)計(jì)_第2頁(yè)
項(xiàng)目4 基于Node-RED 的物聯(lián)網(wǎng)前后端設(shè)計(jì)_第3頁(yè)
項(xiàng)目4 基于Node-RED 的物聯(lián)網(wǎng)前后端設(shè)計(jì)_第4頁(yè)
項(xiàng)目4 基于Node-RED 的物聯(lián)網(wǎng)前后端設(shè)計(jì)_第5頁(yè)
已閱讀5頁(yè),還剩105頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

2相關(guān)知識(shí)34任務(wù)小結(jié)與練習(xí)1任務(wù)實(shí)施任務(wù)引入與目標(biāo)Node-RED安裝與認(rèn)識(shí)一、任務(wù)引入與目標(biāo)任務(wù)目標(biāo)任務(wù)1將安裝Node-RED開(kāi)發(fā)環(huán)境,并編寫(xiě)一個(gè)簡(jiǎn)單的流程來(lái)認(rèn)識(shí)Node-RED,為接下來(lái)完整物聯(lián)網(wǎng)系統(tǒng)的前后端設(shè)計(jì)做準(zhǔn)備。任務(wù)引入一個(gè)系統(tǒng)中,物聯(lián)網(wǎng)功能只是一部分,而物聯(lián)網(wǎng)部分和其他部分有較大的區(qū)別,它和硬件結(jié)合比較緊密。針對(duì)系統(tǒng)前、后端的設(shè)計(jì),有沒(méi)有適合構(gòu)建物聯(lián)網(wǎng)應(yīng)用程序的強(qiáng)大工具,可以滿(mǎn)足快速連接硬件和設(shè)備到Web服務(wù)呢?二、相關(guān)知識(shí)什么是Node-REDNode-RED最初是IBM公司在2013年年末開(kāi)發(fā)的一個(gè)開(kāi)源項(xiàng)目,以滿(mǎn)足其快速連接硬件和設(shè)備到Web服務(wù)和其他軟件的需求。作為物聯(lián)網(wǎng)的一種黏合劑,Node-RED很快發(fā)展成為一種通用的物聯(lián)網(wǎng)編程工具。雖然Node-RED最初是用來(lái)處理物聯(lián)網(wǎng)的應(yīng)用,也就是說(shuō),它與現(xiàn)實(shí)世界交互和控制設(shè)備,但隨著它的發(fā)展,它已經(jīng)成為一個(gè)較為開(kāi)放的物聯(lián)網(wǎng)開(kāi)發(fā)工具。Node-RED編程方法Node-RED是構(gòu)建物聯(lián)網(wǎng)應(yīng)用程序的一個(gè)強(qiáng)大工具,其重點(diǎn)是簡(jiǎn)化代碼塊的“連接”以執(zhí)行任務(wù)。它使用可視化編程方法,允許開(kāi)發(fā)人員將預(yù)定義的代碼塊(稱(chēng)為“節(jié)點(diǎn)”,Node)連接起來(lái)執(zhí)行任務(wù)。連接的節(jié)點(diǎn),通常是輸入節(jié)點(diǎn)、處理節(jié)點(diǎn)和輸出節(jié)點(diǎn)的組合,當(dāng)它們連接在一起時(shí),構(gòu)成一個(gè)“流”(Flows)。課堂討論你使用過(guò)哪些可視化編程軟件?三、任務(wù)實(shí)施實(shí)施設(shè)備安裝了Windows操作系統(tǒng)的計(jì)算機(jī)。實(shí)施過(guò)程1.Node.js安裝在官網(wǎng)(/en/)下載,如圖4-1所示。圖4-1下載Node.js雙擊安裝,然后選擇合適的安裝目錄,如圖4-2所示。圖4-2選擇合適的安裝目錄三、任務(wù)實(shí)施如圖4-3所示,在ToolsforNativeModules(本機(jī)模塊的工具)界面不選中方框,否則會(huì)下載全部工具到本機(jī),速度比較慢。等待安裝完成。2.Node-RED安裝如圖4-4所示,進(jìn)入cmd,輸入命令:npminstall-g--unsafe-permnode-red。等待安裝完成。圖4-3不選擇本機(jī)模塊的工具圖4-4安裝Node-RED三、任務(wù)實(shí)施3.啟動(dòng)Node-RED如圖4-5所示,在cmd輸入node-red,即可啟動(dòng)。如圖4-6所示,打開(kāi)瀏覽器訪(fǎng)問(wèn)Node-RED::1880。需要說(shuō)明的是,是本機(jī)IP,或用localhost表示。如果處在局域網(wǎng)和廣域網(wǎng)中,可以在其他設(shè)備輸入對(duì)應(yīng)的IP地址訪(fǎng)問(wèn)。圖4-5啟動(dòng)Node-RED圖4-6訪(fǎng)問(wèn)Node-RED三、任務(wù)實(shí)施4.Node-RED節(jié)點(diǎn)如圖4-7所示,將左側(cè)的節(jié)點(diǎn)拖入中間編輯區(qū),以構(gòu)建“流”。節(jié)點(diǎn)的功能可以在右側(cè)“幫助”欄查看。雙擊節(jié)點(diǎn),即可對(duì)其進(jìn)行編輯。比如inject節(jié)點(diǎn),手動(dòng)或定期將消息注入流中。消息的有效荷載可以有多種類(lèi)型,包括字符串、JavaScript對(duì)象或當(dāng)前時(shí)間。消息共有2個(gè)屬性:topic和payload。在最右側(cè)的設(shè)置菜單,點(diǎn)擊“節(jié)點(diǎn)管理”,可以安裝和查看節(jié)點(diǎn),如處理json、郵件、mysql數(shù)據(jù)庫(kù)、存儲(chǔ)等幾類(lèi)節(jié)點(diǎn)。圖4-7Node-RED的節(jié)點(diǎn)三、任務(wù)實(shí)施5.第一個(gè)Node-RED流程如圖4-8所示,使用2個(gè)節(jié)點(diǎn),第一個(gè)是“inject”(注入)節(jié)點(diǎn),第二個(gè)是“debug”(調(diào)試)節(jié)點(diǎn)。如圖4-9所示,第一個(gè)節(jié)點(diǎn)設(shè)置輸出消息的payload(載荷)為字符串“hello,world!”,每隔5秒執(zhí)行一次。圖4-8第一個(gè)Node-RED流程圖4-9編輯inject節(jié)點(diǎn)三、任務(wù)實(shí)施如圖4-10所示,第二個(gè)節(jié)點(diǎn)設(shè)置輸出消息的payload,消息的payload是由上一個(gè)節(jié)點(diǎn)輸入的。流編輯完成后,點(diǎn)擊“部署”按鈕,打開(kāi)右邊的調(diào)試窗口(蟲(chóng)子圖標(biāo)),即可觀(guān)察debug節(jié)點(diǎn)打印的消息payload,如圖411所示。如果不想在調(diào)試窗口顯示打印內(nèi)容,那么點(diǎn)擊debug節(jié)點(diǎn)右側(cè)的框即可。后面消息的payload盡量都是用JSON格式。圖4-10編輯debug節(jié)點(diǎn)圖4-11流程運(yùn)行結(jié)果四、任務(wù)小結(jié)與練習(xí)任務(wù)小結(jié)任務(wù)1通過(guò)編寫(xiě)一個(gè)簡(jiǎn)單的流程,讓我們認(rèn)識(shí)了Node-RED,為接下來(lái)實(shí)現(xiàn)完整的物聯(lián)網(wǎng)系統(tǒng)的前后端設(shè)計(jì)做準(zhǔn)備。修改第一個(gè)Node-RED流程中inject節(jié)點(diǎn)的消息載荷為JSON對(duì)象格式,觀(guān)察debug節(jié)點(diǎn)打印的調(diào)試信息。實(shí)踐練習(xí)謝謝聆聽(tīng)2相關(guān)知識(shí)34任務(wù)小結(jié)與練習(xí)1任務(wù)實(shí)施任務(wù)引入與目標(biāo)Web展示網(wǎng)關(guān)上報(bào)的溫濕度一、任務(wù)引入與目標(biāo)任務(wù)目標(biāo)任務(wù)2通過(guò)Node-RED流程設(shè)計(jì),接收網(wǎng)關(guān)上報(bào)的MQTT消息,將消息中溫濕度字段的值解析后,通過(guò)Web頁(yè)面展示出來(lái)。解析展示的過(guò)程,與APP中的設(shè)計(jì)很像,都需要掌握J(rèn)SON解析的知識(shí)。注意,在任務(wù)2中,Node-RED創(chuàng)建了MQTT客戶(hù)端,與網(wǎng)關(guān)、APP中創(chuàng)建的MQTT客戶(hù)端的地位是相等的。網(wǎng)關(guān)用項(xiàng)目3中的程序,將周期上報(bào)間隔改為1分鐘,其他內(nèi)容不變,包括消息的主題和消息的載荷。任務(wù)引入項(xiàng)目3將網(wǎng)關(guān)上報(bào)的MQTT消息經(jīng)過(guò)解析,在APP上展示了溫濕度的值。有了Node-RED工具之后,我們也可以將硬件檢測(cè)的溫濕度值在Web上展示出來(lái),這樣數(shù)據(jù)可視化的形式就更加豐富了。二、相關(guān)知識(shí)dashboard節(jié)點(diǎn)Node-RED中常用的圖形化節(jié)點(diǎn)叫做dashboard,它主要用于快速創(chuàng)建實(shí)時(shí)數(shù)據(jù)儀表板。在安裝節(jié)點(diǎn)的輸入框內(nèi)輸入“dashboard”,找到名為“node-red-dashborad”的控件并點(diǎn)擊安裝即可。Web頁(yè)面布局總體來(lái)看,通過(guò)dashboard設(shè)計(jì)的Web頁(yè)面布局分為三級(jí),分別是:tab、group、spacer。儀表板的布局依賴(lài)于tab和group屬性,tab可以理解為頁(yè)面,group是分組,spacer即控件。一個(gè)頁(yè)面里可以有多個(gè)分組,建議使用多個(gè)分組,而不是一個(gè)大組,因?yàn)閐ashboard可以根據(jù)頁(yè)面的大小動(dòng)態(tài)調(diào)整分組的位置。三、任務(wù)實(shí)施實(shí)施設(shè)備部署了Node-RED和Arduino開(kāi)發(fā)環(huán)境的計(jì)算機(jī)。網(wǎng)關(guān)和溫濕度傳感器各一個(gè)。實(shí)施過(guò)程1.Node-RED接收MQTT消息為了完成本任務(wù)中溫濕度顯示的功能,需要在Node-RED中創(chuàng)建MQTT客戶(hù)端,接收MQTT消息,設(shè)計(jì)流程如圖4-12所示。圖4-12打印溫濕度值流程三、任務(wù)實(shí)施流程中的2個(gè)節(jié)點(diǎn),分別是mqttin(用于mqtt請(qǐng)求)和debug(用于打印調(diào)試信息)。對(duì)于mqttin節(jié)點(diǎn),設(shè)置主題為網(wǎng)關(guān)上報(bào)的消息,如圖4-13所示。接下來(lái)在mqttin節(jié)點(diǎn)中設(shè)置要連接的MQTT服務(wù)器,如圖4-14所示。圖4-13編輯mqttin節(jié)點(diǎn)圖4-14編輯MQTT節(jié)點(diǎn)的服務(wù)器三、任務(wù)實(shí)施然后設(shè)置debug節(jié)點(diǎn),輸出調(diào)試信息,如圖4-15所示。網(wǎng)關(guān)連接溫濕度傳感器,運(yùn)行,使用的程序以及硬件連接與項(xiàng)目3保持一致,這里不再介紹。部署Node-RED流程,打開(kāi)debug窗口,查看結(jié)果,如圖4-16所示。圖4-15編輯debug節(jié)點(diǎn)圖4-16打印調(diào)試結(jié)果三、任務(wù)實(shí)施2.Web頁(yè)面通過(guò)gauge展示溫度我們既可以用文本顯示消息載荷,也可以用圖表顯示網(wǎng)關(guān)上報(bào)的溫度值。將前面的節(jié)點(diǎn)設(shè)為無(wú)效,MQTT節(jié)點(diǎn)復(fù)制后還要再用。增加一個(gè)“switch”和“gauge”節(jié)點(diǎn)?!皊witch”判斷溫度解析值非空,即判斷MQTT消息中是否有“temperature”字段,如圖417所示?!癵auge”放在“健康監(jiān)測(cè)中心”頁(yè)面(對(duì)應(yīng)Web的一個(gè)菜單)的一個(gè)“溫度”組中。顯示的內(nèi)容是{{msg.payload.temperature}},即提取消息載荷的temperature字段的值,如圖4-18所示。圖4-17編輯switch節(jié)點(diǎn)圖4-18編輯gauge節(jié)點(diǎn)三、任務(wù)實(shí)施結(jié)果如圖4-19所示。網(wǎng)址是:1880/ui,用的是本機(jī)IP;如果Node-RED應(yīng)用服務(wù)器部署在公網(wǎng),可通過(guò)公網(wǎng)IP訪(fǎng)問(wèn);如果部署在局域網(wǎng),同一局域網(wǎng)里的計(jì)算機(jī)可以通過(guò)局域網(wǎng)IP訪(fǎng)問(wèn)??梢园l(fā)現(xiàn)采用了二次解析過(guò)程,第一次判斷非空,第二次再解析展示,與之前APP和網(wǎng)關(guān)對(duì)MQTT消息解析過(guò)程相同。二次解析過(guò)程可以避免以下情況:如果上報(bào)的是濕度消息,解析為空,展示錯(cuò)誤圖4-19gauge展示環(huán)境溫度三、任務(wù)實(shí)施3.Web頁(yè)面通過(guò)折線(xiàn)圖展示溫度“健康監(jiān)測(cè)中心”頁(yè)面新增group,名稱(chēng)為“溫度曲線(xiàn)”。流程中需要增加一個(gè)change和chart節(jié)點(diǎn),如圖4-20所示。設(shè)置change節(jié)點(diǎn)的載荷(即輸出到chart節(jié)點(diǎn)的載荷),為輸入此節(jié)點(diǎn)的載荷的temperature的值,如圖4-21所示。圖4-20流程中增加溫度曲線(xiàn)圖4-21編輯change節(jié)點(diǎn)三、任務(wù)實(shí)施在chart節(jié)點(diǎn)中,設(shè)置顯示10分鐘的值。折線(xiàn)圖中的標(biāo)簽為“十分鐘溫度變化”。范圍、顏色等根據(jù)喜好確定即可,如圖4-22所示。部署Node-RED流程,然后查看結(jié)果,如圖4-23所示。圖4-22編輯chart節(jié)點(diǎn)圖4-23gauge和chart顯示溫度三、任務(wù)實(shí)施關(guān)于UI布局,可以在tab的layout里進(jìn)行設(shè)計(jì),如圖4-24所示??梢栽O(shè)置寬度、高度及部件的相對(duì)位置,如圖4-25所示。圖4-24流程的UI布局圖4-26溫度監(jiān)控界面完成后重新部署,結(jié)果如圖4-26所示。圖4-25設(shè)置UI屬性三、任務(wù)實(shí)施4.Web頁(yè)面通過(guò)gauge、折線(xiàn)圖展示溫度、濕度參照溫度顯示,分別以?xún)x表盤(pán)和折線(xiàn)圖的形式顯示網(wǎng)關(guān)上報(bào)的濕度值。流程如圖4-27所示,不再詳細(xì)分析。調(diào)整布局,運(yùn)行一段時(shí)間之后的結(jié)果如圖4-28所示。圖4-27流程中增加濕度監(jiān)控圖4-28溫濕度監(jiān)測(cè)情況四、任務(wù)小結(jié)與練習(xí)任務(wù)小結(jié)任務(wù)2在Node-RED中設(shè)計(jì)流程,分別實(shí)現(xiàn)了Node-RED接收MQTT消息、Web頁(yè)面通過(guò)gauge展示溫度、Web頁(yè)面通過(guò)折線(xiàn)圖展示溫度和濕度等功能。任務(wù)2重點(diǎn)學(xué)習(xí)了節(jié)點(diǎn)對(duì)JSON格式消息的解析方法。將展示溫濕度流程中折線(xiàn)圖節(jié)點(diǎn)的橫軸改為20分鐘,觀(guān)察20分鐘的變化,將結(jié)果提交到課程學(xué)習(xí)平臺(tái)。實(shí)踐練習(xí)謝謝聆聽(tīng)2相關(guān)知識(shí)34任務(wù)小結(jié)與練習(xí)1任務(wù)實(shí)施任務(wù)引入與目標(biāo)在Node-RED中搭建Web服務(wù)器一、任務(wù)引入與目標(biāo)任務(wù)目標(biāo)任務(wù)3在Node-RED中搭建Web服務(wù)器,APP收到用戶(hù)反饋意見(jiàn)時(shí),APP中創(chuàng)建的HTTP客戶(hù)端連接服務(wù)器;服務(wù)器對(duì)HTTP請(qǐng)求進(jìn)行處理,完成郵件轉(zhuǎn)發(fā),并將響應(yīng)發(fā)回;APP接收HTTP響應(yīng),處理其中的數(shù)據(jù)部分。實(shí)現(xiàn)效果:(1)手機(jī)點(diǎn)擊“反饋建議”按鈕后,調(diào)出對(duì)話(huà)框。(2)在對(duì)話(huà)框輸入內(nèi)容后,以post方式向Node-RED中創(chuàng)建的HTTP服務(wù)端提交HTTP請(qǐng)求,網(wǎng)址為后臺(tái)url加上后綴APP_feedback。(3)Node-RED中創(chuàng)建的HTTP服務(wù)端收到請(qǐng)求后,發(fā)回響應(yīng)內(nèi)容“成功收到,感謝您的反饋與建議”,APP將接收的響應(yīng)內(nèi)容在屏幕上Toast出來(lái)。(4)后臺(tái)將收到的內(nèi)容轉(zhuǎn)發(fā)至作者郵箱。任務(wù)引入如果用戶(hù)對(duì)APP有一些建議,那么該怎樣聯(lián)系作者呢?可以在Node-RED中創(chuàng)建Web服務(wù)器,當(dāng)用戶(hù)有建議時(shí),可以通過(guò)HTTP客戶(hù)端向Web服務(wù)器提交請(qǐng)求,由Node-RED處理。二、相關(guān)知識(shí)Node-RED中的郵箱控件Node-RED的輸出郵箱控件,把msg.payload作為郵件內(nèi)容,把msg.topic作為郵件主題。消息接收者可以在節(jié)點(diǎn)中配置,如果它是空白的,那么應(yīng)該使用msg.to來(lái)設(shè)置它。消息的屬性如果留下空白,也可以指定msg.cc(轉(zhuǎn)發(fā)的收件箱地址)屬性。注意,使用SMTP的SSL端口465。郵箱的IMAP和SMTP服務(wù)IMAP是一種電子郵件接收的協(xié)議,用于管理和檢索來(lái)自接收服務(wù)器的電子郵件消息。SMTP是一種電子郵件發(fā)送的協(xié)議,可以使用SMTP從郵件客戶(hù)端(如QQ郵箱)向接收電子郵件服務(wù)器發(fā)送、中繼或轉(zhuǎn)發(fā)郵件。SMTP中繼服務(wù)可以幫助用戶(hù)發(fā)送電子郵件,而不需要建立自己的SMTP服務(wù)器。二、相關(guān)知識(shí)以QQ郵箱為例,設(shè)置IMAP(接收)/SMTP(發(fā)送)服務(wù)。需要保證IMAP/SMTP服務(wù)這一項(xiàng)是開(kāi)啟的,如圖4-29所示。如圖4-30所示,成功開(kāi)啟后,會(huì)給一個(gè)授權(quán)碼,需要記住。如果忘記也沒(méi)關(guān)系,可以再次生成。上述配置的IMAP和SMTP中繼服務(wù),會(huì)在Node-RED中的接收和發(fā)送郵件節(jié)點(diǎn)用到,用來(lái)實(shí)現(xiàn)接收郵件和發(fā)送郵件功能。圖4-29QQ郵箱的IMAP/SMTP服務(wù)圖4-30IMAP/SMTP服務(wù)的授權(quán)碼三、任務(wù)實(shí)施實(shí)施設(shè)備部署了AndroidStudio和Node-RED開(kāi)發(fā)環(huán)境的計(jì)算機(jī)。實(shí)施過(guò)程1.APP設(shè)計(jì)APP設(shè)計(jì)里,需要用到OkHttp框架和對(duì)話(huà)框的知識(shí)。在ThirdActivity.java中,針對(duì)btn32進(jìn)行設(shè)計(jì)。(1)對(duì)話(huà)框。已經(jīng)添加viewBinding框架,需要在第三個(gè)頁(yè)面編寫(xiě)btn32按鈕的事件監(jiān)聽(tīng)方法。binding3.btn32.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewview){finalEditTextet=newEditText(ThirdActivity.this);et.setText("很好");AlertDialogalertDialog=newAlertDialog.Builder(ThirdActivity.this).setTitle("請(qǐng)?zhí)峤灰庖?jiàn)建議").setView(et).setPositiveButton("確定",newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialogInterface,inti){textSuggest=et.getText().toString();Post_as();}}).setNegativeButton("取消",null).show();}})三、任務(wù)實(shí)施前面需要定義變量:privateStringtextSuggest;點(diǎn)擊“確定”按鈕后,調(diào)用Post_as()函數(shù),將文本框的內(nèi)容textSuggest以post的方式、HTTP請(qǐng)求提交給后臺(tái):11:1880/APP_feedback。(2)異步請(qǐng)求Post_as()函數(shù)。所謂異步請(qǐng)求,就是把請(qǐng)求加入enqueue(隊(duì)列)中,等待執(zhí)行。接下來(lái),我們?cè)诋惒秸?qǐng)求函數(shù)Post_as()中使用POST方法,提交異步請(qǐng)求,代碼如下://異步請(qǐng)求函數(shù)privatevoidPost_as(){//創(chuàng)建表單FormBodyformBody=newFormBody.Builder().add("username",).add("feedback",textSuggest).build();//將表單數(shù)據(jù)放入request中,通過(guò)post方法提交Requestrequest=newRequest.Builder().url("11:1880/APP_feedback").post(formBody).build();//將客戶(hù)端加入隊(duì)列中,會(huì)自動(dòng)在子線(xiàn)程中運(yùn)行,返回有2種情況:失敗或者有響應(yīng)okHttpClient.newCall(request).enqueue(newCallback(){@OverridepublicvoidonFailure(@NonNullCallcall,@NonNullIOExceptione){e.printStackTrace();}三、任務(wù)實(shí)施如果沒(méi)有收到response,那么不做處理;如果收到response,那么Toast出后臺(tái)響應(yīng)的數(shù)據(jù)部分。@OverridepublicvoidonResponse(@NonNullCallcall,@NonNullResponseresponse)throwsIOException{//獲取響應(yīng)的數(shù)據(jù)部分Stringresult=response.body().string();//在主線(xiàn)程中Toast出來(lái)runOnUiThread(newRunnable(){@Overridepublicvoidrun(){Toast.makeText(ThirdActivity.this,"后臺(tái)回復(fù):"+result,Toast.LENGTH_SHORT).show();}});}});}三、任務(wù)實(shí)施其中,11為Node-RED所部署的電腦在局域網(wǎng)中的IP地址。如圖4-31所示,查看IP地址的方法:cmd命令行。輸入:ipconfig。至此,APP設(shè)計(jì)就完成了,結(jié)構(gòu)如圖4-32所示。圖4-31查看IP地址圖4-32APP結(jié)構(gòu)三、任務(wù)實(shí)施2.Node-RED流程設(shè)計(jì)(1)測(cè)試打印APP提交的表單信息。在cmd命令行,輸入:node-red。啟動(dòng)Node-RED。注意不要關(guān)閉cmd。在NR中,添加一個(gè)httpin節(jié)點(diǎn)和一個(gè)debug節(jié)點(diǎn),連接起來(lái)。httpin是一個(gè)提供Web服務(wù)的HTTP端點(diǎn)(HTTP服務(wù)器),供APP訪(fǎng)問(wèn)。如圖4-33所示,配置httpin節(jié)點(diǎn),請(qǐng)求方式為POST;URL的后綴為/APP_feedback,完整的URL為11:1880/APP_feedback。debug節(jié)點(diǎn)直接打印消息內(nèi)容,即httpin節(jié)點(diǎn)(HTTP服務(wù)器)收到的消息內(nèi)容。圖4-33編輯httpin節(jié)點(diǎn)三、任務(wù)實(shí)施部署流程2,運(yùn)行APP。當(dāng)APP提交反饋意見(jiàn)“很好!!!”時(shí),Node-RED的debug打印內(nèi)容如圖4-34所示。圖4-34表明:Node-RED成功收到APP的HTTP客戶(hù)端POST的數(shù)據(jù),這正是APP代碼的2個(gè)表單項(xiàng):圖4-34Node-RED接收到HTTP請(qǐng)求//創(chuàng)建表單FormBodyformBody=newFormBody.Builder().add("username",).add("feedback",textSuggest).build();三、任務(wù)實(shí)施(2)Web展示APP提交的表單信息。在Web頁(yè)面顯示APP提交的表單內(nèi)容是較為容易的,回顧之前的JSON解析知識(shí)即可完成。設(shè)計(jì)dashboard,添加頁(yè)面(菜單)“實(shí)時(shí)反饋與建議”,如圖4-35所示,添加一個(gè)組“反饋與建議”,組里面添加2個(gè)“text”節(jié)點(diǎn)作為組件。2個(gè)text節(jié)點(diǎn)的配置如圖4-36所示。圖4-35流程中添加反饋與建議部分圖4-36編輯text節(jié)點(diǎn)三、任務(wù)實(shí)施查看Web頁(yè)面,如圖4-37所示。(3)Web服務(wù)器給APP發(fā)回response。如圖4-38所示,在流程中增加一個(gè)“change”節(jié)點(diǎn)和一個(gè)“httpresponse”節(jié)點(diǎn)。httpresponse節(jié)點(diǎn)將響應(yīng)(response)送回提交請(qǐng)求(request)的HTTP客戶(hù)端。圖4-37查看Web頁(yè)面圖4-38流程中設(shè)定響應(yīng)內(nèi)容圖4-39編輯change節(jié)點(diǎn)change節(jié)點(diǎn)配置如圖4-39所示。三、任務(wù)實(shí)施httpresponse節(jié)點(diǎn)按默認(rèn)設(shè)置即可,如圖4-40所示。結(jié)果如圖4-41所示:APP提交之后,會(huì)Toast從后臺(tái)response的內(nèi)容。圖4-40編輯httpresponse節(jié)點(diǎn)圖4-41APP接收到response三、任務(wù)實(shí)施在流程中添加發(fā)送郵件節(jié)點(diǎn),如圖4-42所示。如果沒(méi)有這個(gè)節(jié)點(diǎn),那么需要安裝,如圖4-43所示。圖4-42添加發(fā)送郵件節(jié)點(diǎn)圖4-43安裝email節(jié)點(diǎn)三、任務(wù)實(shí)施發(fā)送郵件節(jié)點(diǎn)配置,包括收件箱地址、郵件服務(wù)器和端口號(hào)、發(fā)件箱地址和授權(quán)碼,如圖4-44所示。部署流程,查看收件箱是否收到郵件,結(jié)果如圖4-45所示。圖4-44編輯email節(jié)點(diǎn)圖4-45收件箱收到郵件當(dāng)然我們還可以在郵件節(jié)點(diǎn)的前面加上函數(shù)節(jié)點(diǎn),配置郵件轉(zhuǎn)發(fā)等功能,可自行查閱資料研究。我們還可以讓Node-RED接收郵件。四、任務(wù)小結(jié)與練習(xí)任務(wù)小結(jié)任務(wù)3在Node-RED中設(shè)計(jì)流程,并結(jié)合APP中POST方式的HTTP請(qǐng)求,實(shí)現(xiàn)了郵件轉(zhuǎn)發(fā)功能。修改HTTP請(qǐng)求時(shí)表單中的字段名及值,在自己的郵箱中接收用戶(hù)提交的反饋意見(jiàn)。實(shí)踐練習(xí)謝謝聆聽(tīng)2相關(guān)知識(shí)34任務(wù)小結(jié)與練習(xí)1任務(wù)實(shí)施任務(wù)引入與目標(biāo)部署MySQL數(shù)據(jù)庫(kù)服務(wù)器一、任務(wù)引入與目標(biāo)任務(wù)引入APP中的很多功能都需要用到數(shù)據(jù)庫(kù),比如用戶(hù)登錄和注冊(cè)。如果將用戶(hù)名和密碼存放在Android工程中,是很難實(shí)現(xiàn)注冊(cè)功能的。我們可以部署MySQL數(shù)據(jù)庫(kù)服務(wù)器,來(lái)完成需要數(shù)據(jù)存儲(chǔ)的功能。任務(wù)目標(biāo)任務(wù)4將在計(jì)算機(jī)上部署MySQL數(shù)據(jù)庫(kù)服務(wù)器,并安裝可視化數(shù)據(jù)庫(kù)管理軟件,方便數(shù)據(jù)庫(kù)的操作。如果擁有一臺(tái)云服務(wù)器,那么將MySQL數(shù)據(jù)庫(kù)部署在上面,使用會(huì)更為方便。二、相關(guān)知識(shí)使用數(shù)據(jù)庫(kù)的優(yōu)勢(shì)數(shù)據(jù)庫(kù)是現(xiàn)代應(yīng)用程序的重要組成部分,使用數(shù)據(jù)庫(kù)可以帶來(lái)以下幾個(gè)優(yōu)勢(shì):(1)數(shù)據(jù)持久化。通過(guò)將數(shù)據(jù)存儲(chǔ)在數(shù)據(jù)庫(kù)中,可以確保數(shù)據(jù)即使在應(yīng)用程序關(guān)閉或重啟之后也能夠保存下來(lái),并且不會(huì)因?yàn)橄到y(tǒng)崩潰或斷電等問(wèn)題而丟失。(2)數(shù)據(jù)共享。多個(gè)應(yīng)用程序可以使用同一個(gè)數(shù)據(jù)庫(kù),從而實(shí)現(xiàn)數(shù)據(jù)共享和協(xié)作,這樣可以提高團(tuán)隊(duì)協(xié)作效率,避免重復(fù)開(kāi)發(fā)。(3)數(shù)據(jù)安全性。通過(guò)使用數(shù)據(jù)庫(kù)管理系統(tǒng),可以對(duì)數(shù)據(jù)進(jìn)行加密、備份和恢復(fù)等操作,從而保證數(shù)據(jù)的安全性和可靠性。(4)數(shù)據(jù)一致性。在數(shù)據(jù)庫(kù)中,可以通過(guò)事務(wù)控制機(jī)制來(lái)保證數(shù)據(jù)的一致性,防止數(shù)據(jù)沖突和錯(cuò)誤。(5)高效查詢(xún)。數(shù)據(jù)庫(kù)具有快速查詢(xún)和檢索數(shù)據(jù)的能力,便于進(jìn)行數(shù)據(jù)分析和處理,提高數(shù)據(jù)的處理效率和準(zhǔn)確性??傊?使用數(shù)據(jù)庫(kù)不僅可以提高應(yīng)用程序的可靠性、安全性和靈活性,還可以提高數(shù)據(jù)處理效率和數(shù)據(jù)質(zhì)量,是現(xiàn)代應(yīng)用程序的不可或缺的一部分。二、相關(guān)知識(shí)常用的數(shù)據(jù)庫(kù)在開(kāi)發(fā)中,常用的數(shù)據(jù)庫(kù)有如下幾種:(1)SQLite是一個(gè)輕量級(jí)的嵌入式關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),適用于移動(dòng)設(shè)備和嵌入式設(shè)備等資源受限環(huán)境。它支持大部分SQL語(yǔ)法,并具有高可靠性、低復(fù)雜度和易于集成的特點(diǎn)。(2)MySQL是一種流行的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),適用于多用戶(hù)、高并發(fā)的應(yīng)用場(chǎng)景。它具有高性能、高可靠性和可擴(kuò)展性等優(yōu)點(diǎn),同時(shí)支持多種操作系統(tǒng)和編程語(yǔ)言。(3)Oracle是一個(gè)企業(yè)級(jí)關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),適用于高要求的數(shù)據(jù)處理和管理場(chǎng)景。它具有高可靠性、安全性、靈活性和可擴(kuò)展性等優(yōu)點(diǎn),并支持多種操作系統(tǒng)和編程語(yǔ)言。(4)MongoDB是一個(gè)面向文檔的NoSQL數(shù)據(jù)庫(kù)管理系統(tǒng),適用于大規(guī)模數(shù)據(jù)存儲(chǔ)和處理場(chǎng)景。它具有高速度、高伸縮性和易于擴(kuò)展等優(yōu)點(diǎn),并支持多種操作系統(tǒng)和編程語(yǔ)言。(5)Redis是一個(gè)高速的內(nèi)存鍵值存儲(chǔ)數(shù)據(jù)庫(kù),適用于高速數(shù)據(jù)讀寫(xiě)和查詢(xún)場(chǎng)景。它具有高速度、高吞吐量和低延遲等優(yōu)點(diǎn),并支持多種數(shù)據(jù)結(jié)構(gòu)和編程語(yǔ)言。這些數(shù)據(jù)庫(kù)各有優(yōu)劣,選擇哪種數(shù)據(jù)庫(kù)取決于具體應(yīng)用場(chǎng)景和需求。例如,如果需要在移動(dòng)設(shè)備上存儲(chǔ)和管理數(shù)據(jù),則SQLite可能是更好的選擇;如果需要處理高并發(fā)的事務(wù)和請(qǐng)求,則MySQL或Oracle可能更適合;如果需要存儲(chǔ)大量文檔類(lèi)型的數(shù)據(jù),則MongoDB可能更合適;如果需要高速讀寫(xiě)和查詢(xún)數(shù)據(jù),則Redis可能更適合。三、任務(wù)實(shí)施實(shí)施設(shè)備安裝了Windows操作系統(tǒng)的計(jì)算機(jī)。實(shí)施過(guò)程1.下載MySQL安裝包在瀏覽器中輸入官網(wǎng)網(wǎng)址(/downloads/windows/installer/8.0.html),進(jìn)入下載頁(yè)面,下載安裝包,如圖4-46所示。圖4-46下載MySQL安裝包三、任務(wù)實(shí)施2.安裝MySQL雙擊安裝,選擇安裝類(lèi)型:僅服務(wù)器,如圖4-47所示。其他步驟按默認(rèn)操作,直到顯示安裝完成,如圖4-48所示。圖4-47選擇安裝類(lèi)型界面圖4-48MySQL安裝完成界面三、任務(wù)實(shí)施3.配置MySQL出現(xiàn)以下界面,默認(rèn)選第一項(xiàng),主要是端口號(hào)的設(shè)置,如圖4-49所示。密碼驗(yàn)證方式有兩種:caching_sha2_password,mysql_native_password。建議選擇第二種,如圖4-50所示。圖4-49端口號(hào)設(shè)置界面圖4-50密碼驗(yàn)證方式界面三、任務(wù)實(shí)施設(shè)置密碼,如圖4-51所示。系統(tǒng)服務(wù)名稱(chēng)、啟動(dòng)方式等按默認(rèn)即可,如圖4-52所示。圖4-51設(shè)置密碼界面圖4-52系統(tǒng)服務(wù)界面三、任務(wù)實(shí)施如圖4-53所示,勾選Yes。配置完成,然后逐步執(zhí)行即可。4.測(cè)試MySQL如圖4-54所示,從開(kāi)始菜單中打開(kāi)剛剛安裝的mysql命令行客戶(hù)端,輸入密碼按回車(chē)鍵進(jìn)入,然后輸入“showdatabases;”。圖4-54的命令行界面顯示了MySQL服務(wù)器中默認(rèn)存在的數(shù)據(jù)庫(kù),工作正常。圖4-53用戶(hù)權(quán)限界面圖4-54測(cè)試顯示數(shù)據(jù)庫(kù)名三、任務(wù)實(shí)施下載網(wǎng)址:/download.php,如圖4-55所示。下載后,雙擊安裝。安裝完成后,登錄界面如圖4-56所示。輸入正確的IP地址、用戶(hù)名、密碼、端口,即可登錄,如圖4-57所示。圖4-55下載HeidiSQL圖4-56HeidiSQL會(huì)話(huà)圖4-57進(jìn)入MySQL四、任務(wù)小結(jié)與練習(xí)任務(wù)小結(jié)任務(wù)4在計(jì)算機(jī)上部署了MySQL數(shù)據(jù)庫(kù)服務(wù)器,并安裝了可視化數(shù)據(jù)庫(kù)管理軟件HeidiSQL。為MySQL增加一個(gè)普通用戶(hù),然后通過(guò)HeidiSQL找到mysql數(shù)據(jù)庫(kù)里的user表,看看新增加的用戶(hù)是否存在。實(shí)踐練習(xí)謝謝聆聽(tīng)2相關(guān)知識(shí)34任務(wù)小結(jié)與練習(xí)1任務(wù)實(shí)施任務(wù)引入與目標(biāo)Node-RED對(duì)MySQL數(shù)據(jù)庫(kù)的增刪改查一、任務(wù)引入與目標(biāo)任務(wù)引入數(shù)據(jù)庫(kù)最基本和常用的操作就是對(duì)數(shù)據(jù)表記錄的增刪改查。在Node-RED中該如何訪(fǎng)問(wèn)MySQL中的數(shù)據(jù)庫(kù),進(jìn)而對(duì)數(shù)據(jù)表中的記錄進(jìn)行增刪改查呢?任務(wù)目標(biāo)任務(wù)5將在MySQL里創(chuàng)建數(shù)據(jù)庫(kù)和數(shù)據(jù)表,通過(guò)Node-RED訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),實(shí)現(xiàn)對(duì)數(shù)據(jù)表記錄的增刪改查,其中的關(guān)鍵是SQL語(yǔ)句語(yǔ)法。二、相關(guān)知識(shí)增加一條記錄的SQL語(yǔ)句語(yǔ)法:INSERTINTOtable_name(column1,column2,column3,...)VALUES(value1,value2,value3,...);功能是:插入一條記錄到表table_name中,值是value1,value2,value3,...。對(duì)應(yīng)字段為column1,column2,column3,...。刪除記錄的SQL語(yǔ)句語(yǔ)法:DELETEFROMtable_nameWHEREsome_column=some_value;功能是:當(dāng)滿(mǎn)足條件some_column=some_value時(shí),從表table_name中刪除某條記錄。二、相關(guān)知識(shí)修改記錄的SQL語(yǔ)句語(yǔ)法:UPDATEtable_nameSETcolumn1=value1,column2=value2,...WHEREsome_column=some_value;功能是:當(dāng)滿(mǎn)足條件some_column=some_value時(shí),修改table_name表中記錄column1字段的值為value1,column2字段的值為value2,以此類(lèi)推。查詢(xún)表語(yǔ)法:SELECTcolumn1,column2FROMtable_name;功能是:查詢(xún)表中記錄的column1和column2列的值;可以使用WHERE語(yǔ)句來(lái)包含任何條件,可以使用LIMIT屬性來(lái)設(shè)定返回的記錄數(shù)。課堂討論SQL語(yǔ)句中的關(guān)鍵字區(qū)分大小寫(xiě)嗎?三、任務(wù)實(shí)施實(shí)施設(shè)備部署了MySQL和Node-RED開(kāi)發(fā)環(huán)境的計(jì)算機(jī)。實(shí)施過(guò)程1.新建數(shù)據(jù)庫(kù)和數(shù)據(jù)表新建數(shù)據(jù)庫(kù)和數(shù)據(jù)表在命令行和可視化管理軟件中均可完成。任務(wù)5以HeidiSQL為例講解。(1)創(chuàng)建數(shù)據(jù)庫(kù)node_red_test。創(chuàng)建新的數(shù)據(jù)庫(kù)node_red_test,如圖4-58所示。圖4-58創(chuàng)建數(shù)據(jù)庫(kù)三、任務(wù)實(shí)施(2)創(chuàng)建數(shù)據(jù)表student。如圖4-59所示,創(chuàng)建數(shù)據(jù)表,共四個(gè)字段:id、name、age、class。其中,id為自動(dòng)增長(zhǎng)。id設(shè)為主鍵,如圖4-60所示。圖4-59創(chuàng)建數(shù)據(jù)表圖4-60創(chuàng)建主鍵索引然后保存即可。現(xiàn)在表中數(shù)據(jù)記錄顯示為0條記錄,如圖4-61所示。圖4-61student表的記錄三、任務(wù)實(shí)施2.配置Node-RED中的mysql節(jié)點(diǎn)啟動(dòng)Node-RED。先在命令行輸入node-red,然后在瀏覽器輸入網(wǎng)址登錄::1880/。將mysql節(jié)點(diǎn)拖入流程中,如圖4-62所示,配置mysql節(jié)點(diǎn)。如圖4-63所示,如果信息正確,部署之后,就會(huì)發(fā)現(xiàn)數(shù)據(jù)庫(kù)node_red_test連接成功。圖4-62編輯mysql節(jié)點(diǎn)圖4-63成功連接到數(shù)據(jù)庫(kù)node_red_test三、任務(wù)實(shí)施3.通過(guò)mysql節(jié)點(diǎn)增加一條記錄如圖4-64所示,拖入一個(gè)inject節(jié)點(diǎn)和一個(gè)function節(jié)點(diǎn),連接起來(lái)。其中,inject用于單次觸發(fā),function用于編寫(xiě)數(shù)據(jù)庫(kù)操作的SQL語(yǔ)句。節(jié)點(diǎn)的配置如圖4-65所示。圖4-64增加一條記錄流程圖4-65編輯inject節(jié)點(diǎn)三、任務(wù)實(shí)施function節(jié)點(diǎn)實(shí)際上就是一個(gè)JavaScript代碼編輯器,在function節(jié)點(diǎn)的函數(shù)選項(xiàng)卡編輯msg的topic和payload,傳入下一節(jié)點(diǎn)(即node_red_test數(shù)據(jù)庫(kù)節(jié)點(diǎn)),如圖4-66所示。完整的SQL語(yǔ)句為:insertinto"student"("id","name","age","class")values(,"zhangsan",19,"IOT2101")。其中,id的值為空,因?yàn)閕d是自動(dòng)增加的,可以不用賦值。完成后部署。點(diǎn)擊inject節(jié)點(diǎn)觸發(fā)一次,如圖4-67所示。圖4-66編輯function節(jié)點(diǎn)圖4-68數(shù)據(jù)表增加了一條記錄查看數(shù)據(jù)庫(kù)node_red_test中student表的數(shù)據(jù),增加了一條記錄,如圖4-68所示。圖4-67觸發(fā)inject節(jié)點(diǎn)三、任務(wù)實(shí)施按同樣的方法,增加3個(gè)inject和3個(gè)function節(jié)點(diǎn),在數(shù)據(jù)表中增加3條記錄,如圖4-69所示。圖4-69增加4條記錄的流程圖4-70數(shù)據(jù)表中的4條記錄重新部署,新增加的3個(gè)inject節(jié)點(diǎn)各觸發(fā)一次。結(jié)果如圖4-70所示。三、任務(wù)實(shí)施4.通過(guò)mysql節(jié)點(diǎn)修改記錄假設(shè)剛才輸入的lisi的年齡錯(cuò)了,不是20歲而是21歲。修改記錄的流程如圖4-71所示。圖4-71修改記錄的流程圖4-72編輯function節(jié)點(diǎn)如圖4-72所示,用SQL語(yǔ)句編輯function節(jié)點(diǎn),語(yǔ)句為:update"student"set"age"=21where"name"="lisi"。三、任務(wù)實(shí)施部署之后,單擊inject節(jié)點(diǎn)左側(cè)的方框觸發(fā),如圖4-73所示。圖4-73觸發(fā)inject節(jié)點(diǎn)圖4-74修改數(shù)據(jù)表中的記錄結(jié)果如圖4-74所示,可見(jiàn),lisi的age被修改成了21歲。三、任務(wù)實(shí)施5.通過(guò)mysql節(jié)點(diǎn)查詢(xún)數(shù)據(jù)表(1)查詢(xún)操作。在查詢(xún)操作之前,把上面2個(gè)mysql節(jié)點(diǎn)設(shè)置為無(wú)效,以節(jié)省資源。節(jié)點(diǎn)無(wú)效的方法:打開(kāi)節(jié)點(diǎn),在左下角點(diǎn)擊即可在“有效”和“無(wú)效”之間切換。節(jié)點(diǎn)無(wú)效之后,則變成半透明的。下面編輯流程,共4個(gè)節(jié)點(diǎn),如圖4-75所示。如圖4-76所示編輯function節(jié)點(diǎn),傳往下一個(gè)節(jié)點(diǎn)的消息為SQL語(yǔ)句:select*from"student"where"name"="lisi"。圖4-75查詢(xún)數(shù)據(jù)表的流程圖4-76編輯function節(jié)點(diǎn)三、任務(wù)實(shí)施部署之后,觸發(fā)。打印結(jié)果如圖4-77所示。因?yàn)橹徊樵?xún)到一條記錄,所以返回的列表(數(shù)組)中只有一個(gè)元素。這個(gè)唯一的索引為0的元素是JsonObject(JSON對(duì)象)格式的,由4個(gè)成員構(gòu)成。所以可能有人會(huì)問(wèn):“如何取出其班級(jí)值呢?”有了數(shù)組和JSON對(duì)象的知識(shí),我們很容易可以寫(xiě)出:msg.payload[0].class??梢栽赿ebug節(jié)點(diǎn)前增加一個(gè)function節(jié)點(diǎn)或change節(jié)點(diǎn),獲取數(shù)據(jù)庫(kù)查詢(xún)的返回內(nèi)容并提取之后,在debug打印出來(lái)。(2)change節(jié)點(diǎn)解析。增加change節(jié)點(diǎn),如圖4-78所示。圖4-77打印查詢(xún)結(jié)果圖4-78增加change節(jié)點(diǎn)三、任務(wù)實(shí)施change節(jié)點(diǎn)配置如圖4-79所示。部署并觸發(fā),觀(guān)察結(jié)果,如圖4-80所示。圖4-79編輯change節(jié)點(diǎn)圖4-80打印解析結(jié)果三、任務(wù)實(shí)施(3)function節(jié)點(diǎn)解析。增加function節(jié)點(diǎn),如圖4-81所示。function節(jié)點(diǎn)配置,如圖4-82所示。圖4-81增加function節(jié)點(diǎn)圖4-82編輯function節(jié)點(diǎn)三、任務(wù)實(shí)施部署并觸發(fā),觀(guān)察結(jié)果,如圖4-83所示。6.通過(guò)mysql節(jié)點(diǎn)刪除記錄刪除name為wangwu的記錄,流程如圖4-84所示。圖4-83打印解析結(jié)果圖4-84刪除記錄流程三、任務(wù)實(shí)施如圖4-85所示,配置function節(jié)點(diǎn),SQL語(yǔ)句為:delete

from"student"where"name"="wangwu"。部署并觸發(fā),如圖4-86所示。圖4-85編輯function節(jié)點(diǎn)圖4-87刪除一條記錄的結(jié)果查看結(jié)果,如圖4-87所示,wangwu的記錄已經(jīng)不在了。圖4-86流程運(yùn)行結(jié)果四、任務(wù)小結(jié)與練習(xí)任務(wù)小結(jié)任務(wù)5通過(guò)Node-RED中的mysql節(jié)點(diǎn),實(shí)現(xiàn)了對(duì)數(shù)據(jù)表記錄的增刪改查,為接下來(lái)物聯(lián)網(wǎng)系統(tǒng)中的數(shù)據(jù)庫(kù)操作做好了準(zhǔn)備。需要注意采用SQL語(yǔ)句實(shí)現(xiàn)的增刪改查,查詢(xún)時(shí)會(huì)返回一個(gè)數(shù)組,數(shù)組的每個(gè)元素就是數(shù)據(jù)庫(kù)查詢(xún)結(jié)果集里面的每條記錄,數(shù)組元素是滿(mǎn)足JSON對(duì)象格式的??梢园凑諏?zhuān)業(yè)和班級(jí)同學(xué)的情況,創(chuàng)建數(shù)據(jù)庫(kù)和數(shù)據(jù)表,通過(guò)Node-RED的mysql節(jié)點(diǎn)完成增刪改查操作。實(shí)踐練習(xí)謝謝聆聽(tīng)2相關(guān)知識(shí)34任務(wù)小結(jié)與練習(xí)1任務(wù)實(shí)施任務(wù)引入與目標(biāo)APP的用戶(hù)注冊(cè)功能一、任務(wù)引入與目標(biāo)任務(wù)引入有了任務(wù)5中Node-RED對(duì)數(shù)據(jù)庫(kù)操作的基礎(chǔ)之后,我們就可以設(shè)計(jì)APP的用戶(hù)注冊(cè)功能了。注冊(cè)功能的關(guān)鍵是APP中HTTP客戶(hù)端和Node-RED中Web服務(wù)器之間的HTTP通信,以及Node-RED對(duì)數(shù)據(jù)表的查詢(xún)和增加操作。任務(wù)目標(biāo)任務(wù)6將實(shí)現(xiàn):(1)在APP中點(diǎn)擊btn12按鈕,彈出自定義對(duì)話(huà)框;(2)在對(duì)話(huà)框中輸入要注冊(cè)的用戶(hù)名和密碼,通過(guò)HTTP客戶(hù)端向Web服務(wù)器發(fā)送POST方式的請(qǐng)求;(3)Web服務(wù)器接收到請(qǐng)求后,查詢(xún)用戶(hù)表中是否已存在用戶(hù)名并發(fā)回response,如不存在則往用戶(hù)表增加一條記錄(即注冊(cè)功能);(4)APP的HTTP客戶(hù)端收到HTTPresponse后,Toast注冊(cè)成功與否的提示信息。二、相關(guān)知識(shí)常用的MySQL索引索引是數(shù)據(jù)庫(kù)中的一種數(shù)據(jù)結(jié)構(gòu),它可以提高查詢(xún)和排序的速度,并且加速對(duì)表的訪(fǎng)問(wèn)。MySQL支持多種類(lèi)型的索引,以下是一些常用的MySQL索引:(1)主鍵索引是唯一的索引,用于確保表中每行數(shù)據(jù)的唯一性,可以提供快速的數(shù)據(jù)查詢(xún)和排序;(2)唯一索引也用于確保表中每行數(shù)據(jù)的唯一性,但允許空值,與主鍵索引不同,唯一索引可以有多個(gè);(3)普通索引是最基本的索引類(lèi)型,它沒(méi)有任何約束條件,可以用于快速查詢(xún)和排序;(4)全文索引是一種特殊的索引類(lèi)型,它可以用于全文搜索和匹配文本內(nèi)容,而不是只能用于精確匹配;(5)組合索引是將多個(gè)列作為一個(gè)索引來(lái)創(chuàng)建的,可以提高多列聯(lián)合查詢(xún)和排序的速度。需要注意的是,盡管索引可以提高查詢(xún)和排序的速度,但過(guò)多的索引會(huì)使寫(xiě)入操作變慢并占用更多的磁盤(pán)空間。因此,在設(shè)計(jì)和使用索引時(shí),我們應(yīng)該權(quán)衡查詢(xún)和寫(xiě)入操作的比例,并根據(jù)具體場(chǎng)景選擇適當(dāng)?shù)乃饕?lèi)型和數(shù)量。二、相關(guān)知識(shí)如何實(shí)現(xiàn)APP的用戶(hù)注冊(cè)功能實(shí)現(xiàn)APP的用戶(hù)注冊(cè)功能需要在客戶(hù)端和服務(wù)器端分別編寫(xiě)代碼??蛻?hù)端:首先在APP中添加用戶(hù)注冊(cè)界面,并采集用戶(hù)輸入的基本信息,如用戶(hù)名、密碼、電子郵件地址等;然后對(duì)用戶(hù)輸入的信息進(jìn)行驗(yàn)證和校驗(yàn),確保數(shù)據(jù)的正確性和完整性;最后將用戶(hù)輸入的信息封裝成一個(gè)請(qǐng)求對(duì)象,并通過(guò)HTTP協(xié)議發(fā)送到服務(wù)器端。服務(wù)器端:首先接收來(lái)自客戶(hù)端的用戶(hù)注冊(cè)請(qǐng)求,并解析請(qǐng)求參數(shù);然后對(duì)用戶(hù)輸入的信息進(jìn)行服務(wù)器端驗(yàn)證和校驗(yàn),包括用戶(hù)名是否已經(jīng)存在、密碼復(fù)雜度是否夠高等;如果數(shù)據(jù)驗(yàn)證通過(guò),則將用戶(hù)注冊(cè)信息保存到數(shù)據(jù)庫(kù)中,并返回注冊(cè)成功響應(yīng)給客戶(hù)端。客戶(hù)端:根據(jù)服務(wù)器的響應(yīng)結(jié)果,在注冊(cè)頁(yè)面上顯示注冊(cè)成功或失敗。需要注意的是,為了保證用戶(hù)數(shù)據(jù)的安全和隱私,用戶(hù)注冊(cè)信息應(yīng)該使用加密技術(shù)進(jìn)行傳輸和存儲(chǔ),還可以采用驗(yàn)證碼、第三方登錄、手機(jī)號(hào)碼綁定等方式增強(qiáng)用戶(hù)注冊(cè)的安全性。課堂討論如果不考慮安全性,是否可以不使用服務(wù)器端,僅僅在客戶(hù)端實(shí)現(xiàn)APP的注冊(cè)功能?三、任務(wù)實(shí)施實(shí)施設(shè)備部署了AndroidStudio、MySQL、Node-RED開(kāi)發(fā)環(huán)境的計(jì)算機(jī)。實(shí)施過(guò)程1.APP設(shè)計(jì)(1)btn12按鈕的單擊事件監(jiān)聽(tīng)。btn12按鈕在第一個(gè)頁(yè)面的布局如圖4-88所示。在第一個(gè)頁(yè)面的活動(dòng)文件MainActivity.java編寫(xiě)btn12按鈕的事件監(jiān)聽(tīng)方法,如圖4-89所示。圖4-88btn12的布局圖4-89btn12按鈕的事件監(jiān)聽(tīng)三、任務(wù)實(shí)施(2)實(shí)現(xiàn)對(duì)話(huà)框功能。定義兩個(gè)變量:privateStringuserNameReg;privateStringpassWordReg;對(duì)話(huà)框代碼:以上代碼會(huì)調(diào)出2個(gè)輸入框。點(diǎn)擊“確定”按鈕,將輸入框的內(nèi)容取出,分別賦值給變量userName和passWord。接下來(lái)以post的方式、HTTP請(qǐng)求提交給后臺(tái)。publicvoidonClick(Viewview){//容器layout:線(xiàn)性布局,包括2個(gè)輸入框LinearLayoutlayout=newLinearLayout(MainActivity.this);layout.setOrientation(LinearLayout.VERTICAL);finalEditTextet1=newEditText(MainActivity.this);et1.setText("用戶(hù)名:");layout.addView(et1);finalEditTextet2=newEditText(MainActivity.this);et2.setText("密碼:");layout.addView(et2);//對(duì)話(huà)框:由Title、2個(gè)輸入框、確定按鈕、取消按鈕組成AlertDialogalertDialog=newAlertDialog.Builder(MainActivity.this).setTitle("請(qǐng)輸入用戶(hù)名和密碼")//標(biāo)題.setView(layout)//輸入框et1和et2.setPositiveButton("確定",newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialogInterface,inti){userNameReg=et1.getText().toString();passWordReg=et2.getText().toString();}}).setNegativeButton("取消",null).show();}三、任務(wù)實(shí)施(3)提交HTPP請(qǐng)求與接收響應(yīng)。添加OkHttp框架、網(wǎng)絡(luò)權(quán)限配置等,在之前的項(xiàng)目中已經(jīng)完成。創(chuàng)建HTTP客戶(hù)端對(duì)象,如圖4-90所示。編寫(xiě)一個(gè)異步請(qǐng)求函數(shù),在對(duì)話(huà)框確定按鈕中調(diào)用執(zhí)行。所謂的異步請(qǐng)求,就是把請(qǐng)求加入enqueue(隊(duì)列)中,等待執(zhí)行。將在異步請(qǐng)求函數(shù)中用POST方法。圖4-90創(chuàng)建HTTP客戶(hù)端對(duì)象//異步請(qǐng)求函數(shù)privatevoidRegPost_es(){//創(chuàng)建表單FormBodyformBody=newFormBody.Builder().add("username",userNameReg).add("password",passWordReg).build();三、任務(wù)實(shí)施//表單數(shù)據(jù)放在request中,通過(guò)post方法提交Requestrequest=newRequest.Builder().url("11:1880/APP_register").post(formBody).build();//將客戶(hù)端加入隊(duì)列中,會(huì)自動(dòng)在子線(xiàn)程中運(yùn)行,返回有2種情況:失敗或者有響應(yīng)okHttpClient.newCall(request).enqueue(newCallback(){@OverridepublicvoidonFailure(@NonNullCallcall,@NonNullIOExceptione){e.printStackTrace();}@OverridepublicvoidonResponse(@NonNullCallcall,@NonNullResponseresponse)throwsIOException{//獲取響應(yīng)的數(shù)據(jù)部分Stringresult=response.body().string();//根據(jù)response,在主線(xiàn)程中Toast出來(lái)runOnUiThread(newRunnable(){@Overridepublicvoidrun(){if(result.equals("SuccessRegistration")){Toast.makeText(MainActivity.this,"恭喜,注冊(cè)成功!",Toast.LENGTH_SHORT).show();}elseif(result.equals("UsernameExists")){Toast.makeText(MainActivity.this,"用戶(hù)名已存在,請(qǐng)重新注冊(cè)!",Toast.LENGTH_SHORT).show();}else{Toast.makeText(MainActivity.this,"未知錯(cuò)誤!",Toast.LENGTH_SHORT).show();}}});}});}三、任務(wù)實(shí)施另外,調(diào)用函數(shù)RegPost_es,如圖4-91所示。其中,11為Node-RED所部署的電腦在局域網(wǎng)中的IP地址。查詢(xún)IP地址的方法為cmd命令行,輸入:ipconfig。如果沒(méi)有收到response,打印異常信息;如果收到response,根據(jù)情況,Toast出注冊(cè)成功或失敗的信息。至此,APP設(shè)計(jì)就完成了,接下來(lái)設(shè)計(jì)數(shù)據(jù)庫(kù)以及Node-RED的流程。圖4-91調(diào)用函數(shù)RegPost_es三、任務(wù)實(shí)施2.數(shù)據(jù)庫(kù)設(shè)計(jì)登錄MySQL,如圖4-92所示,在數(shù)據(jù)庫(kù)node_red_test中創(chuàng)建數(shù)據(jù)表user,共3個(gè)字段:id、username、password。如圖4-93所示,將id設(shè)為主鍵,保存。記錄為0條,如圖4-94所示。圖4-92創(chuàng)建數(shù)據(jù)表user圖4-94查詢(xún)數(shù)據(jù)記錄圖4-93創(chuàng)建主鍵索引三、任務(wù)實(shí)施3.Node-RED設(shè)計(jì)(1)流程_查詢(xún)用戶(hù)。如圖4-95所示設(shè)計(jì)流程,由4個(gè)節(jié)點(diǎn)組成,分別是httpin(Web服務(wù)器)、function1(獲取表單數(shù)據(jù))、function2(編寫(xiě)SQL查詢(xún)語(yǔ)句)、mysql(數(shù)據(jù)庫(kù))。為了調(diào)試,另外添加3個(gè)debug節(jié)點(diǎn)。圖4-95查詢(xún)用戶(hù)流程圖4-96編輯httpin節(jié)點(diǎn)配置httpin節(jié)點(diǎn),如圖4-96所示。三、任務(wù)實(shí)施獲取表單數(shù)據(jù)節(jié)點(diǎn)配置,如圖4-97所示。如圖4-98所示,編輯SQL語(yǔ)句節(jié)點(diǎn),語(yǔ)句:select*from

"user"where"username"="admin"。mysql節(jié)點(diǎn)的配置如圖4-99所示。圖4-98編輯SQL語(yǔ)句節(jié)點(diǎn)圖4-99編輯mysql節(jié)點(diǎn)圖4-97編輯function節(jié)點(diǎn)三、任務(wù)實(shí)施部署流程3,手機(jī)運(yùn)行APP,如圖4-100所示。點(diǎn)擊APP的注冊(cè)按鈕,在對(duì)話(huà)框中輸入用戶(hù)名和密碼,點(diǎn)擊確定。Node-RED打印調(diào)試信息,效果如圖4-101所示。可見(jiàn),我們能夠成功根據(jù)提交的用戶(hù)名查詢(xún)數(shù)據(jù)庫(kù),但數(shù)據(jù)庫(kù)返回結(jié)果為空。這是因?yàn)閿?shù)據(jù)表user的數(shù)據(jù)就是空的。圖4-100APP提交用戶(hù)名和密碼圖4-101Node-RED打印調(diào)試信息三、任務(wù)實(shí)施如果前面查詢(xún)不到記錄,則可在數(shù)據(jù)庫(kù)中增加一條記錄(insert),即注冊(cè)功能。流程如圖4-102所示。在上個(gè)流程的基礎(chǔ)上,根據(jù)數(shù)據(jù)庫(kù)查詢(xún)結(jié)果判斷是否已存在用戶(hù)名:若已存在,則向APP的HTTP客戶(hù)端回復(fù)“UsernameExists”;若不存在,則編寫(xiě)增加SQL語(yǔ)句,連接數(shù)據(jù)庫(kù)執(zhí)行insert操作,并向APP的HTTP客戶(hù)端回復(fù)“SuccessRegistration”。如圖4-103所示,在“獲取用戶(hù)名和密碼”函數(shù)節(jié)點(diǎn),增加2個(gè)在flow內(nèi)使用的全局變量,后邊的“insertuser”的節(jié)點(diǎn)要用到。圖4-102注冊(cè)用戶(hù)流程圖4-103編輯function節(jié)點(diǎn)三、任務(wù)實(shí)施switch節(jié)點(diǎn)判斷查詢(xún)結(jié)果里id字段的值是否為空,即數(shù)據(jù)表中是否有同名字段,如圖4-104所示。如圖4-105所示,在change節(jié)點(diǎn)編輯response內(nèi)容,送給httpresponse節(jié)點(diǎn)(response內(nèi)容將發(fā)還請(qǐng)求客戶(hù)端),告知用戶(hù)名已存在。圖4-104編輯switch節(jié)點(diǎn)圖4-105編輯change節(jié)點(diǎn)三、任務(wù)實(shí)施如圖4-106所示,“insertuser”函數(shù)節(jié)點(diǎn)會(huì)獲取全局變量“username”和“password”的值,用在SQL語(yǔ)句的編寫(xiě)過(guò)程中。如圖4-107所示,告知APP的HTTP客戶(hù)端注冊(cè)成功。圖4-106編輯insertuser節(jié)點(diǎn)圖4-107編輯成功回復(fù)的change節(jié)點(diǎn)三、任務(wù)實(shí)施4.結(jié)果測(cè)試部署流程。根據(jù)APP提交的用戶(hù)名和數(shù)據(jù)表中存在的用戶(hù)名匹配情況,可能用戶(hù)注冊(cè)成功,也可能注冊(cè)失敗。(1)注冊(cè)成功的情況。如圖4-108所示,在APP的注冊(cè)按鈕調(diào)出的對(duì)話(huà)框中輸入用戶(hù)名和密碼,Toast“恭喜,注冊(cè)成功”。如果原來(lái)數(shù)據(jù)庫(kù)不存在,就會(huì)添加進(jìn)去。圖4-108APP注冊(cè)成功三、任務(wù)實(shí)施如圖4-109所示,數(shù)據(jù)庫(kù)增加了一條記錄。(2)注冊(cè)失敗的情況。如果已存在同一個(gè)用戶(hù)名,則會(huì)提示注冊(cè)不成功,如圖4-110所示。圖4-110注冊(cè)失敗的情況圖4-109數(shù)據(jù)庫(kù)增加了一條記錄四、任務(wù)小結(jié)與練習(xí)任務(wù)小結(jié)任務(wù)6實(shí)現(xiàn)了APP中用戶(hù)注冊(cè)功能,包括APP、數(shù)據(jù)庫(kù)和Node-RED的設(shè)計(jì)。用戶(hù)能否注冊(cè)成功的關(guān)鍵是提交的用戶(hù)名和數(shù)據(jù)表中的用戶(hù)名是否匹配??梢宰?cè)若干個(gè)用戶(hù)名,如果APP顯示注冊(cè)成功的話(huà),在數(shù)據(jù)庫(kù)中查看數(shù)據(jù)表的記錄,結(jié)果提交到課程學(xué)習(xí)平臺(tái)。實(shí)踐練習(xí)謝謝聆聽(tīng)2相關(guān)知識(shí)34任務(wù)小結(jié)與練習(xí)1任務(wù)實(shí)施任務(wù)引入與目標(biāo)APP的用戶(hù)登錄功能一、任務(wù)引入與目標(biāo)任務(wù)引入任務(wù)6實(shí)現(xiàn)了APP的用戶(hù)注冊(cè)功能,接下來(lái)是APP的用戶(hù)登錄功能。用戶(hù)能否注冊(cè)成功的關(guān)鍵是提交的用戶(hù)名和數(shù)據(jù)表中的用戶(hù)名是否匹配。那么用戶(hù)能否登錄成功的關(guān)鍵又是匹配什么呢?很顯然,既要用戶(hù)名匹配,也要密碼匹配,具體在Node-RED中通過(guò)流程實(shí)現(xiàn)判斷。任務(wù)目標(biāo)任務(wù)7將實(shí)現(xiàn)以下目標(biāo):在APP中點(diǎn)擊btn11按鈕時(shí),彈出自定義對(duì)話(huà)框;在對(duì)話(huà)框中輸入要登錄的用戶(hù)名和密碼,通過(guò)HTTP客戶(hù)端向Web服務(wù)器發(fā)送POST方式的請(qǐng)求;Web服務(wù)器接收到請(qǐng)求后,查詢(xún)用戶(hù)表中是否已存在用戶(hù)名以及密碼是否相符,并發(fā)回response;如果用戶(hù)名和密碼均匹配,則發(fā)回登錄成功的response;APP的HTTP客戶(hù)端收到HTTPresponse后,根據(jù)response的內(nèi)容,決定是否跳轉(zhuǎn)到APP第二頁(yè),或者Toast提示信息。二、相關(guān)知識(shí)Android工程中變量的作用域在Android工程中,變量的作用域是指變量在程序中可以被訪(fǎng)問(wèn)的范圍。變量的作用域由它在代碼中聲明的位置和使用的修飾符等決定。以下是一些常見(jiàn)的變量作用域:(1)局部變量是在方法內(nèi)部或代碼塊中定義的變量,只能在該方法或代碼塊中使用。局部變量可以根據(jù)需要進(jìn)行初始化,包括基本數(shù)據(jù)類(lèi)型和對(duì)象引用類(lèi)型。(2)成員變量是在類(lèi)中定義的變量,可以被類(lèi)中的所有方法和代碼塊訪(fǎng)問(wèn)。成員變量分為實(shí)例變量和靜態(tài)變量?jī)煞N類(lèi)型。實(shí)例變量只有在創(chuàng)建類(lèi)的實(shí)例后才能訪(fǎng)問(wèn),而靜態(tài)變量可以在類(lèi)被加載時(shí)就被訪(fǎng)問(wèn)。(3)參數(shù)變量是作為方法的參數(shù)傳遞進(jìn)來(lái)的變量,可以在方法內(nèi)部使用。參數(shù)變量的作用域與局部變量相同,只能在方法內(nèi)部訪(fǎng)問(wèn)。需要注意的是,變量的作用域和生命周期不同,變量作用域結(jié)束并不意味著它的生命周期也結(jié)束。例如,一個(gè)對(duì)象引用類(lèi)型的變量,在方法結(jié)束后其作用域結(jié)束,但是其引用的對(duì)象可能仍然存在于內(nèi)存中,直到垃圾回收器將其清除。二、相關(guān)知識(shí)Android中的Toast在Android開(kāi)發(fā)中,Toast是一個(gè)簡(jiǎn)單的提示框架,用于在屏幕上顯示短暫的消息。Toast可以用于提示用戶(hù)某個(gè)操作已成功完成、某個(gè)錯(cuò)誤已發(fā)生或其他一些需要向用戶(hù)展示信息的場(chǎng)景。以下是使用Toast的一般步驟:調(diào)用靜態(tài)方法makeText()來(lái)創(chuàng)建Toast對(duì)象,并傳入Context、提示文本和Toast顯示時(shí)間等參數(shù);調(diào)用show()方法將Toast顯示在屏幕上;當(dāng)Toast顯示時(shí)間結(jié)束后,Toast會(huì)自動(dòng)消失。例如,下面的代碼演示了如何在Android應(yīng)用程序中使用Toast://定義一個(gè)Context變量Contextcontext=getApplicationContext();//創(chuàng)建和顯示ToastCharSequencetext="HelloToast!";intduration=Toast.LENGTH_SHORT;Toasttoast=Toast.makeText(context,text,duration);toast.show();在這個(gè)例子中,我們首先獲取了一個(gè)ApplicationContext對(duì)象;然后創(chuàng)建了一個(gè)Toast對(duì)象,并設(shè)置Toast提示文本為“HelloToast!”,Toast顯示時(shí)間為SHORT(即2秒鐘);最后,調(diào)用show()方法,在屏幕上顯示Toast。三、任務(wù)實(shí)施實(shí)施設(shè)備部署了AndroidStudio、MySQL、Node-RED開(kāi)發(fā)環(huán)境的計(jì)算機(jī)。實(shí)施過(guò)程1.APP設(shè)計(jì)(1)btn11按鈕的單擊事件監(jiān)聽(tīng)。btn11按鈕在第一個(gè)頁(yè)面的布局如圖4-111所示。圖4-111btn11的布局三、任務(wù)實(shí)施在第一個(gè)頁(yè)面的活動(dòng)文件MainActivity.java中編寫(xiě)btn11按鈕的事件監(jiān)聽(tīng)方法,如圖4-112所示。項(xiàng)目2的任務(wù)6實(shí)現(xiàn)過(guò)btn11的單擊功能,單擊btn11后APP直接跳轉(zhuǎn)到page2。本任務(wù)需要完善btn11的單擊功能,實(shí)現(xiàn)點(diǎn)擊btn11后訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),用戶(hù)名和密碼驗(yàn)證無(wú)誤后APP跳轉(zhuǎn)到page2。另外,登錄功能的很多代碼與注冊(cè)功能類(lèi)似,可以拷貝后修改。圖4-112btn11按鈕的事件監(jiān)聽(tīng)三、任務(wù)實(shí)施對(duì)話(huà)框代碼:程序的功能:點(diǎn)擊btn11后,會(huì)跳出2個(gè)輸入框和1個(gè)“確定”按鈕;取出輸入框的內(nèi)容賦值給變量userNameLog和passWordLog;點(diǎn)擊“確定”按鈕后,將userNameLog和passWordLog作為參數(shù),以post的方式提交HTTP請(qǐng)求到Node-RED中的HTTP服務(wù)端。binding1.btn11.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewview){//容器layout:線(xiàn)性布局,包括2個(gè)輸入框LinearLayoutlayout=newLinearLayout(MainActivity.this);layout.setOrientation(LinearLayout.VERTICAL);finalEditTextet3=newEditText(MainActivity.this);et3.setText("用戶(hù)名:");layout.addView(et3);finalEditTextet4=newEditText(MainActivity.this);et4.setText("密碼:");layout.addView(et4);//對(duì)話(huà)框:由Title、2個(gè)輸入框、確定按鈕、取消按鈕組成AlertDialogalertDialog=newAlertDialog.Builder(MainActivity.this).setTitle("請(qǐng)輸入用戶(hù)名和密碼")//標(biāo)題.setView(layout)//輸入框et3和et4.setPositiveButton("確定",newDialogInterface.OnClickListener

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論