WEB开发网      濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻橀弻锝夊箣閿濆棭妫勯梺鍝勵儎缁舵岸寮诲☉妯锋婵鐗嗘慨娑氱磽娴e搫鈻堢紒鐘崇墵瀵顓奸崼顐n€囬梻浣告啞閹歌顫濋妸鈺佺闁靛繒濮Σ鍫熺箾閸℃ê濮囨い搴㈡崌濮婃椽宕ㄦ繝鍌氼潓閻庢鍠栭悥濂哥嵁閺嶎厼绠涙い鏃傚亾閿涘繘姊洪崨濠冨瘷闁告洦鍋呴悾顒勬⒒娴e摜鏋冩い顐㈩樀瀹曞綊宕稿Δ鈧粻鏍煃閸濆嫬鏆婇柛瀣崌瀹曠兘顢橀悙鎰╁灪閵囧嫰濡烽敂鍓х杽濠殿喖锕ら幖顐f櫏闂佹悶鍎滈埀顒勫磻閹炬緞鏃堝川椤撶媴绱遍梻浣筋潐瀹曟﹢顢氳椤㈠﹪姊绘担鍛婂暈婵炶绠撳畷褰掑箥椤斿彞绗夊┑鐐村灟閸ㄦ椽鎮¢弴鐔翠簻闁规澘澧庣粙鑽ょ磼閳ь剟宕橀埞澶哥盎闁硅壈鎻槐鏇熸櫏婵犳鍠栭敃銊モ枍閿濆洤鍨濇繛鍡楃箚閺嬪酣鏌熼鍡楀暙椤ユ劙姊婚崒娆戭槮闁硅姤绮嶉幈銊╂偨缁嬭法顦┑鐐叉閸旀帞鎹㈤崱娑欑厽闁靛繆鎳氶崷顓犵焼閻庯綆鍋佹禍婊堟煛瀹ュ啫濮€濠㈣锕㈤弻娑㈡倷椤忓嫬顫囧┑顔硷攻濡炶棄螞閸愵煁褰掑Χ閸℃瑢濮囬梺鐟板槻閹虫﹢鐛幘璇茬鐎广儱鎷嬪Λ婊堟⒒閸屾瑧顦︽繝鈧柆宥呯?闁靛牆顦埀顒€鍟村畷鍗炩槈濡厧骞堥梻浣告贡閸庛倝銆冮崱娑欏亗闁哄洢鍨洪悡娑㈡煕閵夛絽鍔氬┑锛勫帶闇夋繝濠傚閻鏌曢崶褍顏紒鐘崇洴閺佹劙宕ㄩ鐘垫綁闂傚倷绀侀幖顐e緞閸ヮ剙鐒垫い鎺嗗亾缁剧虎鍙冨鎶藉幢濞戞瑥鈧敻鏌ㄥ┑鍡涱€楀褌鍗抽弻锟犲幢濞嗗繆鏋呴梺鍝勭潤閸曨偒鍤ゅ┑鐐叉閸ㄧ敻宕哄畝鍕拺闂傚牊绋掗ˉ鐐烘偨椤栨稑娴柨婵堝仜閳规垹鈧綆鍋勬禍妤呮煙閼圭増褰х紒鎻掋偢閹粙鎳¢妶鍥╋紳婵炶揪缍€椤曟牕鈻撻弴銏$厱闁靛ǹ鍎虫禒銏°亜椤愩垻绠崇紒杈ㄥ笒铻i悹鍥ф▕閳ь剚鎸剧槐鎾存媴閸︻厸妲堝銈嗗灥閹冲酣鍩㈤幘娲绘晣闁绘劏鏅滈弬鈧俊鐐€栧褰掑几婵犳艾绀傛い鎺戝€荤壕濂告煟濡寧鐝€规洖鐭傞弻鏇㈠幢閺囩媭妲銈庡亝缁诲牓鐛崶銊﹀闁稿繐顦伴悗鍛婄節閻㈤潧啸闁轰礁鎲¢幈銊╊敇閵忕姷锛涢梺瑙勫礃缁夘喛銇愰幒鎾存珳闂佹悶鍎弬鍌炲焵椤掆偓閿曨亪寮婚敓鐘茬劦妞ゆ帊鑳堕々鐑芥倵閿濆骸浜為柛妯挎閳规垿鍩ラ崱妤冧画濡炪倖鍨堕悷鈺佺暦閻㈢鍋撻敐搴″幋闁稿鎸鹃幉鎾礋椤掆偓娴犫晠姊虹粙鎸庡攭缂侇噣绠栭幃姗€宕橀瑙f嫼缂傚倷鐒﹂埣銈夘敂閸曢潧娈ㄩ梺鍓插亝濞叉牠鎮块鈧弻锝夊箛椤旇姤姣勭紒鐐劤閵堟悂寮诲☉姘勃闁绘劦鍓涘▓銈夋煛娴e摜澧﹂柟顔筋殘閹叉挳宕熼鍌ゆО缂傚倷绶¢崰鏍崲濡寧顥ら梺璇查叄濞佳囧箺濠婂吘娑㈩敍閻愬鍘靛銈嗙墪濡梻绮堟担鍦浄妞ゆ洍鍋撻柟顔筋殔閳绘捇宕归鐣屼邯闂備胶绮悧婊堝储瑜旈幃楣冩倻閼恒儱浜楅柟鐓庣摠钃辨い顐㈢Т閳规垿鍩ラ崱妤冧户闁荤姭鍋撻柨鏇炲€归崐鐢碘偓瑙勬礀濞层劎澹曟禒瀣厱閻忕偛澧介幊鍛存煕閺傝法校闁靛洤瀚版俊鎼佸Ψ閿旂粯顥i梻浣风串缁插墽鎹㈤崼銉у祦闁哄秲鍔嶆刊瀛樻叏濠靛棙婀伴柟韫嵆濮婄粯鎷呴搹鐟扮濠碘槅鍋勯崯纾嬫"闂佽宕橀褍效閺屻儲鍊甸柨婵嗛閺嬬喖鏌i幘璺烘瀾濞e洤锕俊鍫曞磼濮橆偄顥氶梻鍌欒兌缁垶銆冮崨顓囨稑螖閸涱厾鍘洪梺鍦亾缁剁偤寮崼婵嗙獩濡炪倖妫侀~澶屸偓姘偢濮婃椽鎳¢妶鍛呫垺绻涢懠顒€鈻堥柛鈹惧亾濡炪倖甯掗崯顖炴偟椤忓牊鐓熼煫鍥э工娴滈箖姊婚崒姘偓椋庣矆娓氣偓楠炴牠顢曢敃鈧粻鐘绘煙闁箑骞楅柛娆忕箻閺岀喓绱掗姀鐘崇亶闂佺ǹ顑傞弲鐘诲蓟閿濆围閹艰揪绱曟禒婊勭箾鐎涙ḿ鐭婄紓宥咃躬瀵鎮㈤崗鐓庘偓缁樹繆椤栨繂浜归柣锝嗘そ濮婃椽宕崟顒€娅ょ紓浣筋嚙閻楀棝锝炶箛鎾佹椽顢旈崪浣诡棃婵犵數鍋為崹鍫曟嚌妤e啨鈧倿宕崟銊︽杸闂佸疇妫勫Λ妤佺濠靛鐓熼柣鏂垮级濞呭﹪鏌曢崱鏇狀槮闁宠閰i獮鎺楀籍閸屾稒绶梻鍌欑閹碱偊宕锕€纾瑰┑鐘崇閸庡﹪鏌涢鐘插姕闁抽攱鍨堕幈銊╂偡閻楀牊鎮欓梺璇茬箰瀵墎鎹㈠☉娆愬闁告劖褰冮顐c亜閳哄啫鍘撮柡灞诲姂瀵挳鎮欏ù瀣壕鐟滅増甯楅崑鍌炴煛閸ャ儱鐏柣鎾崇箰閳规垿鎮欓懠顑胯檸闂佸憡鏌i崐婵嬪蓟濞戙垹鐓涢悗锝庡墰钃辨俊鐐€戦崝濠囧磿閻㈢ǹ绠栨繛鍡樻尭缁狙囨煙鐎涙ḿ绠ユ繛鍏肩娣囧﹪濡堕崶顬儵鏌涚€n剙浠遍柡浣稿暣婵偓闁靛牆鍟犻崑鎾存媴缁洘鐎婚梺鍦亾濞兼瑥鈻撻幇鐗堚拺闁告劕寮堕幆鍫熴亜閹存繃鍠橀柣娑卞櫍婵偓闁靛牆妫岄幏濠氭⒑缁嬫寧婀伴柣鐕傚缁﹪鎮ч崼娑楃盎濡炪倖鍔戦崺鍕i幖浣圭厽闁挎繂鎳庡Σ濠氭懚閿濆鐓犳繛鏉戭儐濞呭洭鏌i幘鎰佸剰妞ゎ亜鍟存俊鍫曞幢濮楀棙鈷栭梻浣芥硶閸犲棝宕曢懠顒傜焿鐎广儱鐗勬禍褰掓煙閻戞ɑ灏甸柛妯兼暬濮婅櫣绱掑Ο铏逛桓闁藉啴浜堕幃妯跨疀閿濆懎绠归梻鍥ь槹缁绘繃绻濋崒姘缂備礁顦遍崕銈夊箞閵婏妇绡€闁告侗鍣禒鈺冪磽娴d粙鍝洪悽顖涘笩閻忔帡姊洪幆褏绠婚柍褜鍓氱粙鎺椼€佸鈧濠氬磼濞嗘垵濡介柣搴g懗閸忕姴鎼鍏煎緞婵犲嫭鐓f繝鐢靛仦閸ㄥ墎鍒掓惔銏㈩洸闂侇剙绉甸埛鎺懨归敐鍛暈闁哥喓鍋炵换娑氭嫚瑜忛悾鐢碘偓瑙勬礀缂嶅﹪寮婚崱妤婂悑闁告侗鍨伴獮鍫ユ⒒娴d警鏀伴柟娲讳邯濮婁粙宕熼娑樹簵濠电偛妫欓幐濠氭偂閻樺磭绠鹃柡澶嬪焾閸庢劖绻涢崨顓熷櫣闂囧鏌eΟ铏癸紞闁活厼锕弻宥囨喆閸曨偆浼岄梺鎼炲姂缁犳牠骞冨▎鎾村癄濠㈣泛顦崹婵嬫⒒閸屾瑦绁版い鏇熺墵瀹曟澘螖閸涱偀鍋撻崘顔煎窛闁哄鍨归崣鈧┑鐘灱閸╂牠宕濋弴鐘典笉闁规儼濮ら悡娆撴煙椤栧棗鑻▓鍫曟偡濠婂嫭绶叉繛灞傚妿濡叉劙骞樼拠鑼紲濠电偛妫欓崹鑲╃玻濡ゅ懏鈷戦柛婵勫劚鏍¢梺缁橆殘婵炩偓闁靛棔绶氬浠嬵敇閻愯尙鐛╅梻浣告贡閳峰牓宕㈡禒瀣柧闁挎繂顦伴埛鎴犵磼鐎n厽纭剁紒鐘冲▕閺屾稑螣閻樺弶鍣烘い鎰矙閺岋綁骞囬鍓х槇缂備浇顕уΛ娆撳Φ閸曨垰鍐€闁靛ě鍛帓闂佹眹鍩勯崹杈╃矙閹烘梹宕叉繛鎴欏灩瀹告繃銇勯幘璺烘瀻闁哄濮撮埞鎴︻敊绾嘲濮涚紓渚囧櫘閸ㄥ爼鐛箛娑樺窛閻庢稒锚娴狀參姊绘笟鍥у伎缂佺姵鍨甸埢鎾斥攽閸垻锛濋梺绋挎湰閻燂妇绮婇悧鍫涗簻闁哄洤妫楀ú銈囧瑜版帗鐓曟い顓熷灥濞呮﹢鏌涢妶鍡樼缂佽鲸鎸婚幏鍛嫻椤栨粎绐楃紓鍌欒濡狙囧磻閹剧粯鈷掑ù锝堫潐閸嬬娀鏌涙惔顔肩仸鐎规洘绻傞濂稿川椤忓懐鈧椽姊洪幖鐐插姶闁告挻宀搁崺娑㈠箣閻樼數锛滈柣搴秵閸嬪嫰顢氬⿰鍕瘈闁逞屽墴楠炲秹顢欓崜褝绱查梺璇插嚱缂嶅棝宕戦崨顓犳殾鐎光偓閳ь剟鍩€椤掑喚娼愭繛鎻掔箻瀹曡绂掔€n亞鐣烘繛瀵稿Т椤戝懎顔忓┑鍡忔斀闁绘ɑ褰冮鈺傤殽閻愭惌娈滄慨濠冩そ閹兘寮堕幐搴♀偓顖炴⒑娴兼瑧绉靛ù婊庝簻閻i鎲撮崟顓犵槇濠殿喗锕╅崜娑㈠储閹扮増鈷戦柛婵嗗閸屻劑鏌涢妸锔姐仢闁诡噯绻濇俊鐑芥晜閽樺浼庢繝纰樻閸ㄤ即鎮樺┑瀣亗闁规壆澧楅悡鐔兼煙閹规劖纭鹃柡瀣洴閺岋綁骞欓崘銊ゅ枈閻庤娲栭悥鍏间繆閻戣棄唯闁靛鍎涢幋鐘电=闁稿本鐟чˇ锔姐亜閹存繄澧曢柣锝囧厴閹粙宕归顐g稐闂備礁婀遍崕銈咁潖閼姐倕顥氶柛蹇涙?缁诲棙銇勯弽銊х畵濞存粌缍婇弻锝夋晲閸噥浠╃紓浣介哺閹稿骞忛崨瀛樻優闁荤喐澹嗛鑲╃磽閸屾瑦绁版い鏇嗗洦鍋嬮柛鈩冪⊕閸嬧晝鈧懓瀚伴崑濠傖缚閵娾晜鐓冪憸婊堝礈濮橆厾鈹嶅┑鐘插亞濞兼壆鈧厜鍋撳┑鐘插敪閵娧呯=闁稿本鐟︾粊鏉款渻閺夋垶鎲搁柟骞垮灲瀹曠厧鈹戦幇顓犵▉缂傚倸鍊烽悞锕佹懌婵犳鍨伴顓犳閹烘垟妲堟慨妤€妫楅崜鏉库攽閻愯尙澧涢柛鏃€鐟ラ~蹇撁洪鍕啇闂佺粯鍔栬ぐ鍐€栭崱娑欌拺闁告稑饪村▓鏃堟煕閻旈攱鍋ラ柟顕€绠栭幃婊呯驳鐎n偅娅栭梻浣虹帛閸旀ḿ浜稿▎鎰垫闁搞儺鍓氶埛鎴︽煟閻旂厧浜伴柛銈囧枎閳规垿顢氶埀顒€岣胯閸┿垽骞樺ǎ顒€浜濋梺鍛婂姀閺備線骞忛搹鍦=闁稿本鐟ч崝宥夋嫅闁秵鐓冮梺鍨儏濞搭噣鏌$仦鐣屝㈤柣锝忕節楠炲秹顢欑亸鏍у緧闂佽瀛╅鏍闯椤曗偓瀹曟垶绻濋崒婊勬闂佸湱鍎ら〃鍡涘磹閻戣姤鍊甸柣銏㈡瑜版帞宓侀柛顐犲劜閳锋帒霉閿濆洦鍤€闁崇粯娲熼弻鈩冪瑹閸パ勭彎閻庤娲橀崹鍧楃嵁濡偐纾兼俊顖滃帶楠炴劙姊绘担鍛婂暈濞撴碍顨婂畷鏉款潩鐠鸿櫣鐤囬梺鍛婁緱閸犳洜鎹㈤崱娑欑厱婵炲棗娴氬Σ绋库攽椤斿吋鍠橀柟钘夌埣閺佹劖寰勭€n亙鍝楁繝鐢靛仦閸ㄥ墎鏁幒鎾存珷闁哄被鍎查悡娑㈡煕鐏炵虎娈斿ù婊堢畺濮婂宕掑顑藉亾閻戣姤鍤勯柛鎾茬閸ㄦ繃銇勯弽顐粶缂佲偓婢舵劖鐓涢柛銉㈡櫅閳ь剨缍侀幃銏ゅ传閵壯呮闂備焦鎮堕崕婊堝礃閳轰礁濮冮梻鍌氬€烽懗鍓佸垝椤栫偛钃熼柕濞炬櫆閸庡秵绻濋棃娑卞剰缂備讲鏅犻弻銈夊箒閹烘垵濮屾繛瀛樼矋缁捇寮婚敓鐘茬闁靛⿵绠戦ˇ鈺侇渻閵堝啫鍔氭い锔炬暬瀵鈽夐姀鐘愁棟闁荤姴娲︾粊鎾磻閹炬枼鏀介悗锝庝簽椤旀垿姊洪崜鎻掍簼婵炲弶锕㈠畷鎰版倻閼恒儳鍘介梺鐟邦嚟閸嬪秶绱撳鑸电厱婵せ鍋撳ù婊嗘硾椤繐煤椤忓嫪绱堕梺鍛婃处閸撴瑩宕戝澶嬧拺闁告稑锕ラ悡銉╂煛閸偄澧寸€殿喗鐓″畷濂稿即閵婏附娅栭梻浣虹帛閸旀洟顢氶銏犲偍闁告鍋愰弨浠嬫煟閹邦剙绾фい銉︾矌缁辨帞绱掑Ο铏诡儌缂備緡鍠氱划顖滄崲濠靛棭娼╂い鎾跺Т楠炴劙姊虹拠鑼闁稿鍠栧鏌ヮ敃閿濆棙鐝¢梻浣筋嚙濮橈箓锝炴径濞掓椽鏁冮崒姘憋紱婵犵數濮撮崐濠氬汲閿曞倹鐓熼柡鍐ㄥ€甸幏锟犳煛娴e憡顥㈤柡灞界Х椤т線鏌涢幘瀵告噰闁糕斂鍨归鍏煎緞鐎n偅鐝抽梻浣规偠閸庮噣寮插┑瀣櫖婵犻潧娲ㄧ粻楣冨级閸繂鈷旂紒瀣吹閹叉悂寮堕崹顔芥缂備礁鍊哥粔褰掑箖濞嗘搩鏁嗛柛灞剧矌濡插洭姊绘笟鈧ḿ褎顨ヨ箛鏇炵筏闁告挆鍕幑闂佺粯鍔﹂崗娆愮濠婂牊鐓欓悗娑欋缚缁犳牜鈧懓鎲$换鍕閹烘鏁婇柛鎾楀啰顐奸梻渚€娼ч悧鐐电礊娴e摜鏆︽慨妞诲亾闁糕晪绻濆畷姗€濡搁妷褜鍚嬮梻鍌氬€峰ù鍥敋瑜忛埀顒佺▓閺呮繄鍒掑▎鎾崇闁瑰濮寸粻鐢告煟閻樺厖鑸柛鏂垮缁嬪顓奸崱妯哄伎濠碉紕鍋犻褎绂嶆ィ鍐┾拺闁告繂瀚~锕傛煕閺傝法鐒搁柛鈹垮劜瀵板嫭绻涢姀銏犳瀾鐎垫澘瀚伴幆鍌炲传閵夘灖鎴︽⒑闂堟稒鎼愰悗姘卞娣囧﹪骞栨担瑙勬珳闂佸憡渚楅崢鑹邦杺闂傚倸鍊峰ù鍥敋閺嶎厼绐楁俊銈呮噺閸嬶繝鏌嶉崫鍕櫡闁逞屽厸缁舵艾顕i鈧畷鐓庘攽閸偅效濠碉紕鍋戦崐鏍箰閼姐倖宕查柛鏇ㄥ幘閻棝鏌涢弴銊ョ仭闁抽攱甯¢弻娑氫沪閸撗勫櫗缂備椒鑳舵晶妤呭Φ閸曨垰鍗抽柣鏂挎惈閳峰矂鎮楃憴鍕;闁告鍟块锝嗙鐎e灚鏅濋梺闈涚墕濞村倸危缁嬪簱鏀介柣妯虹仛閺嗏晛鈹戦鑺ュ唉鐎规洘鍔栫换婵嗩潩椤掍浇绶㈤梻浣瑰濞叉牠宕愯ぐ鎺撳亗婵炲棙鍔戞禍婊堟煛瀹ュ骸浜滃ù鐘崇矊闇夋繝濠傛噹椤g厧菐閸パ嶈含闁瑰磭濮甸敍鎰攽閸℃﹩鍞查梻鍌欑閻ゅ洭锝炴径鎰瀭闁秆勵殔閺勩儵鏌涢弴銊ョ仩缂佲偓閸愵喗鐓忓┑鐐戝啯鍣烽柛瀣р偓鏂ユ斀闁挎稑瀚禍濂告煕婵炲灝鈧繂鐣烽姀掳鍋呴柛鎰╁妿椤ρ冣攽閳藉棗鐏熼悹鈧敃鍌氬惞闁哄洢鍨洪崑锝夋煕閵夛絽濡块柕鍫濈摠娣囧﹪骞撻幒鏂库叺闂佸搫鏈ú婵堢不濞戙垹鍗抽柣鎴濇缂嶅矂姊绘担绋挎毐闁圭⒈鍋婇獮濠呯疀濞戞瑥浜楅棅顐㈡处閹尖晠鎮㈤崱娑欏仯濡わ附瀵ч鐘差熆瑜庡ú鐔煎蓟濞戙垹绫嶉柍褜鍓熼獮鎰板箮閽樺鎽曞┑鐐村灟閸ㄧ懓螞濡崵绠鹃柛鈩冪懃娴滄儳螖閺冨倻纾介柛灞剧懄缁佹澘顪冪€涙ɑ鍊愭鐐村姈缁绘繂顫濋鍌ゅ數闂備礁鎲℃笟妤呭垂閹惰姤鍎楁繛鍡樻尭缁犲綊鎮楀☉娅虫垹浜搁鐏荤懓饪伴崼銏㈡毇闂佸搫鏈粙鎴﹀煘閹达箑绀嬫い鎰╁灩琚橀梻鍌欑劍濡炲潡宕㈡禒瀣濡わ絽鍟粻鐔兼煙闂傚鍔嶉柛瀣儔閺屾盯顢曢敐鍥╃暭闂佽崵鍠嗛崝鎴濐潖濞差亜浼犻柛鏇㈡涧閸擃喚绱撴担钘夌厫鐎光偓缁嬫鍤曞┑鐘崇閸嬪嫰鏌i幘铏崳妞わ富鍙冮幃宄扳堪閸愵亞顔婇梺杞扮贰閸犳牠鍩ユ径鎰潊闁挎稑瀚獮鎰版⒒娴e憡鍟炲〒姘殜瀹曟澘螖閸涱厾锛欓梺瑙勫婢ф鎮″☉銏″€堕柣鎰邦杺閸ゆ瑥鈹戦鐓庘偓鍧楀蓟閻旂⒈鏁婇柛婵嗗閸嬫挸鈹戦崱娆愭闂佸湱鍎ら崹鐔肺i崼鐔稿弿婵°倐鍋撴俊顐f⒒濡叉劙鏁撻敓锟� ---闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚敐澶婄闁挎繂鎲涢幘缁樼厱濠电姴鍊归崑銉╂煛鐏炶濮傜€殿噮鍣e畷濂告偄閸涘⿴鍞堕梻鍌欒兌鏋い鎴濇楠炴劙宕滆閸ㄦ繃銇勯幘璺轰汗婵℃彃鐗婃穱濠囶敍濮橆厽鍎撶紓浣哄Ь椤曆囧煘閹达附鍊烽柛娆忣槴閺嬫瑦绻涚€涙ḿ鐭嬬紒顔芥崌楠炲啴鍨鹃弬銉︻潔闂侀潧楠忕槐鏇㈠储閸楃偐鏀介柣鎰綑閻忋儳鈧娲﹂崜鐔兼偘椤斿槈鐔沸ч崶锔剧泿闂備礁鎼崐鍦偓绗涘泚澶愬閳╁啫寮挎繝鐢靛Т閹冲繘顢旈悩缁樼厵闁荤喐婢橀顓炩攽閳╁啯鍊愬┑锛勫厴閺佸倿骞嗚缁嬪牓姊婚崒姘偓鐑芥嚄閸洖绠犻柟鎹愵嚙閸氬綊鏌″搴″箹缂佺媭鍨堕弻銊╂偆閸屾稑顏�
开发学院软件开发Java WebSphere sMash 的创新应用,第 2 部分: 借助包装... 阅读

