《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 其他 > 業(yè)界動(dòng)態(tài) > Java異常處理技術(shù)及EJB中的應(yīng)用

Java異常處理技術(shù)及EJB中的應(yīng)用

2009-02-25
作者:郭廣軍,羊四清,戴經(jīng)國(guó),賀文華

1 引言
傳統(tǒng)的基于函數(shù)返回錯(cuò)誤代碼的錯(cuò)誤處理方法存在明顯的不足,如程序邏輯復(fù)雜,結(jié)構(gòu)不清;可靠性差,維護(hù)不便;返回信息有限,不直觀需譯碼;返回代碼標(biāo)準(zhǔn)化困難,代碼復(fù)用率低;在面向?qū)ο蟮膽?yīng)用系統(tǒng)中,有些如構(gòu)造方法等沒有返回值而無(wú)法報(bào)告程序錯(cuò)誤。因此,在Java中新的錯(cuò)誤檢測(cè)和報(bào)告方法—異常處理機(jī)制應(yīng)運(yùn)而生。
異常是指中斷程序正常執(zhí)行流程的錯(cuò)誤事件,如程序打開不存在的文件、裝載不存在的類、網(wǎng)絡(luò)連接中斷、被零除、訪問數(shù)組越界、系統(tǒng)資源耗盡等。在Java中,異常[1](Exception,例外)是特殊的運(yùn)行錯(cuò)誤對(duì)象,是異常類的一個(gè)對(duì)象,而每個(gè)異常類代表一種運(yùn)行錯(cuò)誤,在異常類中封裝了該運(yùn)行錯(cuò)誤的信息和處理錯(cuò)誤的方法等內(nèi)容。Java異常處理機(jī)制的基本思想是由發(fā)現(xiàn)而不能處理錯(cuò)誤的方法引發(fā)一個(gè)異常對(duì)象,然后由該方法的直接或間接調(diào)用者捕獲并處理這個(gè)錯(cuò)誤。其優(yōu)越性有:在catch中傳播與捕獲錯(cuò)誤信息,實(shí)現(xiàn)了錯(cuò)誤代碼與業(yè)務(wù)邏輯的分離,結(jié)構(gòu)清晰;可對(duì)錯(cuò)誤類型分組并標(biāo)準(zhǔn)化;方便了對(duì)錯(cuò)誤的定位與維護(hù);能有效防止由于異常而導(dǎo)致程序運(yùn)行崩潰,可靠性高;強(qiáng)制程序員考慮程序的容錯(cuò)性、健壯性和安全性。

