本發(fā)明涉及一種面向BS架構(gòu)的數(shù)據(jù)接口生成方法。
背景技術(shù):
對(duì)于大多數(shù)網(wǎng)站而言,網(wǎng)站沒有配置參數(shù)和查看參數(shù)的API使得開發(fā)者如果要更改或查詢服務(wù)器的配置或參數(shù)必須先進(jìn)行登錄,然后點(diǎn)擊多個(gè)頁面完成參數(shù)配置。而開發(fā)者大部分的時(shí)間都花在了參數(shù)配置和查看信息上,這樣的效率顯然是低下的。如果有API的話,開發(fā)者可以通過調(diào)用API獲取或是修改服務(wù)器相關(guān)配置信息。但是大部分網(wǎng)站提供很少或是沒有提供相對(duì)應(yīng)的API,而且讓開發(fā)者自己封裝API也是十分困難的,因?yàn)檫@需要開發(fā)者對(duì)網(wǎng)站結(jié)構(gòu),后臺(tái)發(fā)送的HTTP請(qǐng)求等信息有所了解,同時(shí)開發(fā)者也不應(yīng)該在與開發(fā)無關(guān)的工作上面花費(fèi)多余的時(shí)間。然而在封裝API的過程中可能會(huì)碰到以下困難:
對(duì)HTTP數(shù)據(jù)請(qǐng)求的處理:1、對(duì)于網(wǎng)站操作而言,我們能獲取到的信息只有HTTP請(qǐng)求包,然而我們應(yīng)該從這些請(qǐng)求中提取出哪些有用的信息,以及這些信息之間的有什么樣的聯(lián)系等等,這些問題都給后續(xù)工作帶來一定的困難。
2、網(wǎng)站的狀態(tài)性維持:對(duì)于實(shí)現(xiàn)一個(gè)操作而言,我們需要連續(xù)發(fā)送一系列的HTTP請(qǐng)求,而請(qǐng)求之間是有順序關(guān)系并且如果缺少某一個(gè)請(qǐng)求可能操作就沒有辦法實(shí)現(xiàn)。這就涉及到請(qǐng)求之間狀態(tài)的轉(zhuǎn)化,所以如何維持網(wǎng)頁的狀態(tài)也是研究中所面臨的挑戰(zhàn)。
所以我們需要有一套能自適應(yīng)封裝API的系統(tǒng)來簡(jiǎn)化開發(fā)者日常的管理工作,免去開發(fā)者自己封裝API的繁瑣。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明的目的在于提供一種面向BS架構(gòu)的數(shù)據(jù)接口生成方法,通過該方法,用戶只需要上傳數(shù)據(jù)集,填寫所需API信息,便可自動(dòng)封裝出特定API。
為實(shí)現(xiàn)上述目的,本發(fā)明的技術(shù)方案是:一種面向BS架構(gòu)的數(shù)據(jù)接口生成方法,包括如下步驟,
S1、源數(shù)據(jù)處理:從用戶上傳的HTTP請(qǐng)求集合中提取出關(guān)鍵信息,建立HTTP請(qǐng)求模型,并對(duì)集合進(jìn)行分類;
S2、模型到圖的轉(zhuǎn)化:根據(jù)HTTP請(qǐng)求模型,定義有向圖的節(jié)點(diǎn)和邊的含義,并對(duì)圖進(jìn)行優(yōu)化;
S3、API封裝:根據(jù)有向圖中信息,形成請(qǐng)求路徑,按照不同功能生成對(duì)應(yīng)API。
在本發(fā)明一實(shí)施例中,所述步驟S1中,所述HTTP請(qǐng)求模型為Request請(qǐng)求模型,該Request請(qǐng)求模型包括請(qǐng)求目的地址、請(qǐng)求源地址、請(qǐng)求類型、請(qǐng)求方法、請(qǐng)求頭部、請(qǐng)求參數(shù)、返回頁面。
在本發(fā)明一實(shí)施例中,所述步驟S2具體實(shí)現(xiàn)如下,
首先,定義有向圖的節(jié)點(diǎn)Node在形式上相當(dāng)于一個(gè)頁面,該節(jié)點(diǎn)包括頁面地址url和頁面內(nèi)容content;有向圖的邊Edge表示一個(gè)節(jié)點(diǎn)可達(dá)另一個(gè)節(jié)點(diǎn);
其次,根據(jù)Request請(qǐng)求模型,映射出有向圖的節(jié)點(diǎn)集合和有向圖的邊集合,進(jìn)而獲得有向圖G:
G=<Nodes,Egdes>
其中,Nodes表示有向圖的節(jié)點(diǎn)集合,Node∈Nodes,Edges表示有向圖的邊集合,Edge∈Edges;
最后,采用路徑優(yōu)化、相似節(jié)點(diǎn)優(yōu)化方式對(duì)有向圖進(jìn)行優(yōu)化。
在本發(fā)明一實(shí)施例中,所述路徑優(yōu)化,即將有向圖轉(zhuǎn)換為樹的形式,
對(duì)于每一個(gè)樹的節(jié)點(diǎn)Tnode∈Tnodes ,Tnodes 表示樹的節(jié)點(diǎn)集合:Tnode=<nodeType,url,childs,content>;
其中,nodeType表示樹節(jié)點(diǎn)Tnode的節(jié)點(diǎn)類型,url等價(jià)于有向圖G中 Node.url,childs 表示子節(jié)點(diǎn)集合,content等價(jià)于有向圖G中Node.content;
對(duì)于樹的邊集合TEdges∈有向圖的邊集合Edges。
在本發(fā)明一實(shí)施例中,所述相似節(jié)點(diǎn)優(yōu)化,具體實(shí)現(xiàn)如下,
通過遍歷樹中所有節(jié)點(diǎn),通過比較每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)DOM樹結(jié)構(gòu)來判斷該節(jié)點(diǎn)是否存在相似子節(jié)點(diǎn),若存在將相似節(jié)點(diǎn)合并成新節(jié)點(diǎn);并在樹的節(jié)點(diǎn)集合TNodes 中加入屬性ProSame用于表示該樹的節(jié)點(diǎn)Tnode下相似節(jié)點(diǎn)集合,取出相似節(jié)點(diǎn)的最長(zhǎng)前綴作為默認(rèn)值,將前綴后的內(nèi)容作為新的參數(shù)需要用戶輸入;其中,DOM樹結(jié)構(gòu)是通過對(duì)node.content中的xml文檔轉(zhuǎn)化而來。
相較于現(xiàn)有技術(shù),本發(fā)明具有以下有益效果:
本發(fā)明提出一種自動(dòng)化封裝網(wǎng)站API的方法,簡(jiǎn)化用戶日常復(fù)雜繁瑣的操作,用戶無需對(duì)網(wǎng)絡(luò)請(qǐng)求報(bào)文或是API等知識(shí)有相關(guān)了解。用戶只需要填入所需要的參數(shù)信息,設(shè)置API名稱,系統(tǒng)便可以封裝出對(duì)于API,在以后的操作中無需重復(fù)的步驟,便可以直接調(diào)用該API。
附圖說明
圖1為本發(fā)明方法概覽圖。
圖2為未優(yōu)化的有向圖路徑。
圖3相似節(jié)點(diǎn)圖。
圖4為優(yōu)化后的有向圖路徑。
具體實(shí)施方式
下面結(jié)合附圖,對(duì)本發(fā)明的技術(shù)方案進(jìn)行具體說明。
如圖1-4所示,本發(fā)明的一種面向BS架構(gòu)的數(shù)據(jù)接口生成方法,包括如下步驟,
S1、源數(shù)據(jù)處理:從用戶上傳的HTTP請(qǐng)求集合中提取出關(guān)鍵信息,建立HTTP請(qǐng)求模型,并對(duì)集合進(jìn)行分類;
S2、模型到圖的轉(zhuǎn)化:根據(jù)HTTP請(qǐng)求模型,定義有向圖的節(jié)點(diǎn)和邊的含義,并對(duì)圖進(jìn)行優(yōu)化;
S3、API封裝:根據(jù)有向圖中信息,形成請(qǐng)求路徑,按照不同功能生成對(duì)應(yīng)API。
所述步驟S1中,所述HTTP請(qǐng)求模型為Request請(qǐng)求模型,該Request請(qǐng)求模型包括請(qǐng)求目的地址、請(qǐng)求源地址、請(qǐng)求類型、請(qǐng)求方法、請(qǐng)求頭部、請(qǐng)求參數(shù)、返回頁面。
所述步驟S2具體實(shí)現(xiàn)如下,
首先,定義有向圖的節(jié)點(diǎn)Node在形式上相當(dāng)于一個(gè)頁面,該節(jié)點(diǎn)包括頁面地址url和頁面內(nèi)容content;有向圖的邊Edge表示一個(gè)節(jié)點(diǎn)可達(dá)另一個(gè)節(jié)點(diǎn);
其次,根據(jù)Request請(qǐng)求模型,映射出有向圖的節(jié)點(diǎn)集合和有向圖的邊集合,進(jìn)而獲得有向圖G:
G=<Nodes,Egdes>
其中,Nodes表示有向圖的節(jié)點(diǎn)集合,Node∈Nodes,Edges表示有向圖的邊集合,Edge∈Edges;
最后,采用路徑優(yōu)化、相似節(jié)點(diǎn)優(yōu)化方式對(duì)有向圖進(jìn)行優(yōu)化。
所述路徑優(yōu)化,即將有向圖轉(zhuǎn)換為樹的形式,
對(duì)于每一個(gè)樹的節(jié)點(diǎn)Tnode∈Tnodes ,Tnodes 表示樹的節(jié)點(diǎn)集合:Tnode=<nodeType,url,childs,content>;
其中,nodeType表示樹節(jié)點(diǎn)Tnode的節(jié)點(diǎn)類型,url等價(jià)于有向圖G中 Node.url,childs 表示子節(jié)點(diǎn)集合,content等價(jià)于有向圖G中Node.content;
對(duì)于樹的邊集合TEdges∈有向圖的邊集合Edges。
所述相似節(jié)點(diǎn)優(yōu)化,具體實(shí)現(xiàn)如下,
通過遍歷樹中所有節(jié)點(diǎn),通過比較每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)DOM樹結(jié)構(gòu)來判斷該節(jié)點(diǎn)是否存在相似子節(jié)點(diǎn),若存在將相似節(jié)點(diǎn)合并成新節(jié)點(diǎn);并在樹的節(jié)點(diǎn)集合TNodes 中加入屬性ProSame用于表示該樹的節(jié)點(diǎn)Tnode下相似節(jié)點(diǎn)集合,取出相似節(jié)點(diǎn)的最長(zhǎng)前綴作為默認(rèn)值,將前綴后的內(nèi)容作為新的參數(shù)需要用戶輸入;其中,DOM樹結(jié)構(gòu)是通過對(duì)Node.content中的xml文檔轉(zhuǎn)化而來。
以下為本發(fā)明的具體實(shí)現(xiàn)過程。
如圖1所示,本發(fā)明的面向BS架構(gòu)的數(shù)據(jù)接口生成方法由三個(gè)部分組成:源數(shù)據(jù)處理,模型到圖的轉(zhuǎn)化,API封裝。其中,源數(shù)據(jù)處理是從用戶上傳的HTTP請(qǐng)求集合中提取出關(guān)鍵信息,建立HTTP請(qǐng)求模型,并對(duì)集合進(jìn)行分類;數(shù)據(jù)到有向圖的轉(zhuǎn)化是為了建立數(shù)據(jù)之間的關(guān)聯(lián),根據(jù)HTTP請(qǐng)求模型,定義有向圖的節(jié)點(diǎn)和邊的含義,并對(duì)圖進(jìn)行優(yōu)化;API封裝是根據(jù)有向圖中信息,形成請(qǐng)求路徑,按照不同功能生成對(duì)應(yīng)API。通過本發(fā)明,用戶只需要上傳數(shù)據(jù)集,填寫所需API信息(包括API名稱,所含參數(shù)),便可自動(dòng)封裝出特定API。
、源數(shù)據(jù)處理
網(wǎng)站使用者在網(wǎng)站內(nèi)進(jìn)行一項(xiàng)操作實(shí)際上是后臺(tái)發(fā)送HTTP請(qǐng)求實(shí)現(xiàn)的。因此在進(jìn)行信息瀏覽或是數(shù)據(jù)處理的過程中會(huì)產(chǎn)生一系列HTTP請(qǐng)求,而這些請(qǐng)求便是我們實(shí)現(xiàn)API封裝所需要的數(shù)據(jù)。但是,數(shù)據(jù)中有很多信息不是我們所需要的。所以,我們需要對(duì)HTTP請(qǐng)求進(jìn)行處理。
首先,我們將請(qǐng)求分成兩類,一類是SET類型,另一類是GET類型。GET類型我們認(rèn)為是用來到達(dá)某個(gè)頁面的路徑的方式,并且GET類型請(qǐng)求會(huì)帶來狀態(tài)的改變,因?yàn)橛脩舻拿恳淮雾撁娴狞c(diǎn)擊是有順序的,到達(dá)某一頁面是通過發(fā)送多次請(qǐng)求并按一定順序?qū)崿F(xiàn)的,而不是直接發(fā)送一個(gè)請(qǐng)求就可以完成的,所以不同的GET類型請(qǐng)求會(huì)帶來狀態(tài)的改變。對(duì)于SET類型請(qǐng)求,我們認(rèn)為是無狀態(tài)的,是為了用于實(shí)現(xiàn)某一操作,例如提交表單和上傳文件。但這并不代表可以在任意頁面直接發(fā)送不屬于該頁面的SET類型請(qǐng)求實(shí)現(xiàn)操作,我們?nèi)孕枰竭_(dá)特定頁面才能發(fā)送特定的SET類型請(qǐng)求。而到達(dá)特定頁面的方式就是通過發(fā)送GET類型請(qǐng)求實(shí)現(xiàn)的。
我們從HTTP請(qǐng)求中提取特定信息,建立Request請(qǐng)求模型。一個(gè)Request模型包括請(qǐng)求目的地址(url),請(qǐng)求源地址(refer),請(qǐng)求類型(type),請(qǐng)求方法(method),請(qǐng)求頭部(headers),請(qǐng)求參數(shù)(parameters),返回頁面(content)。
以下是一個(gè)請(qǐng)求模型:
<Request>
<url>http://tomcat.apache.org/whichversion.html</url>
<refer>http://tomcat.apache.org/</refer>
<type>GET</type>
<method>GET</method>
<headers>
<Host>tomcat.apache.org</Host>
<User-Agent>
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0
</ User-Agent>
<Accept-Language>zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</ Accept-Language>
<Connection>keep</ Connection>
</headers>
<parameters>
<sitesearch>tomcat.apache.org</sitesearch>
<p>java</p>
</parameters>
<content></content>
</Request>
2、數(shù)據(jù)到圖的轉(zhuǎn)化
完成一個(gè)完整的操作需要多個(gè)Request請(qǐng)求配合實(shí)現(xiàn)的,所以我們需要找出Request請(qǐng)求之間的聯(lián)系。有向圖能夠很好的表達(dá)節(jié)點(diǎn)之間的關(guān)系,比如我們可以把從某一頁面到達(dá)另一個(gè)頁面的過程看作是從某一節(jié)點(diǎn)到達(dá)另外一個(gè)節(jié)點(diǎn)的路徑。而具體需要做的操作則是到達(dá)特定頁面時(shí)才可以完成的。所以我們需要從Request請(qǐng)求中提取關(guān)鍵信息,定義節(jié)點(diǎn)和邊的含義,完成從數(shù)據(jù)到有向圖的轉(zhuǎn)化。
節(jié)點(diǎn)的描述:一個(gè)節(jié)點(diǎn)(Node)在形式上相當(dāng)于一個(gè)頁面,但并不代表一個(gè)具體的HTML頁面,一個(gè)Node包含頁面地址(url)和頁面內(nèi)容(content)。url信息表示了該節(jié)點(diǎn)的標(biāo)識(shí)符,用來識(shí)別不同節(jié)點(diǎn)。content表示了該節(jié)點(diǎn)的詳細(xì)內(nèi)容,通常來說,當(dāng)我們需要得到網(wǎng)頁上的數(shù)據(jù)時(shí),我們需要通過訪問該節(jié)點(diǎn)的content來獲取特定的數(shù)據(jù)內(nèi)容。
邊的描述:若一個(gè)節(jié)點(diǎn)可達(dá)另一個(gè)節(jié)點(diǎn),即在某一頁面發(fā)送HTTP請(qǐng)求后跳轉(zhuǎn)到另一個(gè)頁面,則我們說兩節(jié)點(diǎn)間存在一條有向邊(Edge)。一條Edge包含對(duì)應(yīng)request請(qǐng)求的編號(hào)requestID,前驅(qū)節(jié)點(diǎn)的url屬性值(from),To表示后繼節(jié)點(diǎn)的url屬性值。當(dāng)點(diǎn)Node1和點(diǎn)Node2有邊edge相連時(shí),我們可以通過查找edge中requestID所對(duì)應(yīng)的具體請(qǐng)求信息發(fā)送HTTP請(qǐng)求,從而從Node1對(duì)應(yīng)頁面到達(dá)Node2對(duì)應(yīng)頁面。
通過算法1,我們可以從Request集合映射出節(jié)點(diǎn)集合和邊集合,進(jìn)而獲得有向圖G=<Nodes,Egdes> ,如圖2所示。進(jìn)一步說,我們可以通過構(gòu)造出的有向圖得到從某一頁面到達(dá)另一頁面的路徑,如要到達(dá)Node9對(duì)應(yīng)頁面,我們需要依次經(jīng)過如下步驟到達(dá):Node1->Node5->Node6->Node9。為了維持網(wǎng)頁內(nèi)的狀態(tài),當(dāng)我們需要完成某一操作時(shí),需要沿著圖中所給定的路徑,依次發(fā)送有向邊所對(duì)應(yīng)實(shí)際HTTP請(qǐng)求,直到到達(dá)指定頁面,再繼續(xù)完成對(duì)應(yīng)操作。
算法1:節(jié)點(diǎn)和邊集合構(gòu)造
輸入: Request[]←請(qǐng)求集合
輸出: Node[]←節(jié)點(diǎn)集合
Edge[]←邊集合
開始
…
for request in Rrequests[]
If(request.url 不在 Nodes[]集合中)
node=new node(request.url,request.content)
Nodes.add(node)
for request in Request[]
If(edge in Edge[]&&(edge.from=request.referer&&edge.to=request.url)
edge.id=request.requestID
else
edge=new edge(request.requestID,request.referer,request.url)
…
結(jié)束
優(yōu)化:
(1)路徑優(yōu)化:實(shí)際上我們已經(jīng)獲得到達(dá)每個(gè)節(jié)點(diǎn)路徑,但是這并不一定是最高效的路徑。我們需要解決下面兩種問題:(1)兩個(gè)頁面實(shí)際上應(yīng)該只有一種方式到達(dá)(兩點(diǎn)之間理論上應(yīng)該只有一條有向邊相連)。實(shí)際上,在封裝某一API時(shí)我們需要確保到達(dá)某一頁面完成特定功能時(shí)僅存在唯一一條路徑,否則在封裝過程中可能會(huì)出現(xiàn)二義性,給工作帶來一定的麻煩。(2)從某一頁面到達(dá)另一頁面存在更短的路徑。之前的路徑圖是根據(jù)用戶上傳的數(shù)據(jù)請(qǐng)求所構(gòu)造出的,而用戶上傳的數(shù)據(jù)是通過記錄日常操作所得到的,對(duì)于用戶日常的操作往往存在不確定性和隨機(jī)性。例如,頁面A通過頁面B到達(dá)頁面C。而在保持狀態(tài)的情況下可能存在一種方式使得頁面A直接到達(dá)頁面C。對(duì)于這些問題的解決方案,我們采用將圖轉(zhuǎn)成樹的形式。具體做法如下:將主頁面作為樹的根節(jié)點(diǎn),對(duì)于任何操作我們都認(rèn)為是從主頁面開始執(zhí)行的。樹的形式保證了從根節(jié)點(diǎn)到達(dá)子孫節(jié)點(diǎn)存在唯一路徑,而第N層節(jié)點(diǎn)僅能到達(dá)第N+1層節(jié)點(diǎn),而不能訪問其他層次節(jié)點(diǎn)。任意節(jié)點(diǎn)都可以且必須從根節(jié)點(diǎn)為起點(diǎn)到達(dá)為后續(xù)封裝API時(shí)帶來一定的便利。經(jīng)過優(yōu)化以后,我們可以得到從主頁面到達(dá)任意頁面最高效同時(shí)不丟失狀態(tài)信息的路徑,詳細(xì)見算法2。
算法2:路徑優(yōu)化,圖轉(zhuǎn)成樹
輸入: G[][]←有向圖
輸出: 優(yōu)化樹Tree
開始
…
令Count 表示節(jié)點(diǎn)層數(shù)
令P[]表示某節(jié)點(diǎn)所屬層數(shù)
令level[][]表示某一層上的所有節(jié)點(diǎn)
Procedure create(Nodei,count):
for(j=1;j<節(jié)點(diǎn)數(shù);j++):
if G[i][j]==1:
if p[j]==0:
將節(jié)點(diǎn)j加入level[count]
P[j]=count
else P[j]>count
P[j]=count
在Level[P[j]]中刪除Nodej
在Nodej的父節(jié)點(diǎn)中刪除Nodej子節(jié)點(diǎn)
在Level[count]中加入Nodej
將節(jié)點(diǎn)j作為結(jié)點(diǎn)i的子節(jié)點(diǎn)
for nodej in Nodei的子節(jié)點(diǎn)
create(nodej,count+1)
…
結(jié)束
算法2 將節(jié)點(diǎn)按層次劃分,從主頁面能到達(dá)的節(jié)點(diǎn)作為第二層節(jié)點(diǎn),從第N層可達(dá)的節(jié)點(diǎn)屬于第N+1層,若某一結(jié)點(diǎn)屬于層次信息大于待更新層次,或是本身沒有層次信息便更新其層次信息。 對(duì)于每個(gè)樹節(jié)點(diǎn)Tnode∈Tnodes ,Tnode=<nodeType,url,childs,content>
其中nodeType表示 Tnode節(jié)點(diǎn)類型(根節(jié)點(diǎn),葉節(jié)點(diǎn),普通節(jié)點(diǎn))url 等價(jià)于 有向圖G中 node.url,childs 表示 子節(jié)點(diǎn)集合,content 等價(jià)于 有向圖G中 node.content,對(duì)于樹的邊TEdges ∈有向圖的Edges。
2、相似節(jié)點(diǎn):我們稱頁面結(jié)構(gòu)相同,但是頁面展示內(nèi)容不同的一類節(jié)點(diǎn)為相似節(jié)點(diǎn)。我們通過查看node.content來獲得頁面具體信息。而content的信息往往是以xml文檔的形式呈現(xiàn)的,而我們需要查看具體數(shù)據(jù)時(shí)需要將xml文檔轉(zhuǎn)化成對(duì)應(yīng)得DOM樹。而我們稱DOM樹的形態(tài)為頁面結(jié)構(gòu),而DOM樹中結(jié)點(diǎn)的值稱為頁面內(nèi)容。而在實(shí)際操作中,往往存在許多相似節(jié)點(diǎn),例如在上傳GITHUB項(xiàng)目時(shí),我們需要填寫項(xiàng)目詳細(xì)信息(包括項(xiàng)目名稱,項(xiàng)目?jī)?nèi)容等),而在查看具體項(xiàng)目時(shí),這些項(xiàng)目所在的頁面往往頁面結(jié)構(gòu)相同,只是具體展示的信息(項(xiàng)目名稱和內(nèi)容等)不同,如圖3中Project1,2,3所對(duì)應(yīng)的頁面。而對(duì)于這類型的節(jié)點(diǎn),我們沒有必要在樹中全部羅列,因?yàn)檫@些節(jié)點(diǎn)可能會(huì)增加圖的復(fù)雜性,對(duì)于封裝API時(shí)造成大量重復(fù)性的操作。所以我們需要找出樹中多組相似節(jié)點(diǎn),對(duì)它們進(jìn)行合并成新節(jié)點(diǎn),形成帶參數(shù)的GET請(qǐng)求,只需要在訪問時(shí)添加節(jié)點(diǎn)ID參數(shù)來區(qū)分相似節(jié)點(diǎn)中具體的特定節(jié)點(diǎn)。具體做法如下:通過遍歷樹中所有節(jié)點(diǎn),通過比較每個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)DOM樹結(jié)構(gòu)來判斷該節(jié)點(diǎn)是否存在相似子節(jié)點(diǎn),若存在將相似節(jié)點(diǎn)合并成新節(jié)點(diǎn)。在原來樹的定義下 在TNodes 中加入屬性ProSame用于表示該Tnode節(jié)點(diǎn)下相似節(jié)點(diǎn)集合,取出相似節(jié)點(diǎn)的最長(zhǎng)前綴作為默認(rèn)值,將前綴后的內(nèi)容(節(jié)點(diǎn)標(biāo)識(shí)符)作為新的參數(shù)需要用戶輸入。
經(jīng)過構(gòu)造圖和圖優(yōu)化等步驟,我們最終可以得到一個(gè)完整的請(qǐng)求路徑圖,如圖4所示。對(duì)于任意節(jié)點(diǎn),均有一條從根節(jié)點(diǎn)到達(dá)該節(jié)點(diǎn)的唯一路徑,我們可以通過訪問其沿邊所對(duì)應(yīng)的 request請(qǐng)求,發(fā)送相應(yīng)HTTP數(shù)據(jù),從而在實(shí)際上到達(dá)該節(jié)點(diǎn)。而對(duì)于相似節(jié)點(diǎn)的情況,我們也只需要在之前基礎(chǔ)上增加節(jié)點(diǎn)ID的參數(shù)到達(dá)指定節(jié)點(diǎn)。
、API封裝
要實(shí)現(xiàn)API的封裝需要兩個(gè)步驟,第一步到達(dá)特定頁面,第二步則是在指定頁面進(jìn)行相應(yīng)的操作。針對(duì)第一步來說,我們需要按照所構(gòu)造圖的路徑形成相應(yīng)的請(qǐng)求序列,讓用戶填寫請(qǐng)求參數(shù)等信息。而第二步則是在指定頁面完成數(shù)據(jù)獲取或是處理等操作,我們把操作分為兩種一種是數(shù)據(jù)獲取的getAPI,另一種是數(shù)據(jù)處理的setAPI。
對(duì)于getAPI來說,主要是為了獲取網(wǎng)頁上的信息。不同的用戶要獲取同一個(gè)網(wǎng)頁上的信息可能各不相同。為了實(shí)現(xiàn)數(shù)據(jù)的提取,最重要的是對(duì)頁面進(jìn)行解析得到數(shù)據(jù)并記錄其位置。對(duì)于一個(gè)HTML頁面,我們可以轉(zhuǎn)化成DOM樹的結(jié)構(gòu)。而針對(duì)用戶所需的數(shù)據(jù),則屬于DOM樹下某一節(jié)點(diǎn)的屬性值。所以我們可以通過解析DOM樹來獲取不同數(shù)據(jù)的XPATH路徑DataPath。
對(duì)于用戶所訪問的頁面,我們認(rèn)為其頁面結(jié)構(gòu)是不變的,會(huì)更改的只有頁面呈現(xiàn)的數(shù)據(jù)。所以每一次根據(jù)所獲得的頁面解析出的DataPath是相同的。當(dāng)用戶輸入目標(biāo)節(jié)點(diǎn)的URL時(shí),我們查找PathTree 中對(duì)應(yīng)的Node節(jié)點(diǎn),向用戶展示Node.content對(duì)應(yīng)的頁面,根據(jù)用戶選擇自動(dòng)生成DataPath。
對(duì)于setAPI來說,主要是為了進(jìn)行數(shù)據(jù)處理,比如修改密碼或是上傳一個(gè)新項(xiàng)目等。在之前的處理中,我們將請(qǐng)求劃分成set類型和get類型。對(duì)于get類型,我們認(rèn)為是用來生成請(qǐng)求路徑的,而set類型則是用來封裝setAPI的。而在處理setAPI時(shí)存在兩種情況,一種是到達(dá)某頁面,并在此頁面直接進(jìn)行set操作。另一種是發(fā)送連續(xù)多個(gè)set類型請(qǐng)求完成set操作。針對(duì)第一種情況,我們依然可以用getAPI的算法獲得到達(dá)該node的路徑,此時(shí)用戶只需要填寫該post請(qǐng)求發(fā)送的參數(shù),便可以封裝成setAPI。而針對(duì)另一種情況,我們認(rèn)為這樣的set操作實(shí)際上是發(fā)送了一系列的set類型請(qǐng)求所構(gòu)成的。我們只需找出這樣的post序列,將參數(shù)統(tǒng)一填寫好封裝成一個(gè)統(tǒng)一的API,而不是多個(gè)API。
以一個(gè)調(diào)用GET API完整過程為例,用戶只需要輸入API名稱,設(shè)置API參數(shù),選定為GET類型API,同時(shí)設(shè)置所需返回?cái)?shù)據(jù)在原頁面的實(shí)際地址便可自動(dòng)封裝出對(duì)于getAPI。在實(shí)際調(diào)用時(shí)輸入API名稱,以及參數(shù),便可獲得對(duì)于API返回結(jié)果,調(diào)用過程具體如下所示。
以下是服務(wù)器端提供的GET類型API的接口代碼:
@GET
@Path("/GET/{APIname}")
@Produces(MediaType.APPLICATION_JSON)
public String GetData(@PathParam("APIname") String APIname){
resendRequest=new ResendRequest();
String result=resendRequest.getResendRequest(APIname);
return result;
}
以下是處理用戶調(diào)用API請(qǐng)求的代碼:
public String getResendRequest(String APIname){
…
api=apiDao.selectAPI(APIname); //查詢?cè)揂PI的參數(shù)
request=requestDao.selectRequest(api.getRequestID()); //查詢需要重發(fā)的請(qǐng)求
GetMethod getMethod=new GetMethod(request.getURL());
HashMap<String,String> headers=request.getHeader();
for(Entry<String, String> entry : headers.entrySet()){
getMethod.addRequestHeader(entry.getKey(), entry.getValue());//重新構(gòu)建該請(qǐng)求
}
String returnName=api.getReturnDes().get(0);//提取用戶需要返回參數(shù)的位置
String realPosition=api.getReturnParameter().get(0);
try{
client.executeMethod(getMethod); //重新發(fā)送該請(qǐng)求
String html = getMethod.getResponseBodyAsString();
result=returnName+":"+parserHtml.getData(html,api.getReturnParameter().get(0));//返回參數(shù)
}catch(IOException e){
e.printStackTrace();
}
return result;
}
本發(fā)明提出一種自動(dòng)化封裝網(wǎng)站API的方法,簡(jiǎn)化用戶日常復(fù)雜繁瑣的操作,用戶無需對(duì)網(wǎng)絡(luò)請(qǐng)求報(bào)文或是API等知識(shí)有相關(guān)了解。用戶只需要填入所需要的參數(shù)信息,設(shè)置API名稱,系統(tǒng)便可以封裝出對(duì)于API,在以后的操作中無需重復(fù)的步驟,便可以直接調(diào)用該API。
以上是本發(fā)明的較佳實(shí)施例,凡依本發(fā)明技術(shù)方案所作的改變,所產(chǎn)生的功能作用未超出本發(fā)明技術(shù)方案的范圍時(shí),均屬于本發(fā)明的保護(hù)范圍。