WebSphere sMash 的创新应用,第 2 部分: 借助包装外部系统管理工具,通过云来实现企业操作自动化

 2010-10-09 08:13:06 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鎯у⒔閹虫捇鈥旈崘顏佸亾閿濆簼绨绘い鎺嬪灪閵囧嫰骞囬姣挎捇鏌熸笟鍨妞ゎ偅绮撳畷鍗炍旈埀顒勭嵁婵犲嫮纾介柛灞捐壘閳ь剛鎳撻~婵嬪Ω閳轰胶鐤呯紓浣割儐椤戞瑩宕ョ€n喗鐓曟い鎰靛亝缁舵氨绱撻崘鈺傜婵﹤顭峰畷鎺戔枎閹搭厽袦婵犵數濮崑鎾绘⒑椤掆偓缁夌敻骞嗛悙鍝勭婵烇綆鍓欐俊鑲╃磼閹邦収娈滈柡灞糕偓鎰佸悑閹肩补鈧尙鏁栧┑鐐村灦閹稿摜绮旈悽绋课﹂柛鏇ㄥ灠閸愨偓濡炪倖鍔﹀鈧繛宀婁邯濮婅櫣绱掑Ο璇茶敿闂佺ǹ娴烽弫璇差嚕婵犳碍鏅插璺猴工瀹撳棝姊虹紒妯哄缂佷焦鎸冲畷鎴﹀箻鐠囧弶宓嶅銈嗘尰缁嬫垶绂嶉悙顒佸弿婵☆垳鍘ф禍楣冩倵濮樼偓瀚�闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鎯у⒔閹虫捇鈥旈崘顏佸亾閿濆簼绨奸柟鐧哥秮閺岋綁顢橀悙鎼闂侀潧妫欑敮鎺楋綖濠靛鏅查柛娑卞墮椤ユ艾鈹戞幊閸婃鎱ㄩ悜钘夌;婵炴垟鎳為崶顒佸仺缂佸瀵ч悗顒勬⒑閻熸澘鈷旂紒顕呭灦瀹曟垿骞囬悧鍫㈠幍缂傚倷鐒﹂敋缂佹う鍥ㄧ厓鐟滄粓宕滈敃鍌氱煑闁告劦鐓堝ḿ鏍煕濠靛棗鐝旂憸鏂跨暦閹偊妲炬繛瀵稿Т閵堢ǹ顫忛搹瑙勫珰闁肩⒈鍓涢澶愭⒑閻撳海绉虹紒鐘崇墵楠炲啯銈i崘鈺佲偓濠氭煢濡警妲奸柟鑺ユ礋濮婃椽妫冨☉杈€嗘繝纰樷偓铏枠鐎规洏鍨介幃浠嬪川婵炵偓瀚奸梺鑽ゅ枑閻熴儳鈧氨鍏樺畷顖濈疀濞戞瑧鍘遍梺缁樏壕顓熸櫠閻㈠憡鐓忛柛鈩冾殔閳ь剙婀辩紓鎾寸鐎n亜绐涙繝鐢靛Т鐎氼剟鐛崼銉︹拺缁绢厼鎳庨ˉ宥夋煙濞茶绨芥俊鍙夊姍瀵挳鎮㈤崫鍕ㄥ彏闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥囧弲闂侀潧鐗嗗ú鐘诲磻閹炬剚娼╂い鎰╁灩缁侇噣姊虹紒妯圭繁闁革綇缍侀悰顕€骞掗幊铏閸┾偓妞ゆ帒鍊绘稉宥夋煥濠靛棙顥犵紒鈾€鍋撻梻鍌氬€搁悧濠勭矙閹达箑姹叉繛鍡楃贩閻熸壋鍫柛顐犲灮閺嗩偊姊洪崫鍕効缂傚秳鐒﹂幈銊╁焵椤掑嫭鐓冮柟顖滃绾偓绻濋埀顒佹綇閵娧呭骄闂佸搫娲ㄩ崰鎾跺姬閳ь剙鈹戦鏂や緵闁告﹢绠栧畷銏ゆ偨閸涘ň鎷虹紓鍌欑劍閿氬┑顕嗙畵閺屾盯骞橀弶鎴濇懙闂佽鍠楄摫婵炵厧绻樻俊鎼佸Χ閸モ晝鏆伴梻鍌欑濠€杈╁垝椤栨粍鏆滈柣鎰摠濞呯姵绻涢幋鐐寸殤缁炬崘鍋愮槐鎾存媴鐠愵垳绱板┑鐐村絻椤曨參鍩€椤掑喚娼愭繛鍙夌墪閻g兘顢楅崘顏冪胺闂傚倷绀侀幉锟犲礉閺囥垹鐤柣妯款嚙缁€鍫熺節闂堟稓澧涚€规洖寮剁换娑㈠箣閻愩劎绱伴梺鍝勬濡鍩為幋锔藉亹閺夊牜鍋勯崢锟犳⒑鏉炴壆鍔嶉柣妤佺矌濡叉劙骞樼€涙ê顎撴繛瀵稿Т椤戝懘骞楅悽鍛娾拺闁革富鍘介崵鈧┑鐐茬湴閸婃繈骞冩ィ鍐╁€婚柦妯侯槺椤斿﹪姊虹憴鍕剹闁告ü绮欏畷鎾绘偨閸涘ň鎷洪梺鑽ゅ枑濠㈡﹢骞冩笟鈧弻锝夊箳閻愮數鏆ら梺璇″枟椤ㄥ﹪鐛弽銊﹀闁稿繐顦扮€氳棄鈹戦悙鑸靛涧缂佹彃娼″畷鏇㈠Χ婢跺﹤鎯為梺閫炲苯澧存慨濠冩そ楠炴牠鎮欏ù瀣壕闁哄稁鍘介崑瀣煟濡灝鍚圭€规挷绶氶悡顐﹀炊閵娧€濮囬梺鍝勬噺閹倿寮婚妸鈺傚亞闁稿本绋戦锟�濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻橀弻锝夊箣閿濆棭妫勯梺鍝勵儎缁舵岸寮诲☉妯锋婵鐗婇弫楣冩⒑閸涘﹦鎳冪紒缁樺灴婵$敻宕熼姘鳖啋闂佸憡顨堥崑鐔哥閼测晝纾藉ù锝呮惈椤庡矂鏌涢妸銉у煟鐎殿喛顕ч埥澶愬閻樼數鏉搁梻鍌氬€搁悧濠勭矙閹烘鍊堕柛顐犲劜閸婄敻鏌i悢鍝勵暭闁哥喓鍋熺槐鎺旀嫚閹绘帗娈绘繝纰夌磿閺佽鐣烽悢纰辨晬婵﹢纭搁崯瀣⒑鐠囨煡鍙勬繛浣冲洤绠烘繝濠傜墛閸嬧晛鈹戦崒姘暈闁抽攱鍨归惀顏堫敇閻愭潙顎涘┑鐐插悑閸旀牜鎹㈠☉銏″殤妞ゆ巻鍋撻柡瀣閵囧嫰顢曢姀銏㈩唺缂備浇椴哥敮鎺曠亽闂佸吋绁撮弲婊堝吹瀹€鍕拻濞撴埃鍋撻柍褜鍓涢崑娑㈡嚐椤栨稒娅犳い鏃囧亹閺嗗棝鏌ㄥ┑鍡欏闁告柨鐏氶妵鍕晜閻e苯寮ㄩ梺璇″櫙缁绘繃淇婇懜闈涚窞閻庯綆鍓欑敮楣冩⒒娴gǹ顥忛柛瀣噽閹广垽宕橀鑲╋紱濡炪倕绻愰幊鎰不閸撗€鍋撻悷鏉款棌闁哥姵娲滈懞杈ㄧ節濮橆剛鐣鹃梺缁樻煥閸氬鍩涢幋锔藉€甸柛锔诲幖鏍¢梺闈涙閸熸挳寮婚妶澶婄闁肩⒈鍓欓悡鐔兼倵鐟欏嫭绀冪紒璇茬墦瀵偊宕橀鑲╁姦濡炪倖甯掔€氀囧焵椤掍焦顥堢€规洘锕㈤、娆撳床婢诡垰娲﹂悡鏇㈡煃閳轰礁鏋ゆ繛鍫燂耿閺岋綁鎮㈢粙鍨潚濠殿喖锕ュ浠嬪箖閳╁啯鍎熼柍鈺佸暞閻︼綁姊绘担铏瑰笡闁绘娲熸俊鍓佺矙鐠恒劍娈鹃梺缁樺灦宀h法寮ч埀顒勬⒑閹肩偛鍔€闁告劑鍔庨妶顕€姊婚崒娆戠獢婵炰匠鍕垫闊洦娲橀~鏇㈡煛閸ャ儱鐏╅柛灞诲妽閵囧嫯绠涢幘璺侯杸闂佹娊鏀遍崹鍧楀蓟閻斿吋鍤冮柍杞版缁爼姊洪崨濠冣拹妞ゃ劌锕濠氭晸閻樻彃绐涘銈嗘閺侇喗鎱ㄩ崶鈺冪=濞达絿枪閳ь剙婀遍弫顕€鎮㈡俊鎾虫川閳ь剟娼ч幗婊呭婵傜ǹ绾ч柛顐g☉婵¤偐绱掑Δ浣侯暡缂佺粯鐩幃鈩冩償閿濆浂鍟嬮梻浣虹《閺備線宕滃┑瀣闁告稑鐡ㄩ悡銉╂倵閿濆懐浠涚紓宥嗩殜濮婂宕掑顑藉亾瀹勬噴褰掑炊瑜滃ù鏍煏婵炵偓娅嗛柛濠傛健閺屻劑寮撮悙娴嬪亾閸濄儳涓嶉柡灞诲劜閻撴洟鏌曟径妯烘灈濠⒀屽櫍閺岋紕鈧絺鏅濈粣鏃堟煛瀹€鈧崰鏍х暦濠婂棭妲鹃柣銏╁灡閻╊垶寮婚敓鐘插窛妞ゆ棁妫勯埀顒佸姍閺岋紕浠︾拠鎻掝潎闂佽鍠撻崐婵嗙暦閹烘垟妲堟慨妤€妫旂槐锟�闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鎯у⒔閹虫捇鈥旈崘顏佸亾閿濆簼绨绘い鎺嬪灪閵囧嫰骞囬姣挎捇鏌熸笟鍨妞ゎ偅绮撳畷鍗炍旈埀顒勭嵁婵犲嫮纾介柛灞捐壘閳ь剛鎳撻~婵嬪Ω閳轰胶鐤呯紓浣割儐椤戞瑩宕ョ€n喗鐓曟い鎰靛亝缁舵氨绱撻崘鈺傜婵﹤顭峰畷鎺戔枎閹搭厽袦婵犵數濮崑鎾绘⒑椤掆偓缁夌敻骞嗛悙鍝勭婵烇綆鍓欐俊鑲╃磼閹邦収娈滈柡灞糕偓鎰佸悑閹肩补鈧尙鏁栧┑鐐村灦閹稿摜绮旈悽绋课﹂柛鏇ㄥ灠閸愨偓濡炪倖鍔﹀鈧繛宀婁邯濮婅櫣绱掑Ο璇茶敿闂佺ǹ娴烽弫璇差嚕婵犳碍鏅插璺猴工瀹撳棝姊虹紒妯哄缂佷焦鎸冲畷鎴﹀箻鐠囧弶宓嶅銈嗘尰缁嬫垶绂嶉悙顒佸弿婵☆垳鍘ф禍楣冩倵濮樼偓瀚�  闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚敐澶婄闁挎繂鎲涢幘缁樼厱闁靛牆鎳庨顓㈡煛鐏炶鈧繂鐣烽锕€唯闁挎棁濮ら惁搴♀攽閻愬樊鍤熷┑顕€娼ч~婵嬪Ω瑜庨~鏇㈡煙閹规劦鍤欑痪鎯у悑缁绘盯宕卞Ο铏圭懆闂佸憡锕槐鏇犳閹惧鐟归柛銉戝嫮褰梻浣规偠閸斿矂鎮ラ崗闂寸箚闁圭虎鍠栫粈鍐┿亜閺冨倸甯剁紒鎰洴濮婃椽宕崟鍨ч梺鎼炲妼缂嶅﹤鐣烽姀鐘嗘椽顢旈崨顓涘亾閸偒娈介柣鎰皺娴犮垽鏌涢弮鈧喊宥夊Φ閸曨垱鏅滈悹鍥皺娴犳悂鎮楃憴鍕┛缂佺粯绻堥悰顔芥償閵婏箑娈熼梺闈涳紡閸愩劌顩梻鍌氬€搁オ鎾磻閸曨個娲晝閳ь剛鍙呴梺鍝勭Р閸斿孩鏅堕敓鐘斥拻闁稿本鐟︾粊鐗堛亜閺囧棗鎳夐崑鎾诲垂椤愩垺璇為悗瑙勬礃缁捇骞冮姀锛勯檮濠㈣泛顑囩粙渚€姊绘担鐟板姢缂佺粯鍔曢敃銏℃綇閳轰緡妫滈梺绋跨箻濡法鎹㈤崱妯镐簻闁哄秲鍔庨。鏌ユ煙椤栨氨澧涢柕鍥у椤㈡洟濮€閳惰¥鍨洪妵鍕敂閸曨偅娈绘繝纰樷偓宕囧煟鐎规洖宕灃闁逞屽墴閿濈偞鎯旈妸锔规嫼闂佸憡绋戦オ鎾倿婵傚憡鐓曢柕澶嬪灥閹冲骸顕i妸銉㈡斀闁绘﹩鍠栭悘杈ㄧ箾婢跺顬奸柣褍鐭傚铏圭磼濡崵鍙嗛梺鍛婅壘椤戝骞冮敓鐘参ㄩ柍鍝勫€搁埀顒傛暬閺屻劌鈹戦崱娑扁偓妤呮煕濡粯灏﹂柡灞剧〒閳ь剨缍嗛崑鍛焊閹殿喚纾肩紓浣贯缚缁犳挻銇勯锝囩疄妞ゃ垺锚閳藉鈻庤箛锝勭椽闂傚倷娴囧畷鐢稿窗閹邦喖鍨濋幖娣灪濞呯姵淇婇妶鍛殲闁哄棙绮撻弻鐔兼倻濡鏆楀銈傛櫆瑜板啴婀侀梺缁樻尭濞寸兘骞楅悩缁樼厽闁规儳鐡ㄧ粈瀣煛瀹€鈧崰鏍嵁閸℃凹妾ㄩ梺鎼炲€楅崰鏍蓟瀹ュ瀵犲鑸瞪戦埢鍫ユ⒑閸濆嫯瀚扮紒澶婂濡叉劙骞掗幊宕囧枛閹筹繝濡堕崨顓熻緢婵犵绱曢崑鎴﹀磹閵堝纾婚柛娑卞灡瀹曟煡鏌涢鐘插姎缂佺姷濮电换婵囩節閸屾稑娅i梺鍝勵儏閻楀﹥绌辨繝鍥舵晬婵犲灚鍔曞▓顓烆渻閵堝懐绠扮紓宥咃工椤繑绻濆顒傦紲濠电偛妫欓崺鍫澪i鈧铏规兜閸滀礁娈濈紓浣介哺濞叉粓宕氶幒鎴旀瀻闁规儳纾娲⒑閹稿孩鐓ラ柟纰卞亝缁傚秵绺介崨濞炬嫼闂佸憡绻傜€氬嘲危瑜版帗鐓曢柕濞у啯鐏堥悗娈垮枟閹倸顕i鈧畷濂告偄閸濆嫬绠伴梻鍌欑閹诧繝宕濊瀵板﹪鎳為妷褜娲搁梺鍛婃寙閸涱垽绱冲┑鐐舵彧缂嶁偓婵炲拑绲块弫顔尖槈濮樿京锛滈柣搴秵閸嬪懐浜搁幍顔剧<闁稿本绋戝ù顕€鏌℃担绋挎殻鐎规洘甯掗~婵嬪箟鐎n剙绨ユ繝鐢靛У椤旀牠宕板Δ鍛櫇闁冲搫鎳庣粈鍫ユ煥閺囩偛鈧綊宕愰悽鍛婄厵闁诡垱婢樿闂佹娊鏀辩敮鎺楁箒闂佹寧绻傞幊蹇涘箟閹间焦鐓ユ繛鎴炨缚鑲栫紓浣介哺鐢繝銆佸璺哄窛妞ゆ挾濮冲鎾翠繆閵堝洤啸闁稿鍋ゅ畷褰掑垂椤旂偓娈鹃梺鍓插亝濞诧箓寮崱娑欑厱閻忕偟鍋撻惃鎴︽煏閸剛鐣垫慨濠呮閹风娀骞撻幒鎴炵槪缂傚倸鍊哥粔鏉懳涘▎鎴犵焿鐎广儱顦崘鈧銈嗘尵閸嬬喖宕Δ浣虹閻庣數枪瀛濆銈嗗灥濡繈骞冮垾鏂ユ瀻闁瑰墽琛ラ幏鍝勵渻閵堝棙灏柛鏂块叄閹箖宕¢悜鍡欏數閻熸粍绮撳畷褰掓焼瀹ュ憘锕傛煕閺囥劌鐏犳俊顐o耿閺屾盯鈥﹂幋婵囩亐闂佺ǹ顑嗛幐楣冨箟閹绢喖绀嬫い鎾寸⊕閺侀潧鈹戦悩鍨毄濠殿喗娼欑叅闁挎洖鍊哥壕褰掓⒑閸噮鍎嶅ù婊勭矒閻擃偊宕堕妸锕€纰嶅銈呯箞閸婃繈寮诲☉姘e亾閿濆骸浜濈€规洖鐬奸埀顒侇問閸犳牠鍩€椤掑倸娅忔俊淇卞妼閳规垿鎮欓幓鎺撳€梺缁橆殕濞茬喖宕洪悙鍝勭闁挎棁妫勬禍褰掓煟鎼粹剝璐″┑顔芥尦钘熸繝闈涱儐閳锋垹绱掔€n厼鍔垫い顐畵閺屾盯寮崸妤€寮板Δ鐘靛仜椤︻垶锝為姀鐘垫殕闁逞屽墴閹潡鍩€椤掆偓閳规垿鎮欓弶鎴犱桓鐎光偓閿濆懏鍋ラ柟顔兼健瀹曘劎鈧稒菤閹锋椽姊洪棃鈺佺槣闁告瑢鍋撳┑锛勫亾閹倿寮诲☉銏″亹闁归鐒﹂悿渚€鎮楀▓鍨灍闁绘搫绻濋悰顕€寮介妸锕€顎撻梺闈╁瘜閸樼厧顕i幎鑺モ拻濞达綀娅g敮娑欑箾閸欏澧电€规洘鍔欏畷鐑筋敇濞戞ü澹曞┑顔结缚閸嬫挾鈧熬鎷�
核心提示:本系列文章描述了有关 IBM® WebSphere sMash® 的真实例子,在该例子中 IBM WebSphere sMash 被选择用于执行创新和有价值的任务,WebSphere sMash 的创新应用,第 2 部分: 借助包装外部系统管理工具,通过云来实现企业操作自动化,来辅助位于美国 CT So

本系列文章描述了有关 IBM® WebSphere sMash® 的真实例子,在该例子中 IBM WebSphere sMash 被选择用于执行创新和有价值的任务,来辅助位于美国 CT Southbury 的 IBM's Green Innovation Data Center(GIDC)的运行。第 1 部分 关注如何利用 WebSphere sMash 为构造数据中心指示板构建灵活的架构。在本文中,您将看到 WebSphere sMash 如何利用易用 APIs 包装外部系统管理工具来简化那些高成本的、会增加 GIDC 运行开销的手工任务的自动化。

简介

运行数据中心时,不能只盯着满架的服务器。为达到当今企业在安全标准、数据保护、以及资产管理方面的需求,所必须执行的流程和过程的数量在不断增长。找到新方法来自动化这些任务,并将它们构建到灵活的工作流中,是创新工程组所关注的一个重要问题。

本文重点介绍,利用 WebSphere sMash 的特性,轻松包装外部 API,来实现过去必须由操作人员利用用户接口来执行的一系列步骤,自动化地由云管理基础结构的控制组件驱动的相关例子。