2? Java異常處理機(jī)制
2.1? 異常類
2.1.1? 系統(tǒng)定義的異常類
異常類用于處理異常,分為系統(tǒng)定義的異常類和用戶自定義的異常類[1]。在java.lang包中提供的Throwable類是異常類層次結(jié)構(gòu)的頂層類,Error類和Exception類是從Throwable類直接派生的兩個(gè)知名子類
Exception類:它代表了Java語(yǔ)言中異常的基本屬性,除Java預(yù)定義的由Exception類派生的諸多異常類外,還支持用戶擴(kuò)展Exception類來(lái)實(shí)現(xiàn)自定義異常類。其構(gòu)造函數(shù)主要有public Exception()和public Exception(String s)等;它從Throwable類繼承了若干方法,常用的有:public String toString()方法,用來(lái)返回異常類信息;public void printStackTrace()方法,默認(rèn)在當(dāng)前標(biāo)準(zhǔn)輸出設(shè)備上輸出當(dāng)前異常對(duì)象的堆棧使用軌跡。Exception類定義的是非致命性錯(cuò)誤,允許用戶編寫代碼來(lái)處理這類錯(cuò)誤,并繼續(xù)程序的執(zhí)行。通常觸發(fā)異常(Exception)的原因有打開的文件不存在;網(wǎng)絡(luò)連接中斷;操作數(shù)超過允許范圍;想要加載的類文件不存在;試圖通過空的引用型變量訪問對(duì)象;數(shù)組下標(biāo)越界等。
Error類:它定義的錯(cuò)誤是致命性錯(cuò)誤,如虛擬機(jī)錯(cuò)誤、裝載錯(cuò)誤、動(dòng)態(tài)連接錯(cuò)誤,一般會(huì)導(dǎo)致程序停止執(zhí)行,通常是由于Java系統(tǒng)或執(zhí)行環(huán)境發(fā)生錯(cuò)誤(Error)而導(dǎo)致的。由于這類異常主要與硬件、運(yùn)行時(shí)系統(tǒng)有關(guān),而不是由用戶程序本身拋出的,因此用戶程序不對(duì)這類異常進(jìn)行處理。
需指出,除java.lang包中定義的異常處理之外,其他的Java包中也包括異常。實(shí)際上幾乎每個(gè)Java包都定義了相應(yīng)的異常類。此外,運(yùn)行時(shí)異常RuntimeException類及其派生子類是Java程序員不用處理的異常。Java創(chuàng)建者認(rèn)為運(yùn)行時(shí)異常不應(yīng)由程序來(lái)處理,而且程序也很難真正的對(duì)付運(yùn)行時(shí)異常。
2.1.2? 用戶自定義異常類
用戶自定義異常類是指擴(kuò)展Exception類或其他某個(gè)已經(jīng)存在的系統(tǒng)異常類或其他用戶異常類而形成新的異常類。可以給新的異常類定義新的屬性和方法,或重載父類的屬性和方法,并使這些屬性和方法能夠體現(xiàn)該類所對(duì)應(yīng)的錯(cuò)誤信息。要特別注意的是:第一? 一個(gè)方法被覆蓋時(shí),覆蓋的方法必須扔出與被覆蓋方法相同的異?;蚱洚惓n惖淖宇悾坏诙? 若父類拋出多個(gè)異常,則覆蓋方法只能拋出父類所拋出的異常的一個(gè)子集,或者說(shuō)不能拋出新的異常。
2.2? 基本機(jī)制與語(yǔ)法結(jié)構(gòu)
2.2.1? 基本機(jī)制
Java異常處理機(jī)制采用中斷模式[2],即引發(fā)并拋出異常后,中止正在執(zhí)行的程序塊,控制流轉(zhuǎn)至異常處理器,待完成異常處理后,再返回調(diào)用點(diǎn)繼續(xù)執(zhí)行。異常處理的基本算法是:
Step1:拋出異常,即創(chuàng)建一個(gè)異常對(duì)象并將它交給運(yùn)行時(shí)系統(tǒng)的過程;
Step2:捕獲異常,即找到異常處理程序的過程:運(yùn)行時(shí)系統(tǒng)從發(fā)生錯(cuò)誤的方法開始回溯,在方法調(diào)用堆棧里向后搜索,直到找到能處理當(dāng)前發(fā)生的異常的處理程序的方法;
Step3:處理異常,即通過方法調(diào)用來(lái)實(shí)現(xiàn)對(duì)異常的處理;
Step4:終止異常處理。若運(yùn)行時(shí)系統(tǒng)在方法調(diào)用棧中遍歷了所有的方法而未找到合適的異常處理程序,則顯示缺省錯(cuò)誤并終止執(zhí)行運(yùn)行時(shí)系統(tǒng)的異常處理。
2.2.2? 語(yǔ)法結(jié)構(gòu)
Java異常處理機(jī)制通過throws、throw、try、catch和finally 5個(gè)關(guān)鍵詞來(lái)實(shí)現(xiàn),分為三個(gè)基本部分[3]。
·throws:此關(guān)鍵字統(tǒng)一定制并明確標(biāo)明了一個(gè)方法可能拋出的各種異常,這些異常是該方法定義的一部分。其實(shí)質(zhì)是允許將異常處理遞歸交給調(diào)用它的上一級(jí)方法去處理,此時(shí)Java編譯器會(huì)強(qiáng)制此方法的調(diào)用者必須將其放在調(diào)用方法的try、catch塊中以拋出并捕獲處理這些異常。
·throw:此語(yǔ)句用來(lái)拋出緊跟其后的一個(gè)異常對(duì)象給此方法的調(diào)用者,此異常對(duì)象可用new創(chuàng)建,或者是一個(gè)Throwable的實(shí)例句柄通過參數(shù)傳到catch中。因?yàn)橛脩糇远x的異常不能由系統(tǒng)自動(dòng)拋出,所以必須借助于throw語(yǔ)句來(lái)拋出各種錯(cuò)誤情況所對(duì)應(yīng)的異常,且要求在程序中的合適位置定義好用戶自定義的異常類。
·try-catch-finally:此語(yǔ)句是Java錯(cuò)誤處理的基本結(jié)構(gòu),主要用來(lái)捕獲和處理一個(gè)或多個(gè)異常。通常由try、catch、finally三個(gè)塊組成。?。﹖ry塊:將所有可能拋出異常的代碼部分放入try塊中;ⅱ)catch塊:用緊跟在try塊后面一個(gè)或多個(gè)catch子句來(lái)捕獲異常,其的目標(biāo)是處理異常,把變量設(shè)到合理的狀態(tài),并象沒有出錯(cuò)一樣繼續(xù)運(yùn)行。若一個(gè)子程序不處理這個(gè)異常,則可返回到上一級(jí)處理,如此不斷的遞歸向上直到最外一級(jí)。ⅲ)finally塊:finally是Java異常處理機(jī)制的精髓,使用finally可以維護(hù)對(duì)象的內(nèi)部狀態(tài)、清理非內(nèi)存資源、將系統(tǒng)恢復(fù)到應(yīng)該處于的狀態(tài)。若沒有finally,要實(shí)現(xiàn)其功能的代碼是很費(fèi)解的。finally塊是可選塊,若定義了finally塊,則不論try塊中有無(wú)異常產(chǎn)生,finally塊都會(huì)被執(zhí)行;甚至若在try或catch塊中執(zhí)行了return、break語(yǔ)句,finally塊也會(huì)被執(zhí)行,但要特別注意此時(shí)finally塊后面的語(yǔ)句并不會(huì)被執(zhí)行。只有在try或catch中執(zhí)行了System.exit(0)操作,才不會(huì)執(zhí)行finally塊。另要特別指出的是:捕獲異常時(shí),catch語(yǔ)句是按其位置由前至后依次對(duì)被拋出的異常對(duì)象進(jìn)行匹配捕獲,若有多個(gè)catch語(yǔ)句,則異常類要按從子類到父類的順序放置;在應(yīng)用技巧中,還可通過在try塊中由throw拋出“異?!保缓笤赾atch塊中捕獲之,實(shí)現(xiàn)程序中業(yè)務(wù)邏輯控制流程的跳轉(zhuǎn)。
2.3? 異常處理的基本原則
對(duì)于非運(yùn)行時(shí)異常必須捕獲或聲明,而對(duì)運(yùn)行時(shí)異常則不必,可以交給Java運(yùn)行時(shí)系統(tǒng)來(lái)處理;對(duì)于自定義的異常類,通常把它作為Exception類的子類,且類名常以Exception結(jié)尾,不要把自定義的異常類作為RuntimeException類或Error的類的子類;在捕獲或聲明異常時(shí),要選取合適類型的異常類,注意異常類的層次,根據(jù)不同的情況使用一般或特殊的異常類;根據(jù)具體的情況選擇在何處處理異常,或者在方法內(nèi)捕獲并處理,或者用throws子句把它交給調(diào)用棧中上層的方法去處理;在catch語(yǔ)句中盡可能指定具體的異常類型,必要時(shí)使用多個(gè)catch;使用finally語(yǔ)句為異常處理提供統(tǒng)一的出口;若無(wú)法處理某個(gè)異常,則不捕獲它;若捕獲了一個(gè)異常,則要對(duì)它進(jìn)行適當(dāng)?shù)奶幚恚槐M量在靠近異常被拋出的地方捕獲異常;除非要向上層遞歸拋出異常,否則要在捕獲異常的地方將其記錄到日志中。

