版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
浙江大學(xué)碩士學(xué)位論文摘要錯誤!文檔中沒有指定樣式的文字。浙江大學(xué)碩士學(xué)位論文 第4章網(wǎng)上藥物影響查詢網(wǎng)站的實現(xiàn)PAGE6PAGE38網(wǎng)上藥物影響查詢網(wǎng)站的實現(xiàn)web端實現(xiàn)JSF開發(fā)環(huán)境配置首先,引入需要的jar包。由于JSF是建立在Servlet基礎(chǔ)上的,所以在引入jsf的同時還需要引入servlet的jar包。對一個項目來說,它是依賴的jar包非常重要,既不能少,也不能夠版本不正確。早期很多公司都是不得不將其提交到SVN中[17]。Maven是基于項目對象模型(POM,ProjectObjectModel),通過描述信息管理項目構(gòu)建,報告和文檔的軟件項目管理工具[18]。pom.xml配置如圖4.1所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s11pom配置圖FacesServlet在web.xml內(nèi)的配置如圖4.2所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s12FacesServlet在web.xml內(nèi)配置每個JavaEE應(yīng)用服務(wù)器都包含EJB容器和Web容器,使得EJB和Web都可以部在同一個應(yīng)用服務(wù)器上[19]。JSF的托管Bean處于應(yīng)用服務(wù)器的管理之下,因而服務(wù)器可以很容易地將業(yè)務(wù)邏輯組件注入到JSF的托管Bean中[20]。在JSF端需要使用EJB端的service。由于J2EE官方并沒有給出一個標(biāo)準(zhǔn)API,我們通過添加Spring啟動監(jiān)視器,然后在Spring配置文件內(nèi)采用jee:remote-slsb方式遠(yuǎn)程調(diào)用EJB。在此之前需要添加下Spring的支持。Spring在web.xml文件中配置如圖4.3所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s13Spring在web.xml內(nèi)配置spring配置文件如下,<jee:remote-slsbid="drugSearchLogicService"business-interface="com.drug.search.service.DrugSearchLogicService"jndi-name="com.drug.search.service.DrugSearchLogicService"home-interface="com.drug.search.service.DrugSearchLogicService"cache-home="false"refresh-home-on-connect-failure="true"environment-ref="jndiEnv"/>最后,在JSF托管Bean內(nèi)只需添加drugSearchLogicService對象、ManagedProperty("#{drugSearchLogicService}")注釋和其get、set方法就可以得到想要的service了。JSFManagedBean實現(xiàn)ManagedBean在這個項目里面主要分為了六個包:(1)com.memberaccess.validation,主要負(fù)責(zé)驗證頁面輸入內(nèi)容是否正確,如輸入的藥物名、病癥名是否符合長度規(guī)范等。用戶自己編寫的validator類需要實現(xiàn)JSF的Validator接口。同時@FacesValidator注釋需要保證里面的值與web頁面調(diào)用的值一樣,不然就會無法查找到。除此之外還要保證在頁面調(diào)用的唯一標(biāo)示,否則也會報錯。其書寫形式有@FacesValidator("")和@FacesValidator(value="")兩種。如下是一個簡單的validator,@FacesValidator("drugNameValidator")publicclassDrugNameValidatorimplementsValidator{ privatestaticfinalLoggerlog=LoggerFactory.getLogger(DrugNameValidator.class); privatestaticfinalStringDRUG_NAME_REQUIRED="three_chars_least_drug_search"; privatestaticfinalintLIMIT_LENGTH=3; @Override publicvoidvalidate(FacesContextfacesContext,UIComponentcomponent,Objectvalue){ ("validate()invoked"); UIInputinputDrugName=(UIInput)facesContext.getViewRoot().findComponent("drugSearchForm") .findComponent("drugSearchForm:drugEntry"); ("drugName:{}",inputDrugName); StringdrugName=inputDrugName==null?"":((String)inputDrugName.getSubmittedValue()).trim(); ("drugName:{}",drugName); Stringmsg=""; if(isEmpty(drugName)||drugName.length()<LIMIT_LENGTH){ msg=DRUG_NAME_REQUIRED; } log.debug("validateComplete"); }}(2)com.memberaccess.converter,主要負(fù)責(zé)頁面下拉框需要顯示的內(nèi)容、數(shù)字、電話號碼等需要在Object和頁面所顯示的String之間轉(zhuǎn)換的情況。用戶自定義converter需要實現(xiàn)getAsObject和getAsString方法。和validator相同,需要保證其在頁面調(diào)用中是唯一標(biāo)示。如下是一個簡單的converter,@FacesConverter("zipCodeConverter")publicclassZipCodeConverterimplementsConverter{ privatestaticfinalLoggerlog=LoggerFactory .getLogger(ZipCodeConverter.class); privatestaticfinalIntegerINDEX_ZERO=0; privatestaticfinalIntegerINDEX_FIVE=5; privatestaticfinalStringSYMBOL_HYPHEN="-"; privatestaticfinalIntegerLENGTH_CONDITION=5; @Override publicObjectgetAsObject(FacesContextcontext,UIComponentcomponent, Stringstr){ returnnull; } @Override publicStringgetAsString(FacesContextfacescontext, UIComponentuicomponent,Objectobj){ ("getAsString()invoked"); StringfomattedZipCode=""; if(obj!=null){ fomattedZipCode=(String)obj; log.debug("fomattedZipCode:{}",fomattedZipCode); if(fomattedZipCode.length()>LENGTH_CONDITION){ StringBufferbuffer=newStringBuffer(); fomattedZipCode=buffer .append(fomattedZipCode.substring(INDEX_ZERO,INDEX_FIVE)) .append(SYMBOL_HYPHEN) .append(fomattedZipCode.substring(INDEX_FIVE)).toString(); } } log.debug("getAsString()Complete"); returnfomattedZipCode; }}(3)com.memberaccess.userstate.drugsearch,主要用于放ManagedBean包。其和寫在頁面上的頁面邏輯部分一起構(gòu)成了基本所有的頁面邏輯。當(dāng)某個公共ServiceBean被多個ManagedBean調(diào)用的時候,多將其統(tǒng)一存放于CommonBusinessControlMB內(nèi)部,這樣便于注入修改,和java中Fa?ade的思想一致。managedBean多使用@SessionScoped或者是通過@CustomScoped(value="")使用項目內(nèi)部自定義的范圍。除了作用周期標(biāo)簽外,@ManagedBean標(biāo)簽是所有ManagedBean必不可少的。(4)com.memberaccess.util,放置用于存放各個項目都會用到的工具,如項目中用到的XProperties文件讀取工具以及用于JSFComponent的ComponentUtil工具。(5)com.memberaccess.web,用于存放讀取web具體配置屬性相關(guān)的工具類、繼承了JSF的ExceptionHandlerFactory的自定義exception-handler-factory、以及web中用到的切面類等和web密切相關(guān)的類。web端相關(guān)實現(xiàn)類圖以下是web端用到的主要類圖及類間關(guān)系。由于病情搜索和藥物搜索都是通過drugSearchLogicService進(jìn)行搜索的,所以就一同寫在了DrugSearchMB里面。Condition里面裝載了病情的編號,是否有藥物治療或預(yù)防等信息。FdbDrug里面包含了一個藥物的主要id和藥物名稱、劑型、劑量主鍵等信息。MemberAccessExceptionHandler繼承ExceptionHandlerWrapper,在前臺提示用戶由于后臺哪些錯誤,該如何解決等信息。LocalizationFilter類用于解決不同語言切換后語言的properties文件切換問題。web端主要類圖如圖4.4所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s14web端類圖系統(tǒng)展示在用戶輸入賬戶信息通過驗證后,就可進(jìn)入藥物查找頁面。藥物查找可以通過藥物開頭名和癥狀名兩種方式。藥物查詢方式選擇界面如圖4.5所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s15藥物查詢方式選擇頁面通過病癥名和直接通過藥物開頭名查詢在頁面顯示上的區(qū)別并不大,只是通過病癥名查找時是通過一張存儲了用戶經(jīng)常搜索的病癥名對應(yīng)正確病癥名表進(jìn)行搜索,然后在左側(cè)列出正確病癥名列供用戶選擇。選擇后右側(cè)的搜索出該病癥的治療藥物列表。用戶選擇HighCholesterol(高膽固醇)病癥后搜索出的頁面如圖4.6所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s16病癥查詢藥物搜索頁面在將Lipitor藥物前面的多選框勾上后,用戶再搜索vfend藥物并點擊右側(cè)藥物名查看藥物詳細(xì)信息。用戶可以點擊AddDrugtoDrugListto計算藥物服用時間、服用頻率等信息后統(tǒng)計出的費用。藥物詳細(xì)信息頁面提供了藥物的劑型、劑量、藥物圖片、作用、服用方式、副作用、藥物影響、預(yù)警、過量服用后果、錯過服用時的信息、保存以及備注說明等信息。藥物詳細(xì)信息頁面如圖4.7所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s17藥物詳細(xì)信息頁面點擊“AddDrugtoDrugListtoCheckinteractions”鏈接,彈出顯示有已選藥物的彈出層供用戶修改。已選藥物彈出層如圖4.8所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s18已選藥物彈出層點擊CheckInteractions按鈕,跳轉(zhuǎn)到藥物影響信息頁面,提供給用戶藥物和藥物影響、藥物食物反應(yīng)、用藥重復(fù)、藥物和藥物影響嚴(yán)重程度分級信息。藥物影響頁面如圖4.9所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s19藥物影響信息頁面EJB端接口EJB端包劃分在網(wǎng)上安全用藥查詢系統(tǒng)的后臺里面,文件主要分為以下幾種:Entity對象:在本項目內(nèi)是以CMP結(jié)尾的POJO實體文件,只是添加了JPA的annotation。ConverterServiceBean:用于將CMP文件轉(zhuǎn)換為頁面使用的DTO的類。DTO:數(shù)據(jù)傳輸對象(DataTransferObject),用于傳遞給web端頁面顯示使用。EAO:StatelessSessionBean,用于處理數(shù)據(jù)庫的CRUD操作。在本項目內(nèi)以ServiceBean結(jié)尾,基本會在方法返回前調(diào)用ConverterServiceBean將Entity轉(zhuǎn)換為DTO。LogicService:負(fù)責(zé)業(yè)務(wù)邏輯,調(diào)用EAO完成復(fù)雜操作,但在本項目內(nèi)也是StatelessSessionBean,事務(wù)管理則采用CMT方式完成。業(yè)務(wù)邏輯層EJB端搜索病癥和藥物的主要LogicService類圖如圖4.10所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s110EJB端LogicService類圖DrugSearchLogicServiceBean通過再調(diào)用具體的底層Service。數(shù)據(jù)層類圖如圖4.11所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s111EJB端底層藥物查找service類圖DrugCabinetServiceBean會在將藥物加入藥櫥后檢查所選的藥物是否存在藥物和藥物影響、用藥重復(fù)以及藥物食物反應(yīng)。EJB端用于檢測藥物影響的主要類圖如圖4.12所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s112EJB端藥物影響ServiceBean類圖DrugCabinetServiceBean會將檢查到的藥物影響、用藥重復(fù)、藥物食物反應(yīng)等信息放到DrugCabinet中。頁面顯示的藥物影響相關(guān)DTO類圖如圖4.13所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s113EJB端藥物影響DTO類圖業(yè)務(wù)邏輯實現(xiàn)藥物名查找藥物根據(jù)藥物名查找藥物涉及的相關(guān)數(shù)據(jù)庫圖如圖4.14所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s114藥物相關(guān)數(shù)據(jù)庫圖genericmnid是該藥物的仿制藥主鍵。在該藥物有仿制藥時同時給出仿制藥名。performDrugsStartingWithLetterSearch方法將所有相關(guān)信息搜索出來,然后由web端判斷藥物的品牌名是否相同進(jìn)行過濾。performDrugsStartingWithLetterSearch方法內(nèi)namedQuery主要實現(xiàn)代碼如下,selectdistinctdispensable.*,dispensable.descdisplayassearchdesc,route.abbrevasrouteabbrev,doseform.abbrevasdoseformabbrev,doseform.descriptionasdoseformdesc,drugname.descdisplayasdrugname,drugname_1.descdisplayasgenericdrugname,route.descriptionasroutedescFROMdispensabledispensable,routeroute,drugnamedrugname,doseformdoseform,drugnamedrugname_1WHEREdispensable.rtid=route.rtidanddispensable.dfid=doseform.dfidanddispensable.mnid=drugname.mnidanddispensable.genericmnid=drugname_1.mnidand(dispensable.descsearchLIKE:drugNameordispensable.descaltsearchLIKE:drugName)query.setParameter(“drugName”,drugName+“%”);loadDispensableDrugFromId方法查找到dispensable表內(nèi)的描述、藥物品牌名、用法用量、儲存方式、備注等信息。之后,再通過dispensable表內(nèi)的mnid查找dispensable表內(nèi)具有相同mnid的數(shù)據(jù),將里面的劑量強(qiáng)度、劑量強(qiáng)度單位、劑型和圖片信息做為一個map的value,dispensable的主鍵medid則作為map的key。然后將這個map返回給web端。病癥名查找藥物要通過用戶輸入的病癥名查找正確的病癥,首先是到medcondsearchfml這個專門存放了用戶容易搜索的病癥名的表來查找用戶搜索的病癥名。之后,系統(tǒng)再根據(jù)medcondsearchfml表查找medcond表找到對應(yīng)的正確藥物病癥名。findConditionListByConditionName內(nèi)namedQuery代碼主要如下所示,SELECTdistinctmedcond.*,medcondsearchfml.descdisplayASsearchdescription,medcondsearchfml.syntypecodeFROMmedcondmedcond,medcondsearchfmlmedcondsearchfmlWHEREmedcond.dxid=medcondsearchfml.dxidandconditionsearchfml.descsearchlike:conditionNameORDERBYmedcond.dxid,medcondsearchfml.descdisplay,medcondsearchfml.syntypecodequery.setParameter(“conditionName”,”%”+conditionName+“%”);用戶在左側(cè)選擇一個正確的病癥后,系統(tǒng)通過medcond表(病癥)查找到ind表(臨床病癥表,INDM,Indicationclinicalinformation)。臨床病癥表會和dispensable表有一個多對多關(guān)系。dispensable表含有藥物品牌名、劑型、劑量。medid是dispensable表主鍵,而gcnseqno來源于dispensable表對應(yīng)的Dispensablegeneric表(帶有劑型、劑量的學(xué)術(shù)名藥)。一個學(xué)術(shù)名藥對應(yīng)著一個或多個品牌名藥。這些品牌名藥的藥效基本一致。通過病癥查找藥物涉及表如圖4.15所示,圖STYLEREF1\s4.SEQ圖\*ARABIC\s115通過病癥查找藥物涉及表findFdbDrugListByConditionTreat方法內(nèi)的namedQuery代碼主要如下所示,selectind.*,medcond.descriptionashitdesc,dispensable.medidasdrugid,dispensable.descdisplayasdrugdescription1fromindind,inddruglinkinddruglink,medcondmedcond,dispensabledispensablewhereind.indid=inddruglink.indidandind.dxid=medcond.dxidandinddruglink.gcnseqno=dispensable.gcnseqnoandmedcond.dxid=:dxid用戶在選擇好藥物后將藥物添加入藥櫥,將會進(jìn)行藥物影響查詢并跳轉(zhuǎn)到藥物影響展示頁面。藥物影響查詢在檢查是否有藥物和藥物影響時,系統(tǒng)通過web端用戶查看的dispensabledrug,找到該藥所有的rtgenid(具有施藥途徑的藥物表),然后配合之前查找到的rtgenid到ddimdruglink表內(nèi)查找是否有藥物和藥物影響。ddimdruglink表和ddiminteraction表之間為多對一關(guān)系,通過ddiminteraction表的主鍵interactionid關(guān)聯(lián)。ddiminteraction表(藥物和藥物影響表)內(nèi)含有藥物影響的嚴(yán)重分級。查找藥物和藥物間反應(yīng)的namedQuery實現(xiàn)主要代碼如下所示,selectddimlink.rtgenid1,ddimlink.drugid2,ddiminter.*fromddimdruglinkddimlink,ddiminteractionddiminterwhereddimdruglink.rtgenid1in(:rtgenid1,:rtgenid2,:rtgenid3...)andddimdruglink.rtgenid2in(:rtgenid1,:rtgenid2,:rtgenid3...)anderactionid=eractionidquery.setParameter(“rtgenid1”query.setParameter(“rtgenid2”query.setParameter(“rtgenid3”因為namedQuery無法將一個List插入進(jìn)去,或者是將一個帶有”,”的字符串作為參數(shù)傳入,所以上面的namedQuery不得不采用StringBuilder進(jìn)行拼接。本章小結(jié)本章首先對項目實現(xiàn)過程中JSF通過Spring整合EJB作出了詳細(xì)的闡述。然后講述了網(wǎng)上安全用藥查詢系統(tǒng)的web端幾種基本類的實現(xiàn)方法和其類圖結(jié)構(gòu)。EJB端介紹了系統(tǒng)使用的業(yè)務(wù)邏輯層和數(shù)據(jù)層接口。最后給出了功能模塊的具體實現(xiàn)。浙江大學(xué)碩士學(xué)位論文 第5章難點和解決方法難點和解決方法控制創(chuàng)建Entity時生成的sql含有的列插入的數(shù)據(jù)需要使用數(shù)據(jù)庫的字段默認(rèn)值。在保存用戶選擇哪些藥物數(shù)據(jù)時,有些字段采用的數(shù)據(jù)應(yīng)該采用數(shù)據(jù)庫設(shè)置的默認(rèn)值,但是由于數(shù)據(jù)庫和JPA兩方對非null的要求會導(dǎo)致數(shù)據(jù)操作失敗。解決辦法:定義DynamicInsert注解,在Entity中添加EntityListeners:DynamicInsertEntityListener,通過在SQLstatament中移除有DynamicInsert注釋并且其值為null的字段來解決。DynamicInsert代碼如圖5.1所示,圖STYLEREF1\s5.SEQ圖\*ARABIC\s11DynamicInsert代碼圖DynamicInsertEntityListener代碼如圖5.2所示,圖STYLEREF1\s5.SEQ圖\*ARABIC\s12DynamicInsertEntityListener代碼圖最后,只需要在CMP內(nèi)添加DynamicInsertEntityListener并添加DynamicInsert注解就可以在createTs為null時不出現(xiàn)在insert語句里面。具體代碼如圖5.3所示,圖STYLEREF1\s5.SEQ圖\*ARABIC\s13Entity使用DynamicInsert代碼圖編寫namedQuery在返回搜索到的藥物數(shù)量時始終會拋出異常本項目使用eclipseLink的JPA實現(xiàn)。在分頁顯示的時候,需要計算總共有多少藥物符合搜索條件時,但是通過query.getSingleResult()強(qiáng)轉(zhuǎn)成Long類型返回有時會拋出轉(zhuǎn)換異常。在一番debug后,發(fā)現(xiàn)query.getSingleResult()只有在返回值為0的時候才是Integer,其他情況下都是Long。正確寫法如下:Longcount=Long.valueOf(query.getSingleResult().toString());namedQuery在真實環(huán)境下有錯在真實環(huán)境下,點擊藥物名進(jìn)入藥物詳細(xì)信息頁面的時候,會發(fā)生報錯。但是在本地部署的時候并沒有發(fā)現(xiàn)這個問題。究其原因是eclipseLink對JPA的實現(xiàn)在不同版本下有些不同。本地使用的eclipseLink版本允許將Long類型的值以String類型傳入,但是真實環(huán)境使用的eclipseLink版本不允許類型不同的值傳入。解決辦法:setParameter時傳入正確的類型。將eclipseLink切換為2.3.3版本。簡化EJB單元測試在進(jìn)行單元測試的時候經(jīng)常會出現(xiàn)由于數(shù)據(jù)庫測試數(shù)據(jù)被人改掉而導(dǎo)致JUnitTest掛掉。除此之外,數(shù)據(jù)庫在大洋彼岸也導(dǎo)致連接異常緩慢,不適合本地開發(fā)測試。而且在Jenkins上部署時候會自動運行JUnitTest。如果使用真實數(shù)據(jù)庫連接則測試無法通過,如果將JUnitTest注釋掉又會降低代碼測試覆蓋率。所以,迫切地需要將項目中使用真實數(shù)據(jù)庫的地方都切換為內(nèi)存數(shù)據(jù)庫。在使用JPA的EntityManager往內(nèi)存數(shù)據(jù)庫內(nèi)插入使用到的建表和數(shù)據(jù)的sql時,我們通過真實數(shù)據(jù)庫表結(jié)構(gòu)的模仿和插入數(shù)據(jù)主鍵的特殊要求,對表的結(jié)構(gòu)做出了一定的變動,使其變得更加便捷準(zhǔn)確。在本項目內(nèi),所有Test文件都繼承了AbstractDbTestBase。在該abstract文件內(nèi)通過EntityManager建立和內(nèi)存數(shù)據(jù)庫連接的實現(xiàn)代碼如下,staticEntityManagergetInstance(){Propertiesproperties=newProperties();properties.put("javax.persistence.jdbc.driver","org.hsqldb.jdbcDriver");properties.put("javax.persistence.jdbc.user","sa");properties.put("javax.persistence.jdbc.password","");properties.put("javax.persistence.jdbc.url","jdbc:hsqldb:mem:testdb");properties.put(PersistenceUnitProperties.CACHE_SHARED_DEFAULT,"false");properties.put(PersistenceUnitProperties.TARGET_SERVER,"");properties.put(PersistenceUnitProperties.TARGET_DATABASE,"HSQL");properties.put("javax.persistence.jtaDataSource","");properties.put("javax.persistence.transactionType","RESOURCE_LOCAL");EntityManagerFactoryemf=Persistence.createEntityManagerFactory("drug-ejb-test",properties);EntityManagerentityManager=emf.createEntityManager();}drug-ejb-test是test\resources\META-INF\persistence.xml下的persistence-unit名,所以必須保持一致。test所用persistence.xml文件主要修改如下,<persistence-unitname="deductible-ejb-test" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <jta-data-source>jdbc/drugDB</jta-data-source> <class>com.drug.DrugCMP</class> <exclude-unlisted-classes>true</exclude-unlisted-classes></persistence-unit>AbstractDbTestBase讀取執(zhí)行DDL文件部分代碼如下,publicstaticvoidsetupClass(StringtestDateLocation)throwsException{em=getInstance();em.getTransaction().begin();BufferedReaderreader=newBufferedReader(newInputStreamReader(AbstractDbTestBase.class .getResourceAsStream(testDateLocation)));Stringtxt=reader.readLine();while(txt!=null&&!"null".equals(txt)){ try{ if(txt.contains(";")){ em.createNativeQuery(txt).executeUpdate(); txt=reader.readLine(); }else{ txt=txt+reader.readLine(); } }catch(Exceptione){ LOG.debug(e.getMessage()); }}在DDL文件內(nèi),我們也做出了一些優(yōu)化,通過使用GENERATEDBYDEFAULTASIDENTITY(STARTWITH1,INCREMENTBY1),實現(xiàn)既可以使用自增長主鍵,也可以在插入內(nèi)存數(shù)據(jù)庫數(shù)據(jù)時指定主鍵值,從而使得插入的數(shù)據(jù)主鍵值和數(shù)據(jù)庫上的測試數(shù)據(jù)主鍵值一致,便于將數(shù)據(jù)庫上的測試數(shù)據(jù)導(dǎo)入。同時也不用在代碼里面費心地在測試內(nèi)寫死主鍵值。具體代碼實現(xiàn)如下,DROPSCHEMATESTIFEXISTSCASCADE;CREATESCHEMATESTAUTHORIZATIONDBA;CREATETABLETEST.NDC_MSTR_A999(NDCCHAR(8)NOTNULL,NDC_SRC_CDEDECIMAL(9)GENERATEDBYDEFAULTASIDENTITY(STARTWITH1,INCREMENTBY1)NOTNULL,BRND_NMECHAR(8)NOTNULL,DEA_INDRCHAR(8)NOTNULL, DESI_DRG_INDRCHAR(8)NOTNULL,DOS_FRM_CDECHAR(8)NOTNULL,DOS_FRM_DESCNCHAR(8)NOTNULL,DRG_CTGY_CDECHAR(8)NOTNULL,DRG_CLAS_INDRCHAR(8)NOTNULL,DRG_FRM_INDRCHAR(8)NOTNULL,GCNCHAR(8)NOTNULL, ...);ALTERTABLETEST.NDC_MSTR_A999ADDCONSTRAINTNDC_MSTR_PKPRIMARYKEY(NDC,NDC_SRC_CDE);...最后,在實際進(jìn)行Test前只需要將新創(chuàng)建,并且讀取好sql數(shù)據(jù)的EntityManager注入到ServiceBean內(nèi)就可以了。相關(guān)實現(xiàn)代碼如下,@BeforeClasspublicstaticvoidsetUpBeforeClass()throwsException{ LOGGER.debug("setupClass()invoked"); try{ setupClass(TEST_DATA_LOCATION); }catch(Exceptione){ LOGGER.debug("setUperrore:{}",e); } LOGGER.debug("setupClass()completed");}@BeforepublicvoidsetUpBefore()throwsException{ LOGGER.debug("setUpBefore()invoked"); setUpBeforeClass(); drugServiceBean=newDrugServiceBean(); drugServiceBean.setEntityManager(getEm()); LOGGER.debug("setUpBefore()completed");}簡化web在本地部署的依賴由于EJB框架在目前的J2EE框架中,在創(chuàng)建一個具體應(yīng)用的時候會需要管理多個對象實例和浪費許多寶貴的系統(tǒng)資源在EJB系統(tǒng)事務(wù)、安全和生命周期等問題上,占用服務(wù)器CPU和內(nèi)存[21]。如何在本地開發(fā)部署的時候盡量不修改代碼,又實現(xiàn)不需要部署多余的EJB是一個值得研究的問題。為了部署方便,減少啟動時間和減少必須部署的EJB數(shù)目,簡化整個部署測試過程,我們采用mockito來mock部分依賴的service。在pom中添加Mockito代碼如下,<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.8.5</version> <scope>compile</scope></dependency>在Spring文件中添加需要mock的接口,代碼如下,<beanid="customerSetService"class=".zucc.dummy.DummyServiceFactory" factory-method="createCustomerSetService"/>最后,創(chuàng)建DummyServiceFactory類供Spring調(diào)用,代碼如下,publicclassDummyServiceFactory{ publicstaticCustomerSetServicecreateCustomerSetService(){ CustomerSetServicecustomerSetService=Mockito.mock(CustomerSetService.class); CustomerSetcs=newCustomerSetDTO(); cs.setCustomerSetId(1L); cs.setCustomerSetType(null); cs.setMasterCustomerSet(cs); cs.setName("TopMasterCustomerSet"); Mockito.when(customerSetService.getTopMasterCustomerSet()).thenReturn(cs); returncustomerSetService; }}網(wǎng)站語言的切換當(dāng)用戶切換顯示語言是,不僅需要切換JSF使用的resource-bundle,同時還需要重新調(diào)用service搜索與用戶所選語言相符的該頁面內(nèi)容。faces-config.xml主要用于配置網(wǎng)站的靜態(tài)信息,決定了網(wǎng)站的默認(rèn)顯示語言和支持的語言種類。語言配置如下所示,<locale-config> <default-locale>en_US</default-locale> <supported-locale>en_US</supported-locale> <supported-locale>es</supported-locale></locale-config>用戶選擇了顯示語言后,在web.xml中添加filter,控制網(wǎng)頁顯示的語言。web.xml中添加的filter代碼如下,<filter> <filter-name>localizationFilter</filter-name> <filter-class>.zucc.i18n.LocalizationFilter</filter-class></filter>當(dāng)從request中直接讀取到的locale為空時,自動采用上一次存儲在session中的locale信息。如果不為空,則使用LocaleServletRequestWrapper放入FilterChain。LocaleServletRequestWrapper僅僅是繼承了HttpServletRequestWrapper,對其getLocale和getLocales方法進(jìn)行了重寫。LocalizationFilter的實現(xiàn)如下所示,publicstaticfinalStringLOCALE=".zucc.i18n.LocalizationFilter.locale";@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException, ServletException{ if(requestinstanceofHttpServletRequest){ HttpServletRequestreq=(HttpServletRequest)request; StringlocaleForm=request.getParameter("localeForm"); Stringlocale=request.getParameter("localeForm:locale"); HttpSessionsession=((HttpServletRequest)request).getSession(); if(localeForm==null||locale==null){ locale=(String)session.getAttribute(LOCALE); }else{ session.setAttribute(LOCALE,locale); } if(locale==null){ chain.doFilter(request,response); }else{ request=newLocaleServletRequestWrapper(req,locale); chain.doFilter(request,response); } }else{ chain.doFilter(request,response); }}在JSFFaceletes模版文件中,實現(xiàn)了頁面的多語言選擇。在改變語言選項后,頁面自動更新pageContainer區(qū)域。ui:insert定義了用于模板中為使用該模板定義UIComponent的Facelets頁面定義布局。各個詳細(xì)頁面都會用ui:define在Facelets頁中使用模板添加內(nèi)容。模版文件的實現(xiàn)如下所示,<p:panelid="pageContainer"><h:formid="localeForm"> <ui:insertname="content"/> <h:selectOneMenuid="locale"value="#{commonDataManagerMB.locale}"> <f:selectItemsvar="localeObject" itemLabel="#{localeObject.getDisplayLanguage(localeObject)}" itemValue="#{localeObject.language}" value="#{commonDataManagerMB.supportedLocales}"/> <p:ajaxprocess="@this"event="change"update="pageContainer"/> </h:selectOneMenu></h:form><divid="content"> <ui:insertname=”content”/></div></p:panel>到此為止,程序已經(jīng)知道應(yīng)該使用哪種語言,但是還需要加載項目中用到的英文和西班牙文資源文件。首先,在master.xhtml文件內(nèi)添加i18nmsgs的綁定。其中basename為資源文件所在的位置(cn\edu\zucc)與名稱(master)。var為加載后的變量名。JSF會根據(jù)用戶request內(nèi)的配置自動裝載匹配的資源文件:<f:loadBundlebasename=".zucc.master"var="i18nmsgs"/>然后在resource下添加perties和master_perties西班牙語資源文件(master_perties)內(nèi)容形式和英文資源文件格式一樣,只是需要將等于后的資源換為西班牙語的ascii碼。以下是打印本頁在英文資源文件和西班牙資源文件中的表示:print_current_page=PrintThisPageprint_current_page=Imprimirestapagina這樣,JSF就可以從配置文件里面讀取符合當(dāng)前語言選項下的properties信息顯示到頁面上了。至于頁面上一些從數(shù)據(jù)庫里面存儲的信息調(diào)整,則需要在具體實現(xiàn)頁面在刷新的時候自動比對是否和前一次使用的語言選項相同,不同則采用新的語言編號重新搜索信息。本章小結(jié)本章主要介紹了在網(wǎng)上安全用藥查詢系統(tǒng)的項目開發(fā)中對EJB和WEB的開發(fā)中碰到的問題和解決方法以及測試部署上的優(yōu)化,web頁面國際化的實現(xiàn)方法。浙江大學(xué)碩士學(xué)位論文第6章總結(jié)與展望PAGE41總結(jié)與展望總結(jié)本文首先對比中外醫(yī)藥B2C的交易規(guī)模、醫(yī)藥B2C的交易比例、網(wǎng)上藥店的數(shù)量,和近段時間藥店數(shù)量的迅速增長,意識到即將迎來網(wǎng)上藥店的競爭高潮。同時通過對比國內(nèi)外做法發(fā)現(xiàn)了國外的藥物影響提示對中國傳統(tǒng)藥物通報方式不便民和在線購藥咨詢在購藥咨詢?nèi)藬?shù)增大后無法詳盡回復(fù)。本文進(jìn)而提到對藥物搜索和藥物間影響查詢的探索。本文提出了軟件的總體目標(biāo),介紹了軟
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年金昌道路客運輸從業(yè)資格證培訓(xùn)考試資料
- 2024年石家莊客運資格證在線考試
- 2024年淄博客運資格證考試內(nèi)客
- 2024年青海汽車客運從業(yè)資格考試
- 汽車系統(tǒng)動力學(xué)第二章-車輛動力學(xué)建模方法及基礎(chǔ)理論
- 賽項規(guī)程-高職教師組(學(xué)前教育專業(yè)教育技能)
- 青島市第十五屆職業(yè)技能大賽技術(shù)文件-化學(xué)檢驗員(職工組)
- 無人機(jī)在消防滅火救援中的應(yīng)用
- 辦公室彩鋼瓦屋面改造合同
- 設(shè)備缺陷整改合規(guī)管理
- 大班-科學(xué)語言-塑料瓶到哪里去了?-課件
- 《幼兒園教育活動設(shè)計》-07-幼兒園科學(xué)教育與活動指導(dǎo)課件
- PLM項目管理系統(tǒng)教程
- 售樓處裝修工程施工進(jìn)度表7.31
- 腦缺血再灌注損傷與腦復(fù)蘇課件
- GB/T 11345-2023焊縫無損檢測超聲檢測技術(shù)、檢測等級和評定
- 《輕度損傷的自我處理》教學(xué)設(shè)計
- 船舶設(shè)備與管系-船舶系固設(shè)備
- 修樹施工方案
- 多式聯(lián)運完整
- 《政府采購方式》課件
評論
0/150
提交評論