您还有机会了解,应用 WebSphere sMash 生成 Web 应用开发与配置组件特性的技巧。

一个企业应用场景

在我们的环境中,所有联网计算机 — 真实的和虚拟的 — 都需要在数据库中注册,该数据库作为 Address 数据库。传统上,用户通过具有典型用户接口的 Web 应用,来添加、删除、以及更新系统的每个条目。然而,引入云环境后,我们想要在用户发出请求时,利用与其使用习惯相应的注册实例,来简化处理流程。

幸运的是,我们的 Address 数据库应用中已经包含了一个用于执行这些操作的 Java™ API。企业云中的每个云管理系统可以包括一个利用该 API 来管理 Address 数据库中条目的 Java 程序。

然而,试想一下,多个云系统想要利用这一服务的优势。为避免不得不在多个地方分发与更新 Java API 库,我们可以创建包含该 Java API 的服务,从而其他系统就可以利用 RESTful 端点,通过 HTTP 访问该服务。我们能够拥有贯穿整个企业的公共服务。开发该服务背后的步骤,就是本文所关注的焦点。

图1 阐明了该体系结构的概述。通常,系统 — 而不是用户 — 将连接我们所提供的服务,虽然操作人员仍然可以使用用户接口来直接访问 Address 数据库。

图 1. Address 数据库包装器架构
WebSphere sMash 的创新应用,第 2 部分: 借助包装外部系统管理工具,通过云来实现企业操作自动化