3? EJB中的異常處理
3.1? EJB異常處理

EJB(Enterprise JavaBean)是J2EE企業(yè)級(jí)應(yīng)用開發(fā)的核心組件,EJB的分布式和事務(wù)屬性使得其異常處理成為一個(gè)更重要的問題[4]。EJB中異常可分為三類[5]:?。㎎VM異常:由JVM拋出,是一種致命錯(cuò)誤。ⅱ)系統(tǒng)異常:一般由JVM以RuntimeException的子類拋出,是一種非受查異常。ⅲ)應(yīng)用程序異常:它是一種定制異常,由應(yīng)用程序或第三方類庫(kù)以Exception類或其子類拋出,是一種受查異常,通常由EJB方法的調(diào)用者來(lái)處理之。EJB容器攔截了EJB組件上的每一個(gè)方法調(diào)用,因此方法調(diào)用中發(fā)生的每一個(gè)異常也被EJB容器所攔截。EJB規(guī)范只處理應(yīng)用程序異常和系統(tǒng)異常這兩種類型的異常。
應(yīng)用程序異常:是指在遠(yuǎn)程接口的方法說(shuō)明中所聲明的異常,它不是遠(yuǎn)程異常RemoteException,也不應(yīng)繼承RuntimeException或其子類。但是,在遠(yuǎn)程接口方法的throws子句中聲明的非受查異常并不會(huì)被當(dāng)作應(yīng)用程序異常。應(yīng)用程序異常是業(yè)務(wù)工作流中的例外,當(dāng)這種類型的異常被拋出時(shí),客戶機(jī)可得到一個(gè)恢復(fù)選項(xiàng)。當(dāng)發(fā)生應(yīng)用程序異常時(shí),默認(rèn)情況下EJB容器不會(huì)自動(dòng)回滾事務(wù),只有被顯式說(shuō)明并通過調(diào)用關(guān)聯(lián)的EJBContext對(duì)象的setRollbackOnly()方法才能回滾事務(wù)。實(shí)際上,對(duì)于應(yīng)用程序異常EJB容器通常以它原本的狀態(tài)傳送給客戶機(jī)而不會(huì)以任何方式包裝或修改它。
系統(tǒng)異常:通常被定義為非受查異常,EJB方法不能從這種異常中恢復(fù)。當(dāng)EJB容器攔截到非受查異常時(shí),會(huì)自動(dòng)回滾事務(wù)并執(zhí)行必要的清理工作,然后把該非受查異常包裝到RemoteException類或其子類中并拋給客戶機(jī)。對(duì)于受查異常,若要使用EJB容器的內(nèi)務(wù)處理,則必須將受查異常作為非受查異常拋出。因此,每當(dāng)觸發(fā)受查系統(tǒng)異常時(shí),應(yīng)該對(duì)其原始的異常以javax.ejb.EJBException類或其子類方式包裝后拋出。由于EJBException本身是非受查異常,因此不需要在方法的throws子句中聲明它。EJB容器會(huì)自動(dòng)捕獲EJBException或其子類,并把它包裝到RemoteException中,然后拋給客戶機(jī)。
需指出,雖然EJB規(guī)范規(guī)定系統(tǒng)異常由應(yīng)用程序服務(wù)器記錄,但記錄格式會(huì)因應(yīng)用程序服務(wù)器的不同而異。為確保異常記錄格式的統(tǒng)一,方便對(duì)其進(jìn)行統(tǒng)計(jì)分析,在代碼中記錄異常是一種好的策略。此外,在EJB1.0規(guī)范中要求把受查系統(tǒng)異常以RemoteException拋出,而EJB 1.1及以上規(guī)范則規(guī)定EJB實(shí)現(xiàn)類絕不應(yīng)拋出RemoteException。
3.2? 關(guān)鍵技術(shù)
3.2.1? 日志機(jī)制