查看原图(大图)

您将看到 WebSphere sMash 如何通过消除复杂的配置和引导您关注应用的逻辑,来简化这一流程。

本文假设您熟悉 WebSphere sMash 环境的基本设置以及 “hello world” 应用程序的创建,并假设您已阅读了本系列的 第 1 部分 ,该部分介绍了将在这里详细叙述的概念。在本例中,这一简单应用将被编码到 Groovy 中,但是 WebSphere sMash 为您提供 PHP 替代选项,您可自己选择。

创建基础

在该 Address 数据库上您所要支持的操作包括:创建、删除、列表、检索、以及更新记录。

第 1 部分 说明 WebSphere sMash 如何在 Groovy 文件中轻松实现这些基本操作与方法、HTTP 路径以及操作之间的映射。然而,该文章只关注从服务获取数据(检索以及列表)。在此,服务调用者越想执行更多类型的操作,事情就会变得越有趣。由于用于 Address 数据库的 Java API 提供了所需的操作,您的任务就是将 API 中的 Java 方法与 URI 端点联系起来。

我们用清单 1 中所列出的方法在 /resources 目录中创建名为 system.groovy 的 Groovy 处理程序。要记住,目录 /resources 是包含用于管理收集的 REST 处理程序的优选位置。在本例中,收集是您正在 Address 数据库中注册与管理的一系列系统。