盡管用System.out.println()方法跟蹤異常方便,但開銷大,對(duì)I/O處理的同步控制將大大降低系統(tǒng)吞吐量。缺省時(shí)堆棧跟蹤被輸出至控制臺(tái),但在實(shí)際的應(yīng)用系統(tǒng)中,通過瀏覽控制臺(tái)來(lái)查看異常跟蹤不太現(xiàn)實(shí)。因此,在大型應(yīng)用系統(tǒng)的開發(fā)、測(cè)試和運(yùn)行等生命周期中,采用日志機(jī)制和恰當(dāng)?shù)木幋a策略,精確地記錄各種類型的異常,可以降低系統(tǒng)開銷,提高軟件性能和質(zhì)量。知名的日志實(shí)用程序有兩種:Log4J[6]是Apache的Jakarta的一個(gè)開放源代碼的項(xiàng)目,J2SE 1.4捆綁提供了日志處理包(java.util.logging)[7],它們的使用方法請(qǐng)參考相關(guān)文獻(xiàn)。
3.2.2? Decorators設(shè)計(jì)模式
在面向?qū)ο蟮某绦蛟O(shè)計(jì)中若用一個(gè)對(duì)象(the Decorators)包裝另外一個(gè)對(duì)象,被稱為Decorators設(shè)計(jì)模式。基于Decorators設(shè)計(jì)模式,通過包裝原始的異常消息并在EJB組件中將其重新拋出,以方便對(duì)該異常的查詢和訪問。其次,由于Log4J只能記錄String消息,所以要利用Decorators設(shè)計(jì)模式定義一個(gè)專門類負(fù)責(zé)把堆棧跟蹤轉(zhuǎn)換成String,以獲取該堆棧跟蹤的String表示。
3.3? EJB異常處理策略
3.3.1? 常見EJB異常處理的不足
·拋出帶有出錯(cuò)消息的異常:此種方法存在異常內(nèi)容可能被“吞掉”的現(xiàn)象。
·記錄到控制臺(tái)并拋出一個(gè)異常:僅當(dāng)控制臺(tái)可用時(shí)調(diào)用者才能向后跟蹤。
·包裝原始的異常以保護(hù)其內(nèi)容:可能導(dǎo)致重復(fù)記錄,產(chǎn)品日志或控制臺(tái)不能被交叉引用。
3.3.2? EJB異常處理的優(yōu)化策略
·優(yōu)化應(yīng)用程序異常處理:由EJB開發(fā)者顯式拋出,通常包裝了含義清楚消息,不必將其記錄到EJB層或客戶機(jī)層,而以一種直觀有意義的方式提供給最終用戶,并帶上其解決方案的途徑。
實(shí)體Bean一般是啞類,通常應(yīng)用程序異常主要來(lái)源于會(huì)話Bean。從實(shí)體Bean拋出的應(yīng)用程序異常類型通常是CreateException、FinderException、RemoveException及它們的子類。當(dāng)引用其它EJB遠(yuǎn)程接口時(shí),實(shí)體Bean會(huì)遇到RemoteException,在查找其它EJB組件時(shí)會(huì)遇到NamingException,若使用BMP實(shí)體Bean,則會(huì)碰到SQLException。與這些類似的受查系統(tǒng)異常應(yīng)該被捕獲,并被包裝起來(lái),作為EJBException或它的一個(gè)子類拋出。在優(yōu)化的EJB設(shè)計(jì)中,客戶機(jī)一般不直接調(diào)用實(shí)體Bean上的方法,而通過會(huì)話Bean間接訪問實(shí)體Bean。若會(huì)話Bean調(diào)用相同的實(shí)體Bean方法,則要避免對(duì)異常的重復(fù)記錄。會(huì)話Bean和實(shí)體Bean處理系統(tǒng)異常的方式基本相似。可采用訪問標(biāo)識(shí)技術(shù)避免對(duì)同一異常的重復(fù)記錄。
·優(yōu)化系統(tǒng)異常處理:比應(yīng)用程序異常處理更為復(fù)雜,它的發(fā)生不受EJB開發(fā)者的控制且異常信息不直觀,需要對(duì)其原始異常進(jìn)行包裝,以清楚地表達(dá)系統(tǒng)異常的含義。
·優(yōu)化Web層設(shè)計(jì):通常把異常記錄到Web層本身,則易于實(shí)現(xiàn)且代碼簡(jiǎn)潔。這要求Web層必須是EJB層的唯一客戶機(jī),且Web層必須建立在業(yè)務(wù)委派(Business Delegate)、FrontController或攔截過濾器(Intercepting Filter)等模式和Struts或其它類似于MVC的框架基礎(chǔ)上。
實(shí)際應(yīng)用中,即使采用良好的異常處理策略,但由于編譯器和運(yùn)行時(shí)優(yōu)化,會(huì)限制使用堆棧跟蹤程序跟蹤異常的能力。通常把大的方法調(diào)用分割為更小的、更易于管理的塊,并提高代碼復(fù)用率;并將異常類型按需要?jiǎng)澐殖杉?xì)粒度的、具體的異常,在捕獲異常時(shí)則捕獲已規(guī)定好的具體類型的異常,避免捕獲所有類型的異常。