清单 1. system.groovy 的根存方法

def onList() {  
 
 print("This function will list systems in the database.") 
 
} 
 
def onCreate() {  
 print ("This function will create a new system in the database") 
 
} 
 
def onRetrieve() {  
 print ("This function will retrieve a particular system from the database") 
 
}  
 
def onUpdate() {  
 print ("this function will update an existing system in the database") 
 
}   
 
def onDelete() {  
 print ("this function will delete an existing system from the database") 
 
}

正如表 1 中所列出的,每个方法将由不同的 HTTP 操作触发,该表展示了 HTTP 操作与 URIs 以及方法之间的映射。概括地说,这是我们的 RESTful API。

表 1. HTTP 操作与 URIs、以及方法之间的映射

HTTP 方法URI描述映射到方法
GET/system返回系统列表。onList
POST/system创建新系统。onCreate
GET/system/3检索系统 3 的细节。onRetrieve
PUT/system/4更新现有的系统 4。onUpdate
DELETE/system/7删除现有的系统 7。onDelete

例如,对 /resources/system 执行 HTTP GET,会将 onList 函数映射到 system.groovy 中。以所提供的数据作为负载,对 /resource/system 执行 HTTP POST,将会触发函数来创建新的系统记录。事情就是这么简单,不需要做任何配置。

然而,如果您不想采用默认映射,您可以通过在 zero.config 配置文件中编写定制处理程序配置,并将其映射到 Groovy、PHP、或者 Java 代码来完成映射。

您是否期待在您的系统上进行多种 HTTP 操作测试?Firefox 插件 Poster 可帮助您快速地在您所指定的 URL 上进行 GET、POST、PUT、以及 DELETE 操作测试。

此时,您可对所有操作进行测试。在首次启动应用之前,有必要在应用程序的根目录中,以命令行的方式运行 zero resolve 来进行启动。假定应用程序在本地运行,并采用默认端口 8080,可通过浏览器访问应用的默认 URL:http://localhost:8080/resources/system。

通过表 1 ,可见这个 URL 映射到一列操作,onList。onList 方法只是带有一些浏览器输出的存根。此时,将会在浏览器窗口中看到以下文字:This function will list systems in the database。

如果正在数据库中创建新的条目,可尝试在处理程序上执行 POST,来查看来自存根的响应。此时,不必考虑在 HTTP 请求中加入任何载荷,因为还没有包含相关的解析代码。

连接到后端

此时已经拥有了 system.groovy 中每个操作的存根,并且已了解如何基于所选择的 URL 和 HTTP 方法来引用不同的方法。下面的任务是如何挂接到来自 Groovy 处理程序的 Address 数据库遗留 Java API。我们来看一下如何将两者联系起来。

首先,将 Address 数据库 Java 库 JAR 文件放入 WebSphere sMash 应用的 /lib 目录中,这样就可以利用代码来访问这些类。/lib 目录中的 Java JARs 会在应用启动时自动加载,这样就不再需要手动调整类路径。

针对本例的目的,假设 JAR 文件名为 addressdb.jar,并且它还包含一个 Java 接口 com.ibm.addressdb.Manager.class 来连接到 Address 数据库并执行操作。清单 2 列出了管理接口的细节,并且实现(未展示出来)包含在 ManagerImpl.class 中。JAR 还定义了类 com.ibm.addressdb.SystemDetails.class,其代表了 Address 数据库应用中的一个系统。

清单 2. 管理接口

package com.ibm.addressdb; 
 
import java.util.List; 
 
public interface Manager { 
 
 public abstract void logon(String username, String password) throws Exception; 
 
 public abstract List<SystemDetails> listSystems(); 
 
 public abstract SystemDetails getSystem(int systemId) throws Exception; 
 
 public abstract SystemDetails addSystem(SystemDetails newSystem) throws Exception; 
 
 public abstract SystemDetails updateSystem(int sysId, 
  SystemDetails system) throws Exception; 
 
 public abstract int deleteSystem(int sysId) throws Exception; 
 
}

为使用来自 Groovy 的 Java 工件,包含相应 Java 导入语句。可以无缝地在您的 Groovy 方法中(清单 3)使用它们。

清单 3. 在 system.groovy 上构建

import com.ibm.addressdb.Manager; 
import com.ibm.addressdb.ManagerImpl; 
import com.ibm.addressdb.SystemDetails; 
 
 
def onList() { 
 
 Manager m = ManagerImpl.getInstance () 
 m.logon ('addressdbid@myorg.org','systempassword') 
 List list = m.listSystems ()  
 request.view='JSON' 
 request.json.output=list 
 render() 
 
}

onList 方法用于通过 Java API 连接 Address 数据库,并在表单 JSON 中返回系统列表。请注意,WebSphere sMash 请求处理程序框架会利用所示的语法,自动将包含零或更多 SystemDetails 的 List 对象转换为 JSON 数组。要确保 List 类型的 getters 和 setters 遵循 JavaBean 惯例来支持这一转变。清单 4 展示了相应的示例。随后,将介绍如何对密码进行编码,来避免其以明文形式在代码中出现。

清单 4. 对列表请求的响应

[ 
{ 
"creatorId":"cloud1@myorg,com", 
"ipAddress":"9.45.15.40", 
"ownerId":"user1@myorg.com", 
"systemId":"0", 
"systemName":"financeServer" 
} 
{ 
"creatorId":"cloud1@myorg,com", 
"ipAddress":"9.45.15.41", 
"ownerId":"user2@myorg.com", 
"systemId":"1", 
"systemName":"hrServer" 
} 
]