3.4? EJB異常處理實(shí)例
例1:ejbCreate()方法中的FinderException異常處理。其代碼如下:
public Object ejbCreate(RatepayingOrderValue value) throws CreateException {
try { if (value.getItemName() == null) {
throw new CreateException("不能創(chuàng)建報(bào)稅單!"); }
String taxpId = value.getTaxpayerId();
Taxpayer taxp = taxpayerHome.fingByPrimaryKey(taxpId);
this.taxpayer = taxp;
} catch (FinderException fe) {
//作為應(yīng)用程序異常,還是系統(tǒng)異常?
} catch (RemoteException re) {
//這是系統(tǒng)異常,并記錄在日志中。
throw ExceptionLogUtil.createLoggableEJBException(re);
}
return null;
}
例1中報(bào)稅單RatepayingOrder實(shí)體Bean的ejbCreate()方法試圖獲取納稅人Taxpayer實(shí)體Bean的一個(gè)遠(yuǎn)程引用,可能導(dǎo)致FinderException。此處,盡管可把FinderException當(dāng)作應(yīng)用程序異常或作系統(tǒng)異常,但是若把它當(dāng)系統(tǒng)異常則更好,因?yàn)檫@可以提高EJB組件對(duì)客戶機(jī)的透明性。同理,對(duì)于會(huì)話Bean或者實(shí)體Bean試圖創(chuàng)建另一個(gè)會(huì)話Bean,可能導(dǎo)致的CreateException,或者會(huì)話Bean在它的某個(gè)容器回調(diào)方法中獲得了一個(gè)FinderException等,都最好將其作為系統(tǒng)異常。此外,若考慮會(huì)話Bean在處理下報(bào)稅單時(shí),用戶須具有一個(gè)簡(jiǎn)歷,若沒有,則會(huì)話Bean將觸發(fā)ObjectNotFoundException異常,這時(shí)最好將其作為應(yīng)用程序異常拋出,以告知用戶其簡(jiǎn)歷丟失。
例2:logon()方法的InvalidUserDataException應(yīng)用程序異常處理。其代碼如下:
public void logon(String user, String password) throws InvalidUserDataException
{?if (user == null || password ==null)
??throw new InvalidUserDataException();
?serviceImpl.logon(user, password);
}
以下是應(yīng)用程序異常類InvalidUserDataException的定義。
public class InvalidUserDataException extends Exception
{? public InvalidUserDataException()
?{super(“用戶名或密碼不能為空!”); }
}

4? 結(jié)論
在企業(yè)級(jí)的大型軟件開發(fā)中,嚴(yán)謹(jǐn)強(qiáng)大的Java異常處理機(jī)制為軟件質(zhì)量控制提供了有力的技術(shù)支持,提高了軟件的可讀性、可維護(hù)性、容錯(cuò)性和開發(fā)效率。充分有效的利用Java異常處理機(jī)制、采用合適的異常處理策略,是提高EJB中異常處理的性能的有效途徑。

參考文獻(xiàn):
[1]? Bruce Eckel. Thinking in Java[M].Beijing: China Machine Press,2000.240-281.
[2]? 趙化冰,唐英,唐文彬,蘆東昕. Java異常處理[J]. 計(jì)算機(jī)應(yīng)用, 2003,12:46-48.
[3]? 張聰品,趙琛,糜宏斌. 異常處理機(jī)制研究[J].計(jì)算機(jī)應(yīng)用研究,2005,4:86-89.
[4]? [美]Chuck Cavaness Brian Keeton著,智慧東方工作室 譯. EJB 2.0企業(yè)級(jí)應(yīng)用程序開發(fā)[M].北京:機(jī)械工業(yè)出版社,2002,3.294-310.
[5]? EJB異常處理的最佳做法. http://www.evget.com/view/article/viewArticle.asp?article=548
[6]? Log4J框架. http://jakarta.apache.org/log4j/docs/index.html
[7]? Java Logging API. http://java.sun.com/j2se/1.4/docs/api/java/util/logging/
package-summary.html

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無(wú)法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請(qǐng)及時(shí)通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。