接下来,我们来看您如何为在数据库中创建新的系统记录而进行 onCreate 方法编码。在此,需要领会包含系统细节的 POST 内容,然后将这些填充进 Java API。该操作通过提取 HTTP POST 的内容,并将其转换成 JSON 对象来实现。那么,就可方便引用传入的特定属性。清单 5 以在 POST 请求中显示的格式展示一些系统参数。

清单 5. 创建系统记录的 POST 参数样例

{ 
 "systemName":"auditServer", 
"ownerId":"user4@myorg.com", 
      "ipAddress":“9.45.15.43" 
} 

清单 6 展示了如何轻松地提取请求中的参数并将其提供到 Java API 中。注意,从 JSON 对象中提取 IP 地址、系统名、以及系统所有者名,并将其传入您的服务中。

然而为了审计,还需要识别与服务请求相关的 ID。调用服务的系统将其作为服务 ID。为此,需要通过从检索全局上下文,来获取认证用户的用户名。参见 Global Context Reference 来了解其默认的存储值。借助这一参考,能够发现登录用户的用户名存储在 /request/subject/remoteUser 中。可通过将请求路径作为参数来执行 zget 方法,在全局上下文中检索成员:

zget (“/request/subject/remoteUser”)

或者通过调用另一个语法:

request.subject.remoteUser []

这将会返回认证的用户名。接下来,使用第二个语法,的它很简洁。

因为在当前的应用中并未采用身份认证,此时执行 remoteUser 检索将会返回空值。在下一部分中,您可了解到如何利用 LDAP 来建立认证与授权规则。

在 onCreate 方法的最后,会依照 REST 惯例,返回一个合适的 HTTP 代码。如果创建成功,会返回 HTTP 状态代码 201,来表明操作成功并且已经创建了一些内容。还会在 HTTP 资源头中返回新资源的位置。例如,新系统可能位于 URI:http://localhost:8080/resources/system/3。

可利用这一位置来检索新创建系统的 ID,确定其 ID 并查看其数据。需要追踪本地系统 ID,这样就可在其上执行后续操作(检索、更新、删除),但在本文中我们将要略去对本地数据库的管理。所创建的元素可被有选择地返回,但这不是必需的,我们选择不包含这些。

清单 7 展示检索系统的代码,清单 8 展示了删除系统,清单 9 展示了创建系统。

一些所有技术的注释:

将 POST 或者 PUT 主体中的 JSON 字符串转换为 JSON 对象,采用如下语法:

def systemInputs = zero.json.Json.decode(request.input[]);

接下来您可轻松访问 JSON 对象成员。可在 onUpdate 与 onCreate 中查看相关示例。

如前面所提到的,可利用 WebSphere sMash 的请求/响应框架,将简单 Java 对象和集合(Lists,、Maps 等等)转换成相应的 JOSN。该技术在 onRetrieve 和 onList 方法的最后有相关说明。没有必要手动将 Java 对象转换成 JSON 对象。

将系统 ID 作为 URL 参数提取的方法(onCreate、onRetrieve、onDelete 以及 onUpdate),采用如下语法:

request.params.systemId[]

为引用 URL 参数,然后将参数转换为整数。要遵照以下惯例来构成 “systemId” 部分:将出现在URL(在本例中为 “system” )中的集合资源名与 “Id” 连接来生成 “systemId”。

注意,不论在成功或失败的案例中,在每个方法的最后总返回 HTTP 返回代码。这些提供了 API 中成功操作的一个清楚而简洁的表示。

清单 6. system.groovy 的 onCreate 方法

def onCreate() { 
  
 //Convert request entity to JSON object 
 //then we can easily pull out the objects from it 
 def systemInputs = zero.json.Json.decode(request.input[]) 
 
 SystemDetails newSystem = new SystemDetails () 
 
 newSystem.setIpAddress (systemInputs.ipAddress) 
 newSystem.setSystemName (systemInputs.systemName) 
 newSystem.setOwnerId (systemInputs.ownerId) 
 
 String remoteUser = request.subject.remoteUser[] 
 
 if (remoteUser == null) { 
  
 remoteUser = 'none' 
 //handle error... 
 } 
 
 newSystem.setCreatorId (remoteUser) 
 
 
 
 Manager m =  ManagerImpl.getInstance () 
 m.logon ('addressdbid@myorg.org','systempassword') 
 
 SystemDetails confirmedSystem = m.addSystem (newSystem) 
 
 
 if (confirmedSystem !=null ) { 
 // Set a Location header with URI to the new record 
   locationUri = getRequestedUri(false) + '/' + newSystem.getSystemId() 
 request.status = HttpURLConnection.HTTP_CREATED 
 
  
 } else { 
  
 //handle error 
 request.status = HttpURLConnection.HTTP_INTERNAL_ERROR 
 request.error.message = "system $requestSystemId not found." 
    request.view = 'error' 
    render() 
 
 } 
 
 
}


清单 7. system.groovy 的 onRetrieve 方法

def onRetrieve() { 
 
 
 // Getting the system id of the system from the REST URL 
 // Follows the convention of "collection item name" + "Id" 
 
 def requestSystemId = Integer.parseInt(request.params.systemId[]) 
 
 Manager m = ManagerImpl.getInstance () 
 m.logon ('addressdbid@myorg.org','systempassword') 
 SystemDetails system = m.getSystem (requestSystemId)  
 
 String response = null 
 
 if (system !=null ) { 
 response = zero.json.Json.encode(system) 
 request.json.output=response 
 request.view='JSON' 
  
 render() 
 
  
 } else { 
  // Error handling 
    request.status = HttpURLConnection.HTTP_NOT_FOUND 
    request.error.message = "system $requestSystemId not found." 
    request.view = 'error' 
    render() 
 
  
 
 } 
 
} 


清单 8. system.groovy 的 onDelete 方法

def onDelete() { 
 
 def requestSystemId = Integer.parseInt(request.params.systemId[]) 
 
 Manager m = ManagerImpl.getInstance () 
 
 m.logon ('addressdbid@myorg.org','systempassword') 
 
 int deletedSystem = m.deleteSystem (requestSystemId)  
 
 if (deletedSystem >= 0 ) { 
 request.status = HttpURLConnection.HTTP_NO_CONTENT 
 
  
 } else { 
  
  // Error handling 
    request.status = HttpURLConnection.HTTP_NOT_FOUND 
    request.error.message = "system $requestSystemId not found." 
    request.view = 'error' 
    render() 
 
 } 
 
}


清单 9. system.groovy 的 onUpdate 方法

def onUpdate() { 
 
 
 
 def requestSystemId = Integer.parseInt(request.params.systemId[]) 
 
 
 Manager m = ManagerImpl.getInstance () 
 m.logon ('addressdbid@myorg.org','systempassword') 
 SystemDetails existingSystem = m.getSystem (requestSystemId)  
 SystemDetails confirmedSystem = null 
 
 if (existingSystem!=null){ 
 
 
 // Convert POSTED data to JSON object 
 //then we can easily pull out the objects from it 
 def systemInputs = zero.json.Json.decode(request.input[]) 
  
  
 existingSystem.setIpAddress (systemInputs.ipAddress) 
 existingSystem.setSystemName (systemInputs.systemName) 
 existingSystem.setOwnerId (systemInputs.ownerId) 
  
 String remoteUser = request.subject.remoteUser[] 
  
 if (remoteUser == null) { 
  
  remoteUser = 'none' 
  //handle error... 
 } 
  
 existingSystem.setCreatorId (remoteUser) 
  
  
 confirmedSystem = m.updateSystem (requestSystemId, existingSystem) 
 }    
 
 if (confirmedSystem !=null ) { 
 
 request.status = HttpURLConnection.HTTP_NO_CONTENT 
 
 } else { 
  
  // Error handling 
    request.status = HttpURLConnection.HTTP_NOT_FOUND 
    request.error.message = "system $requestSystemId not found or could not be 
 updated." 
    request.view = 'error' 
    render() 
 } 
 
 
 
}

加强服务的安全

现在已完全拥有了服务的基础,但还有必要实现对其安全访问。不仅您和访问该服务的注册用户需要知道它,而且还要确保只有授权的系统或用户可以访问它。幸运的是,WebSphere sMash 设计目的是使资源安全保护直接了当。最妙的是,仅需几行配置就可实现应用安全。

清单 10 阐述了可包括在 zero.config 中的配置。

清单 10. 安全配置

# Enable Security 
@include "security/enableSecurity.config" 
 
# Secret Key - run "zero secretkey" CLI command to generate secret key 
# Required whenever security is enabled in sMash 
/config/security/secretKey = "xMgwl+sUzcsRBLb4tBkn5w==" 
 
  
 
# Using the LDAP for authentication 
/config/security/userservice/registryType="ldap" 
  
 
### Inbound authorization to this wrapper 
               
# LDAP related configuration 
/config/security/userservice/ldap += { 
"jndiProviderUrl" : "ldaps://<serviceURL> /", 
"jndiSecurityAuthentication" : "simple", 
"ldapSearchScope" : 2, 
"ldapUserIdSearchFilterPattern" : "(&(mail={0})(objectclass=person))", 
"ldapUserIdBaseDn" : "ou=bluepages,o=<domain name>.com", 
"ldapGroupBaseDn" : "ou=memberlist, ou=<groupdDN>,o=<domain name>.com", 
"ldapUserIdAttributeType": "mail" 
}

逐步浏览这一配置:

参考包含在 WebSphere sMash 框架中的配置 security/enableSecurity.config 来确保安全。参考包含在 WebSphere sMash 框架中的配置 security/enableSecurity.config 来启用安全功能。

为了能在应用程序上下文中使用安全功能,需要生成一个密钥。该密钥用于在 WebSphere sMash 环境中加密机密用户数据。生成操作要在 Zero 命令行中使用命令 zero secretkey 实现。一旦生成了密钥,就需要将其包含到文件 zero.config 中。清单 10 展示了密钥的示例。

选择如何进行用户认证。可以在应用中包含一系列用户名和密码,还可以挂接到 LDAP 目录。在本例中,将连接到 LDAP,其操作如下所示:

/config/security/userservice/registryType="ldap"

为了进行测试,可能需要采用基于文件的用户注册方式。这一点在 WebSphere sMash 文档中有具体描述。

包括了 LDAP 数据库,其中是企业 LDAP 服务器所特有的代码。需要依据所采用的 LDAP 服务来定制该代码。

配置的最后一部分,包含在清单 11 中,这部分指出了所需保护的资源以及所要采用的认证方式。本例中选用基本认证方式。配置文件指出了以 “/resources/” 开头的资源需要授权。换句话说,保护的是 resource 目录下的资产而不是整个应用程序。假设有一些文档位于应用程序的公共目录下,任何人都可对其进行访问。如果采用这一安全配置将无法保护 WebSphere sMash 目录结构中 /resource/ 路径之外的公共目录。

注意,授权条件可能需要更细的粒度。在本例中,应用需要在 system.groovy 上执行除了 GET 之外所有操作,包括 POST、PUT、DELETE,进行授权。或者,也可以简单地只包含 HTTP 和 GET 操作。后面将对此做演示。

最后,指定允许访问的 LDAP 组 Address-Database-Wrapper-Users。非该组的用户将无法访问服务。

清单 11. 加密资源
#uses group discovered through LDAP authentication. 
@include "security/basicAuthentication.config"{ 
   "conditions": "(/request/path =~ /resources (/.*)?) &&  
 (/request/method =~ (POST| PUT|DELETE)) " 
  "groups" :["Address-Database-Wrapper-Users"]    
}

重启应用,并尝试对 http://localhost:8080/resources/system 执行 GET 或 POST 操作,将出现认证提示。

基本认证容易实施,因此在原型及情景应用中大量使用。还可方便用于本文所描述的系统到系统的场景中。它也有一些缺点,例如,用户名密码弹出对话框是否美观,要看浏览器的实施情况。另外,浏览器会缓存用户名和密码基本认证,因此无法进行刷新。其结果是退出很难实现。用户需要关闭浏览器来退出应用程序。

为实现更可靠以及定制化功能更强的认证处理,并获得更流畅的用户体验,您可能会选择基于表单的认证方式。此处不讨论基于表单认证方式的细节,但是 WebSphere sMash 框架支持这种方式。

利用 HTTPS 实现安全连接

由于需要请求用户名和密码,因此,在实际环境中必须采用 HTTPS 来实现安全连接。因为开发工作的需要,可以采用自签名认证,WebSphere sMash 在 zero.core.webtools 中包含一个自签名认证测试组件。

为启用 HTTPS,需要对文件 zero.config 进行一些配置,见清单 12。注意,密码 keystore 带有前缀 “<xor>.”。这一语法说明密码已加密,不会以明文方式出现在配置文件中。

现在要编码以明文形式包含在 groovy.system 中,用于后端 API 的密码。可利用 XOREncode 工具完成此操作。在利用 XOR 对应用程序进行编码时,可查询 WebSphere sMash 相关文档。

清单 12. 启用基本 HTTPS - 入站

/config/https/port = 8443 
/config/https/sslconfig = { 
    "keyStore": "./config/key.jks", 
    "keyStorePassword": "<xor>JTotMC8+LCw=" 
 
’, 
    "keyStoreType": "JKS" 
}

配置文件

关于配置的其他一些设置。

采用 WebSphere sMash,需要为应用程序设置上下文根。这有助于确保应用程序的可移植性,并可避免在假定应用资源位于根 “/” 中的前提下进行编码。还可在应用中为 URLs 增加可描述属性。下面是需要在 WebSphere sMash 中设置根上下文的配置示例:

/config/contextRoot="/addressdb"

通过正确设置,应用程序的基本 URL 改变了,之前是 http://localhost:8080/resources/system,现在变为 http://localhost:8080/addressdb/resources/system。

到目前为止,已经介绍了很多需要在配置文件中进行的设置。默认情况下,WebSphere sMash 会查找名为 zero.config 的配置文件。但是,随着配置的增加,zero.config 会变得难以控制。WebSphere sMash 中的一些特性能够帮助避免这一问题。

配置文件包括

配置文件中可以包含其他配置文件。清单 12 展示了将安全配置移动到其所拥有文件中的示例。您可能会发现,在为应用启用安全功能时,曾经见过这一示例。其中包含用于启用安全功能的基本 WebSphere sMash 配置文件。可对我们的文件采用相同的方法。

在清单 13 中,用于连接数据库 Address 的用户名和密码都加入到配置中,这样就可以从代码中删除最初写入的文字值(清单 3、6、8 和 9)。如前面所述,已利用 XOR API 对真实密码 “systempassword” 进行编码,实现了模糊处理;查看配置文件的其他用户无法读取该密码。如果想在代码中引用这些配置值,可采用与获取远程用户操作相同的语法。在本例中,采用 config.addressDB.username[] 来检索用户名。

清单 13. 包含配置文件

zero.config 的内容: 
 
… 
@include "addressDBSecurity.config" 
… 
 
 
Contents of config/addressDBSecurity.config: 
…. 
#default logon ID and password to access backend Address Database 
/config/addressDB/username="addressdbid@myorg.org" 
/config/addressDB/password=<xor>df3533wsKG8tOw== 
 
 
# Enable Security 
@include "security/enableSecurity.config" 
 
# Secret Key - run "zero secretkey" CLI command to generate secret key 
 
/config/security/secretKey = "xMgwl+sUzcsRBLb4tBkn5w=="" 
 
...

重写配置

通常,您很希望能有一个配置文件来帮助组织配置。这样还可以很方便地重写文件中所包含的属性。WebSphere sMash 能够轻松实现这一需求。举一个例子:假设在测试应用时,想利用非默认的测试用户名和密码来连接后端 Address 数据库。清单 14 如何设置 zero.config 文件来达到这一目的。在本清单中,重写了 addressDBSecurity.config 中所提供的默认用户名和密码。

清单 14. 重写匹配规则

Contents of zero.config 
 
… 
@include "addressDBSecurity.config"  
#override the username and password used to connect to the backend Address Database. 
/config/addressDB/username ="test-addressdbid@myorg.org" 
/config/addressDB/password="<xor>MiYvPiwsKG8tOw=="

这模仿在清单 11 资源上中首次设置认证时的技术。在清单 14 中,创建清单 13 上的配置。将整个安全配置转移到 addressDBSecurity.config 中。当调用包含时,就指出了希望替代 addressDBSecurity.config 中的基本配置,就不需要对 “GET” 请求做认证。

调试技术

如果既启用安全功能又要连接到供应商服务,那么启用附加追踪很有必要。requestLogging 服务在针对服务的追踪请求中很有用。每个请求记录到单独的文件中,并包含有价值的信息。而且,还会发现需要针对特定组件的附加追踪。清单 15 展示了日志配置的示例。

清单 15. 日志配置示例

#Enable the logging 
/config/requestLogging = true 
 
# Enable fine detail on certain components. 
/config/logging/levels = { 
    "zero.core.config" : "FINE", 
    "zero.core.security" : "FINEST" 
}

在应用正式上线时,确保已禁用或减少了日志,因为日志总会增加性能负载,而且详细的追踪日志会快速增长,并会消耗掉可用的硬盘空间。

结束语

本系列的第 2 部分,介绍了如何利用 WebSphere sMash 来围绕旧版 Java 工具构建 RESTful API 到外部系统管理应用的包装,并检查了将 WebSphere sMash 编程模式惯例用于支持快速应用开发的更多方法。

本系列中的第 3 部分将介绍 WebSphere sMash 利用可视化工具来创建工作流的能力,并介绍如何将其包含在应用当中。

Tags:WebSphere sMash 创新

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接