WEB开发网      濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堝姛缂佺娀绠栭弻宥堫檨闁告挻姘ㄩ幑銏犫槈濞嗘劕顎撻梺鍛婂姇瀵爼骞栭幇顔炬/闁告挆鍕畬闂佸疇顫夐崹鍧楀箖閳哄啠鍋撻崷顓炐㈡い銉︾箞濮婂搫效閸パ€鍋撳Δ鍛;闁规崘顕ф闂佸憡娲﹂崹鎵不濞戙垺鐓曟い鎰剁稻缁€鍐┿亜鎼达紕效婵﹨娅g划娆忊枎閹冨闂備礁鎽滄慨鐢稿礉濞嗘劒绻嗛柣銏⑶圭粈瀣亜閺嶃劏澹橀柛鐐姂濮婃椽妫冨ù銈嗙⊕閹峰懘骞撻幒宥咁棜闂備礁婀遍崕銈夈€冮崱娑樼厱闁圭儤顨嗛悡鏇㈡煛閸ャ儱濡煎ù婊勭矋閵囧嫯绠涢敐鍛睄闂佸搫澶囬埀顒€纾弳鍡涙倵閿濆骸澧伴柡鍡欏█閺屟勫濞嗘垵鍩岄梺闈涙鐢帡锝炲┑瀣亗閹艰揪绲奸悽鑽ょ磽娴h娈曢柛銊ョ仢椤繒绱掑Ο璇差€撶紓浣圭☉椤戝懎鈻撻鐐╂斀妞ゆ梹鏋婚崗顒傜磼閻樿櫕宕岄柕鍡曠椤繈骞囨担鍏夋瀸濠电姷鏁告慨顓㈠磻閹捐秮褰掓晲閸モ斂鈧﹪鏌¢埀顒佺鐎n偆鍘藉┑鈽嗗灡椤戞瑩宕电€n兘鍋撶憴鍕仩闁稿氦绮鹃悘鍐⒑缂佹◤顏勵嚕閸洖鐤柣鎰暩绾惧ジ鏌涚仦鐐殤閺佸牓鎮楃憴鍕缂侇喖绻樿棟閻庨潧鎽滃Λ顖炴煙椤栧棔绀佹禒顕€鎮楀▓鍨灈闁绘牜鍘ч悾鐑芥偂鎼存ɑ顫嶅┑鈽嗗灟鐠€锕傛倵瀹曞洨纾介柛灞剧懅閸斿秵銇勯妸銉︻棞闁伙絾绻堥獮鏍ㄦ媴濮濆本鎲伴梻浣虹帛濡啴藟閹捐姹查悗锝庡枟閻撶喐淇婇妶鍌氫壕闂佺粯顨呭Λ妤呭煝閹炬緞鏃堝川椤旇瀚奸梺鑽ゅТ濞茬娀鍩€椤掑啯鐝柣蹇婂亾闂傚倷绀侀幖顐﹀箠閹邦厽鍙忛柟缁㈠枟閸嬧晠鏌i妶搴$仜濞存粌缍婇弻鐔兼倻濡偐鐣洪梺鍝勬噺缁诲牆顫忓ú顏咁棃婵炴垶鑹鹃。鍝勨攽閳藉棗浜濋柣鐔叉櫊閵嗕礁鈻庨幒鏃傛澑闂佸搫鍟崐濠氭儊閸儲鈷戞慨鐟版搐閻忓弶绻涙担鍐插椤╃兘鏌ㄩ弴鐐测偓褰掓偂閺囥垺鐓忓┑鐐茬仢閸斻倝鏌涢埡瀣ɑ妞ゃ劊鍎甸幃娆撳级閹存繍娼氭俊銈囧Х閸嬬偤鏁冮姀銈冣偓浣糕枎閹炬潙娈愰梺鍐叉惈椤戝洭鐛姀銈嗏拻闁稿本鐟︾粊鐗堛亜椤愩埄妲搁柣锝呭槻铻i柤娴嬫櫇閻撳顪冮妶鍡橆梿闁跨喆鍎茬粋宥堛亹閹烘挾鍘甸梺缁樺灦钃遍悘蹇e幖闇夋繝濠傚暟缁夌儤鎱ㄦ繝鍛仩缂佽鲸甯掕灒闁惧繘鈧稒顢橀梻鍌欑劍鐎笛兠哄澶婄柧婵炴垶绮庢禍閬嶆⒒娴e憡鍟炴繛璇х畵瀹曞綊鏌嗗鍛幈闂佺鎻梽鍕偂濞嗘挻鐓犳繛鏉戭儐濞呭懎霉閻樺磭鐭婇柍瑙勫灴閸ㄩ箖鎮欓挊澶夊垝闂備浇顕栭崰妤呫€冮崨鏉戠叀濠㈣埖鍔曠粻鎶芥煙閹屽殶鐟滄澘娲ㄧ槐鎾诲磼濞嗘垼绐楅梺鍝ュУ閻楃娀銆侀弽顓炲窛闁圭⒈鍘介弲锝夋⒑缁嬭法绠抽柛妯犲懏顐介柣鎰節缁诲棙銇勯弽銊х煂閻㈩垱绋掔换娑㈠川椤撶喎鏋犲┑顔硷功缁垶骞忛崨瀛樺仭闂侇叏绠戝▓婵堢磽閸屾瑦绁版い鏇嗗洤纾归柛顭戝櫘閸ゆ洜绱撴担璐細缂佲檧鍋撻梻浣规偠閸庮垶宕濆鍛瀺闁搞儺鍓氶埛鎴犵磼鐎n偄顕滄繝鈧幍顔剧<閻庯綆鍋呭畷宀€鈧娲忛崹浠嬪箖娴犲宸濆┑鐘插楠炴姊洪悷鏉挎倯闁伙綆浜畷瑙勭節濮橆剛鍘愰梺鍝勬储閸ㄦ椽鎮¢妷锔藉弿婵☆垰鐏濋悡鎰版煟閹捐泛鏋涢柣鎿冨亰瀹曞爼濡烽妷銉バ戠紓鍌欑椤戝牆鐣烽悽鍨潟闁圭儤姊荤壕鍏间繆椤栨繂浜归柣锝堟缁辨挻鎷呴搹鐟扮缂備浇顕ч悧鍡涙偩瀹勯偊娼ㄩ柍褜鍓氭穱濠傤潰瀹€濠冃ㄧ紓鍌欐祰妞村摜鎹㈤崼婵愭綎缂備焦蓱婵绱掑☉姗嗗剰婵炲牊鍔欏娲箹閻愭彃顬嗛梺鍛婎殔閸熷潡鎮鹃悜绛嬫晬闁绘劘灏欐鍥⒑閻熼偊鍤熷┑顕€娼ч埢鎾淬偅閸愨斁鎷虹紓鍌欑劍钃遍柍閿嬪浮閺屽秴鐣¢幍顔尖叺閻庢鍣崑濠傜暦閹烘鍊烽悗鐢登归獮鍫ユ⒒娴g懓鈻曢柡渚囧櫍瀹曟垿骞樼紒妯煎幐闂佸憡渚楅崰姘跺箠閸涱喕绻嗛柛娆忣槸婵洭鎽堕敐澶嬪仩婵炴垶甯掓晶鏌ユ煛閸屾浜鹃梻鍌氬€烽懗鍓佸垝椤栫偛绀夐柡鍥╁€i悢鍝ョ瘈闁搞儜鍐╁劒闂備胶绮弻銊╂儍濠靛缁╅柤鎭掑劘娴滄粓鏌¢崘銊﹀妞ゃ儱顦甸弻娑㈠棘鐠囨祴鍋撳┑瀣闁割偅娲橀崐鐑芥煟閹寸偍缂氶柛姗€浜跺娲传閸曨剙鍋嶉梺鍛婃煥閺堫剟寮查崼鏇ㄦ晬闁绘劕顕崢鍗炩攽閻愬弶顥滅紒缁樺笧缁粯绻濆顓犲幐闁诲繒鍋熼弲顐f櫏闁诲氦顫夊ú锕傚磻婵犲倻鏆﹂柣鏃傗拡閺佸棝鏌嶈閸撴瑩鍩㈠澶嬫櫜闁搞儮鏅濋敍婵囩箾鏉堝墽绋荤憸鏉垮暞缁傚秹鎮欓鍌滅槇闂侀潧楠忕徊鍓ф兜閻愵兙浜滈柟瀛樼箖瀹告繄绱掗鍓у笡闁靛牞缍佸畷姗€鍩¢崘銊ョ闂備浇顕х€涒晝绮欓幒鎴犲箵閻犳亽鍔庢稉宥嗘叏濡炶浜鹃梺鍝勮閸斿矂鍩ユ径濞㈢喐寰勯惂鍝ョɑ闁靛洤瀚版俊鎼佹晲閸涱厼袝闂備浇顕栭崰妤呮偡閳哄懌鈧線寮崼婵堫槹濡炪倖鎸荤换鍕矆閸曨垱鈷掗柛灞剧懄缁佺増銇勯弴鐔哄⒌鐎规洑鍗冲浠嬵敃閵堝浂妲稿┑鐘垫暩婵挳宕愭繝姘辈闁挎洖鍊归悡娆愩亜閺嶎偄浠滃ù婊呭娣囧﹪鎳犳0婵嗘闂佸疇顫夐崹鍧楀春閸曨垰绀冮柕濞у懌鍋″┑锛勫亼閸娿倝宕㈡ィ鍐ㄧ婵☆垯璀﹂崵鏇㈡偣閸ャ劎銈存俊鎻掔墦閺屾洝绠涢弴鐑嗘綌闂佸啿鎼幊蹇涙偂韫囨搩鐔嗛悹楦挎婢ф洟鏌涢弮鈧幐鎶藉蓟濞戙垹妫樻繛鍡欏亾妤旂紓鍌欐祰妞存悂骞愭繝姘闁告侗鍨抽惌娆撳箹鐎涙ɑ灏ù婊堢畺閺屾稑鈹戦崟顐㈠Б闂佹椿鍘介幐楣冨箟閹间焦鍋嬮柛顐g箘閻熴劑姊洪崫鍕靛剮缂佽埖宀稿濠氭偄閻撳海顦悷婊冪箳閺侇喖鈽夐姀锛勫幐闂佸憡渚楅崰妤呭磹閹扮増鐓涢悘鐐额嚙婵倿鏌熼鍝勨偓婵嗙暦閹烘垟妲堟慨妤€妫旂槐锟� ---闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌i幋锝呅撻柛濠傛健閺屻劑寮崼鐔告闂佺ǹ顑嗛幐鍓у垝椤撶偐妲堟俊顖氭惈缁犺鈹戦悙鍙夆枙濞存粍绮撻幃鈥斥槈閵忥紕鍘卞┑鐐村灥瀹曨剟鐛Ο姹囦簻闁哄倹瀵чˉ銏℃叏婵犲懏顏犻柟鐟板婵℃悂濡烽敂鎯х稈闂傚倷鑳堕幊鎾诲吹閺嶎厼绠柨鐕傛嫹
开发学院软件开发Java 消息中介的实用介绍——第 5 部分:中介请求/响应... 阅读

消息中介的实用介绍——第 5 部分:中介请求/响应样式的消息交互

 2009-10-21 00:00:00 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾剧懓顪冪€n亜顒㈡い鎰Г閹便劌顫滈崱妤€骞婄紓鍌氬€瑰銊╁箟缁嬫鍚嬮柛顐線缂冩洟姊婚崒娆戭槮婵犫偓闁秵鎯為幖娣妼缁愭鏌″搴′簽濞戞挸绉甸妵鍕冀椤愵澀娌梺缁樻尪閸庣敻寮婚敐澶婂嵆闁绘劖绁撮崑鎾诲捶椤撴稑浜炬慨妯煎亾鐎氾拷闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾剧懓顪冪€n亝鎹i柣顓炴閵嗘帒顫濋敐鍛婵°倗濮烽崑娑⑺囬悽绋挎瀬闁瑰墽绮崑鎰版煙缂佹ê绗ч柍褜鍓﹂崣鍐潖閸濆嫅褔宕惰娴犲ジ姊虹拠鑼闁煎綊绠栭幃楣冩倻閽樺鎽曢梺闈涱檧婵″洭宕㈤悽鍛娾拺閻熸瑥瀚烽崯蹇涙煕閻樺磭澧甸柕鍡楀€圭缓浠嬪川婵犲嫬骞堥梺纭呭閹活亞妲愰弴鐔哄ⅰ闂傚倷绶氬ḿ褍煤閵堝洠鍋撳顐㈠祮闁绘侗鍣i獮鎺懳旈埀顒傜不閿濆棛绡€闂傚牊绋戦弳娆徝瑰⿰鍫㈢暫闁哄矉缍佹慨鈧柍鎯版硾濠€杈ㄧ珶閺囩喓绡€婵﹩鍘鹃崢鐢告⒑缂佹ê濮﹂柛鎾村哺閹ɑ娼忛妸銈囩畾闂佸湱绮敮鐐存櫠濞戞氨纾肩紓浣贯缚濞插鈧娲栧畷顒冪亙闂佸憡鍔曢崯鐘诲礈濠靛牊宕叉繛鎴炨缚閺嗗棗鈹戦悩杈厡闁轰焦鐗滅槐鎾存媴娴犲鎽甸梺鍦嚀濞层倝鎮鹃悜钘夌闁规惌鍘介崓鐢告⒑閻熸澘鎮侀柣鎺炵畵閹骞栨担鍏夋嫽婵炶揪绲块崕銈夊吹閳ь剟姊洪幖鐐测偓鏍偋閻樿崵宓侀煫鍥ㄧ⊕閺呮悂鏌ㄩ悤鍌涘濠电姷鏁告慨鐑藉极閸涘﹥鍙忛柣鎴f閺嬩線鏌涘☉姗堟敾闁告瑥绻戦妵鍕箻閸楃偟浠肩紓浣哄閸ㄥ爼寮诲☉銏犵疀闂傚牊绋掗悘鍫ユ倵閻熺増鍟炵紒璇插暣婵$敻宕熼姘鳖啋闁诲酣娼ч幗婊堟偩婵傚憡鈷戠痪顓炴媼濞兼劖绻涢懠顒€鏋庢い顐㈢箳缁辨帒螣閼测晜鍤岄梻渚€鈧偛鑻晶顔肩暆閿濆牆鍔垫い锔界叀閹繝濡舵径瀣帾闂佸壊鍋呯换鍐磻椤忓懐绠剧€瑰壊鍠曠花濠氬箚閻斿吋鈷戦悗鍦У閵嗗啴鏌ら崘鑼煟鐎规洘绻堥弫鍐焵椤掑嫧鈧棃宕橀鍢壯囨煕閳╁喚娈橀柣鐔稿姍濮婃椽鎮℃惔鈩冩瘣闂佺粯鐗曢妶绋跨暦閻戞ḿ绡€闁搞儜鍐ㄧギ闂備線娼ф蹇曟閺囥垹鍌ㄦい蹇撶墛閳锋垿鏌熼懖鈺佷粶闁告梹顨婇弻锟犲川椤旈敮濮囩紓浣稿€圭敮鐔妓囩€靛摜纾奸弶鍫涘妼缁楁碍绻涢悡搴g闁糕斁鍓濋幏鍛存煥鐎e灚缍楅梻鍌氬€峰ù鍥ь浖閵娾晜鍊块柨鏇炲€哥粻鏌ユ煕閵夘喖澧柡瀣╃窔閺岀喖宕滆鐢盯鏌¢崨顔藉€愰柡灞诲姂閹倝宕掑☉姗嗕紦闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾剧懓顪冪€n亜顒㈡い鎰Г閹便劌顫滈崱妤€骞婄紓鍌氬€瑰銊╁箟缁嬫鍚嬮柛顐線缂冩洟姊婚崒娆戭槮婵犫偓闁秵鎯為幖娣妼缁愭鏌″搴′簽濞戞挸绉甸妵鍕冀椤愵澀娌梺缁樻尪閸庣敻寮婚敐澶婂嵆闁绘劖绁撮崑鎾诲捶椤撴稑浜炬慨妯煎亾鐎氾拷  闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌i幋锝呅撻柛銈呭閺屻倝宕妷锔芥瘎婵炲濮靛銊ф閹捐纾兼繛鍡樺笒閸橈紕绱撴笟鍥ф珮闁搞劌鐖兼俊鎾礃椤旂厧绐涢梺鍝勵槹閸ㄥ綊宕㈠ú顏呭€垫鐐茬仢閸旀碍銇勯敂璇茬仸鐎规洩绻濋獮搴ㄦ嚍閵壯冨妇闂傚⿴鍋勫ú锕€煤閺嶃劎澧¢梻鍌欐祰椤曆呪偓鍨浮瀹曟粓鎮㈡總澶嬬稁闂佹儳绻愬﹢杈╁閸忛棿绻嗘い鏍ㄧ閹牊銇勯銏㈢劯婵﹨娅i幏鐘绘嚑椤掑偆鍞规繝娈垮枟鑿ч柛鏃€鍨垮畷娲焵椤掍降浜滈柟鍝勭Ф椤︼箓鏌涢妶搴″⒋闁哄本鐩獮妯兼崉閻戞ḿ鈧顪冮妶搴′簻缂佺粯鍔楅崣鍛渻閵堝懐绠伴悗姘煎墴閹顢橀悜鍡樺瘜闂侀潧鐗嗗Λ娆戠矆閳ь剟姊洪悷鏉挎毐闂佸府绲介悾宄扳堪閸曨偒鍤ら柣搴㈢⊕鑿ら柟閿嬫そ濮婄粯绗熼崶褌绨介梺绋款儐閻╊垶骞婇悢纰辨晬婵炴垶鐟﹂悵宄邦渻閵堝棙鐓ュ褏鏅竟鏇㈡偂鎼搭喚鍞甸柣鐘烘鐏忋劑宕濋悢铏圭<濠㈣泛瀛╅鐘绘煃瑜滈崜姘额敊閺嶎厼绐楅柡宥庡幐閳ь剨绠撻弻銊р偓锝傛櫇缁犳艾鈹戦鐣岀畵闁活厼鐗嗗嵄闁绘垼濮ら埛鎴犵磼鐎n偒鍎ラ柛搴㈠姍閺岀喖鎮烽悧鍫熸倷闁捐崵鍋ら弻娑㈠箛閳轰礁唯濠碘剝褰冮悧濠勬崲濞戙垹骞㈡俊銈呭暟椤斿鈹戦悙鑼闁挎洏鍨归~蹇曠磼濡顎撴俊鐐差儏缁ㄨ偐鎲伴崱娆戠=闁稿本姘ㄨⅵ闂佺ǹ顑嗛幐鑽ゆ崲濞戞埃鍋撳☉娆嬬細闁活厹鍊濋弻娑㈠箻鐠虹儤鐏堥悗瑙勬礃濡炰粙宕洪埀顒併亜閹哄秹妾峰ù婊勭矒閺岀喖鎮滃Ο铏逛淮闂侀€炲苯澧紓宥咃工椤曪綁骞庣粵瀣櫌闂佸憡娲﹂崜娑㈠储闁秵鐓熼幖鎼灣缁夐潧霉濠婂懎鍘撮柣鎿冨墴椤㈡宕掑Δ鈧禍楣冩偡濞嗗繐顏痪鎯ь煼閺屾稑螖閳ь剟宕崸妤婃晪闁挎繂顦壕褰掓煟閺囨氨鍔嶉棄瀣⒒閸屾瑧顦﹂柟纰卞亜铻為悗闈涙憸娑撳秹鏌熼幑鎰靛殭闁藉啰鍠栭弻鏇熺箾閻愵剚鐝曢梺绋款儏濡繈寮诲☉姘勃闁告挆鈧Σ鍫濐渻閵堝懘鐛滈柟鍑ゆ嫹
核心提示:引言如果阅读过本系列中的前几篇文章,那么将熟悉如何创建和使用消息中介,消息中介的实用介绍——第 5 部分:中介请求/响应样式的消息交互,消息中介是对 IBM WebSphere Application Server V6 的消息传递功能的一种新的编程扩展,可以简化使用消息传递的系统、服务、应用程序或组件之间的连接,需要

引言

如果阅读过本系列中的前几篇文章,那么将熟悉如何创建和使用消息中介,消息中介是对 IBM WebSphere Application Server V6 的消息传递功能的一种新的编程扩展,可以简化使用消息传递的系统、服务、应用程序或组件之间的连接。这几篇文章以及 IBM 的同事最近撰写的其他一些文章,都主要关注单向的消息传递模式。然而,也常常为 Java™ Messaging Service (JMS) 和其他的应用程序实现请求/响应样式的语义。JMS 规范甚至提供了 QueueRequestor 和 TopicRequestor 类来简化这种动态的消息传递。在本系列的第 5 部分中,我们将介绍如何使用消息中介来处理请求/响应消息。

考虑到本文的目的,我们将看到的应用程序示例是一个库存管理系统,它将发送查询以确定仓库中某种产品的存货数量。将在响应中发送应答该查询的信息。本文重用了为第 4 部分:通过中介和 XSLT 修改消息编写的中介。

中介回顾

让我们先来回顾一下 WebSphere Application Server 的上下文中,中介和消息格式的含义。

中介处理程序是与消息传递目的地相关联的一个 Java 类,在向该目的地发送消息的时候将调用其中介方法。中介处理程序可以修改、重新路由或甚至删除该消息。

有几种类别的消息可以传递给中介处理程序。中介处理程序通过使用 getFormat 方法获取消息格式,以确定传递给它是何种类别的消息。该格式的可能的取值包括:

格式描述
JMS:byte包含字节数组的 JMS 消息。
JMS:text包含字符串的 JMS 消息。
JMS:object包含使用 java.io.ObjectInputStream 可将其反序列化为对象的字节数组的 JMS 消息。
JMS:stream包含类型化数据流的 JMS 消息。
JMS:无内容的 JMS 消息(通过构造一个 javax.jms.Message 对象而不是任何特定的 JMS 消息类型来创建)。
SOAP:往返 Web 服务的 SOAP 消息。
Bean:往返 Web 服务的消息。

消息传递中的请求/响应处理

消息传递提供者通常并不提供对请求/响应消息传递的直接支持,但是有三种经常使用的常规方法:

使用临时应答队列。在这种模型中,请求者创建了一个临时目的地,将响应目的地的地址放入请求消息中,然后发送该消息。然后响应者将响应发送到这个目的地。JMS 应用程序常常使用这种模型,并且该模型的缺点是将单个请求与响应关联起来,每个请求都需要使用一个临时目的地。要解决这种限制,通常为每个客户端使用单独的临时目的地,然后使用后面的两个要点中所描述的机制来关联单个请求和响应。

将 Message ID 复制到 Correlation ID。 在这种模型中,发出请求的应用程序在一个已知的队列上侦听响应。要么请求者和响应者都知道这个队列,要么请求者在请求消息中指定应答发送到何处。然后,做出响应的应用程序将该请求的消息 ID 复制到响应的相关 ID。请求者随后使用相关 ID 中的内容对响应进行筛选。服务集成总线中的入站、出站和网关服务函数使用了这种模型。WebSphere MQ 应用程序也常常使用它。

将 Correlation ID 复制到 Correlation ID。除了请求者在请求消息中添加了一个相关 ID 之外,这种模型和前面的模型是相同的。然后,响应者将请求消息的相关 ID 复制到响应消息的相关 ID。WebSphere MQ 应用程序常使用这种模型。

总线中的请求/响应处理

总线本身并不具有对请求/响应处理的直接支持,但它为方便地构建请求/响应处理提供了支持。

每个消息都包含了在其通过总线时应该访问的目的地列表(或路径)。这就是转发路由路径,并且通常将发送带有包括单个目的地的路径的请求消息。另外,可以使用缺省转发路由路径对目的地进行配置,如果到达目的地的请求消息没有转发路由路径,那么该缺省转发路由路径将放入到其中。

消息中还包含了一条反向路由路径。尽管在消息通过总线时不会对它进行处理,但该路径通常来自于请求消息并设置为响应消息的转发路由路径。在这种方式中,响应消息在其通过总线时所使用的路由可以受到请求消息处理的影响。

如果要求响应,那么请求消息将设置反向路由路径。每个目的地可以指定一个应答目的地。在消息经过该目的地时,将为反向路由路径(如果已经存在一项)预先计划这个目的地。

通过中介传递请求/响应消息

作为一条通用规则,在总线中通过中介传递请求/响应消息交互并不比通过中介传递单向消息困难多少。如果需要通过中介对请求消息进行传递,在响应路径上可能需要某种形式的中介。一个简单的例子是将消息从 COBOL Copybook 转换为 XML,如果响应者只能理解 XML,而请求者只能理解 COBOL,那么请求和响应消息都需要进行转换。

当通过中介传递请求消息时,如果需要,响应中介可以应用许多方式:

创建可以区分消息是请求还是响应的中介,并进行适当的操作。可以将中介所应用的目的地添加到请求消息的反向路由路径。这就意味着,响应消息将通过中介目的地返回。

创建两个可以创建的中介:一个请求中介和一个响应中介。它们分别应用于两个不同的目的地。请求消息使用一个,而响应消息使用另一个。请求消息可以只需将请求中介的目的地添加到反向路由路径,或者只需应用应答目的地的反向中介。

创建不能区别差别的单个中介。在这种情况下,可以对请求和响应路径应用同一个中介,并执行相同的逻辑,但是不能够根据它所部署的目的地来进行参数化。

这些方法中最简单的实现是最后一种,而最复杂的是第一种。通过利用目的地的应答目的地字段,请求中介不需要做任何事情就可以将响应路由到其伙伴响应目的地。这在使用一般中介(比如 XSLT 中介,需要应用它来对请求和响应分别执行不同的 XSLT 中介)时特别有用。

设计决定

为应用程序和环境选择适当的请求/响应模型是非常重要的。考虑到本文的目的,我们将使用上面列出的第一种和第二种模型的组合形式。在我们的模型中,客户端将为所有的请求创建一个临时目的地,并通过将消息 ID 复制到相关 ID,建立单个请求和响应之间的关联。

我们将浏览一个比较简单的请求/响应中介的示例,介绍如何在无需编写任何代码的前提下执行它。红皮书 Patterns:SOA with an Enterprise Service Bus in WebSphere Application Server V6 提供了关于聚合和分解消息的复杂示例的详细信息。

该示例将利用一个简单的 JMS 应用程序来提供提出请求的客户端和做出响应的服务。它可能出现在现实的解决方案中,其中响应应用程序是与客户端应用程序不同的某种形式的企业应用程序。

JMS 请求消息

JMS 应用程序使用清单 1 所示的 XML 向 requestQueue 发送 JMS BytesMessage。


清单 1. JMS 客户端生成的示例 XML 文档
 <?xml version="1.0" encoding="utf-8"?> 
 <stockQuery> 
  <item number="1234"/> 
 </stockQuery> 

JMS 应用程序的响应部分需要清单 2 所示格式的 XML。


清单 2. 响应 JMS 应用程序所需的示例 XML 文档
 <?xml version="1.0" encoding="utf-8"?> 
 <stockQuery> 
  <item>1234</item> 
 </stockQuery> 

需要在请求消息到达响应应用程序之前对其进行转换。清单 3 中所示的 XSLT 将执行该转换任务。


清单 3. 用来转换两个请求 XML 文档的 XSLT
 <?xml version="1.0" encoding="utf-8"?> 
 <stockQuery xmlns:xslt="http://www.w3.org/1999/XSL/Transform"> 
  <item><xslt:value-of select="/stockQuery/item/@number"/></item> 
 </stockQuery> 

JMS 响应消息

响应 JMS 应用程序在 JMS BytesMessage 中向请求消息中指定的 JMSReplyTo 发送响应。它把清单 4 所示的 XML 放入到响应消息中。


清单 4. 响应应用程序生成的示例 XML 文件
 <?xml version="1.0" encoding="utf-8"?> 
 <stockAvailability> 
  <quantity>2</quantity> 
 </stockAvailability> 

JMS 应用程序客户端部分需要清单 5 所示格式的 XML。


清单 5. 请求应用程序所需的示例 XML 文档
 <?xml version="1.0" encoding="utf-8"?> 
 <stockAvailability> 
  <item quantity="2"/> 
 </stockAvailability> 

需要在响应消息到达客户端应用程序之前对其进行转换。清单 6 所示的 XSLT 将执行该转换任务。


清单 6. 用来转换两个响应 XML 文档的 XSLT
 <?xml version="1.0" encoding="utf-8"?> 
 <stockAvailability xmlns:xslt="http://www.w3.org/1999/XSL/Transform"> 
  <item><xslt:attribute name="quantity"><xslt:value-of select="/stockAvailability/quantity"/> 
  </xslt:attribute></item> 
 </stockAvailability>

当然,该示例比较简单,而在现实应用程序中需要进行更有价值的转换任务。例如,在请求上将 SOAP 转换为 COBOL Copybook,而在响应上则将 COBOL Copybook 转换为 SOAP。

简单的请求/响应中介

这里,我们将展示如何构建请求/响应中介,尤其是如何能够在不需要编写任何代码的情况下构建这些中介。

初始配置

该示例需要创建某些资源,只需使用下载资料中所包含的 createInitialResources.jacl 脚本即可完成这项工作。该脚本将创建这些表格中列出的资源:

将创建具有单个总线成员的总线:

创建总线时的常见错误
在创建总线时(特别是在非联合应用程序服务器上),常常会忘记添加一个总线成员。我总是犯这个错误。

字段
名称dwBus

将在不同的对象中创建两个队列类型的目的地:

字段
标识符dwRequestQueue
标识符dwResponseQueue

单个中介:

好的做法
无论在什么地方,对中介和处理程序列表名都使用相同名称。这样可以避免在调试中介的消息流时出现过多的混淆。

字段
名称dwXSLTMediation
中介处理程序列表名dwXSLTMediation

然后通过 dwXSLTMediation 传递发送到目的地 dwRequestQueue 和 dwResponseQueue 的消息。

对于提供的 JMS 应用程序,将使用缺省消息传递提供者来定义下面的 JMS 资源。

JMS 连接工厂 (connection factory):

字段
名称dwCF
JNDI 名称jms/dw/CF
总线名称dwBus

JMS 队列:

字段
名称dwDest
JNDI 名称jms/dw/dest
总线名称dwBus
队列名称dwRequestQueue

为请求/响应处理进行配置

我们现在已经设置了初始配置,这使得我们可以修改并启用请求/响应处理。(要创建这些基本资源,请参阅本系列中的前几篇文章,如参考资料中所列。)

第一项更改是设置请求目的地上的应答目的地名称:

在 WebSphere Application Server 管理控制台中,展开 Service integration => Buses。

选择总线 dwBus。

在 Destination Resources 下选择 Destinations。

选择目的地 dwRequestQueue。

向下滚动直至可以看到 Reply destination 字段,并如图 1 所示输入 dwResponseQueue。

图 1. 配置应答目的地
消息中介的实用介绍——第 5 部分:中介请求/响应样式的消息交互

单击 OK。

配置上下文属性时的常见错误
在配置上下文属性时,常常没有指定上下文的类型。如果设置了不正确的上下文类型,那么要么数据对中介而言不可用,要么它的类型不正确(导致 ClassCastException)。将会出现哪一种情况,取决与其不匹配的程度。

下一步是配置 XSLT 中介,以使它应用正确的转换任务。可以通过中介传递上下文属性或者目的地上下文属性来指定中介所应用的 XSLT。可以在目的地或中介上的管理控制台中设置这些属性。然后,它们将作为属性放入到 SIMediationContext 中。对于本示例,对两个不同的目的地(其中每个目的地需要应用不同的 XSLT)应用了相同的中介。这意味着,目的地上下文属性是指定该信息的适当的位置。

在管理控制台中,展开 Service integration => Buses。

选择总线 dwBus。

在 Destination Resources 下选择 Destinations。

选择目的地 dwRequestQueue。

选择链接 Context Properties。

单击 New。

输入或选择下面的值(图 2):

名称: Stylesheet

上下文类型: 字符串

上下文值: <?xml version="1.0" encoding="utf-8"?><stockQuery xmlns:xslt="http://www.w3.org/1999/XSL/Transform"><item><xslt:value-of select="/stockQuery/item@number"/></item></stockQuery>


图 2. 配置请求中介 XSLT
消息中介的实用介绍——第 5 部分:中介请求/响应样式的消息交互

图片看不清楚?请点击这里查看原图(大图)。

对于指定第二个 XSLT 的响应目的地,也需要完成这项任务。

在管理控制台中,展开 Service integration => Buses。

选择总线 dwBus。

在 Destination Resources 下,单击 Destinations。

选择目的地 dwResponseQueue。

选择链接 Context Properties。

单击 New。

输入或选择下面的值(图 3):

名称: Stylesheet

上下文类型: 字符串

上下文值: <?xml version="1.0" encoding="utf-8"?><stockAvailability xmlns:xslt="http://www.w3.org/1999/XSL/Transform"><item><xslt:attribute name="quantity"><xslt:value-of select="/stockAvailability/quantity"/></xslt:attribute></item></stockAvailability>


图 3. 配置响应中介 XSLT
消息中介的实用介绍——第 5 部分:中介请求/响应样式的消息交互

图片看不清楚?请点击这里查看原图(大图)。

XSLT 中介

该应用程序中使用的 XSLT 中介对前面的文章中提供的中介(在消息的副本上执行 XSLT)稍微进行了一些改进。本示例中使用的中介对要通过中介传递的消息执行 XSLT。用清单 7 所示的代码替换 XSLTMediationHandler 类中 innerHandle 方法的代码。该中介存储于 MediationPart5MediationEAR.ear 文件中,也包括在下载资料中,并且需要安装到服务器中。


清单 7. 经过修改的 innerHandle 方法的内容
  // Retrieve the message from the context 
  SIMessage message = getContext().getSIMessage(); 
  // Get the message contents in the form of a JMS Bytes message 
  try 
  { 
   // Get a new datagraph for the new message we're about to build - Point 1 
   DataGraph graph = message.getNewDataGraph(SIApiConstants.JMS_FORMAT_BYTES); 
   DataObject body = graph.getRootObject(); 
   if (body.isSet("data")) 
   { 
    // Grab the bytes 
    byte[] payload = body.getBytes("data/value"); 
    // Transform the bytes 
    payload = XSLTTransform.transform(payload,getStringProperty(STYLESHEET_PROPERTY_NAME)); 
    // Replace the payload in the data graph 
    body.setBytes("data/value",payload); 
    message.setDataGraph(graph, SIApiConstants.JMS_FORMAT_BYTES); 
   } 
   else 
   { 
    // No bytes sent, so throw an IllegalArgument so that the message 
    // will be sent to the exception destination 
    IllegalArgumentException e = new IllegalArgumentException("No body to the message"); 
    throw e; 
   } 
  } 
  catch(Exception e) 
  { 
   // Hmm, we had a problem somewhere doing the transformation or maybe the send 
   e.printStackTrace(); 
   throw new MessageContextException(e); 
  } 
  // If we get here, everything worked and the tracking message has been sent 
  return true; 

运行测试应用程序

关于 JMS BytesMessage 的警告
在发送包含 XML 数据的 JMS BytesMessage 时,请避免使用所提供的 writeUTF 方法,因为这种 UTF 编码添加了额外的数据,那么消息将不以字符串中的第一个字符开头。因此,在读取中介中的字符串时必须加以小心。(我们的示例并没有使用这个方法。)

在运行应用程序之前,保存配置并重启该应用服务器是非常重要的。在完成该任务后,通过执行这个命令来运行示例应用程序:launchClient.bat MediationPart5ClientEAR.ear 5。这将出现图 8 所示的输出。

该测试应用程序是一个简单的 JMS 应用程序,它同时扮演了客户端和服务器,并且使用单个数值作为参数。


清单 8. 运行测试应用程序得到的输出
IBM WebSphere Application Server, Release 6.0 
J2EE Application Client Tool 
Copyright IBM Corp., 1997-2004 
WSCL0012I: Processing command line arguments. 
WSCL0013I: Initializing the J2EE Application Client Environment. 
WSCL0035I: Initialization of the J2EE Application Client Environment has completed. 
WSCL0014I: Invoking the Application Client class mediation.messages.part5.Main 
Sending request message: <?xml version="1.0" encoding="utf-8"?> 
<stockQuery> 
 <item number="5" /> 
</stockQuery> 
Received request message:<?xml version="1.0" encoding="UTF-8"?><stockQuery><item>5</item></stockQuery> 
Sending response message: <?xml version="1.0" encoding="utf-8"?> 
<stockAvailability> 
 <quantity>2</quantity> 
</stockAvailability> 
Received response message: <?xml version="1.0" encoding="UTF-8"?> 
 <stockAvailability><item quantity="2"/></stockAvailability>

关联请求和响应

到目前为止,我们已经讨论了一种简单的情况,其中响应所采取的操作仅依赖于响应消息的内容。然而在很多情况下不可能如此,比如,假设将请求消息发送到总线,并通过中介对其进行传递,然后传输到 WebSphere MQ 队列管理器。在这种情况下,不可能对反向路由路径进行维护,但是对于总线正确地处理响应而言这却是必需的。另一个示例是聚合和分解消息:如果将单个消息分解为几个消息,并且所需要的是单个消息,那么在接收到所有的消息时必须确定它。

在这些情况下,需要存储关于请求消息的附加信息,以使响应中介能够看到它。这就称为关联。存储该关联信息有两种简单的方法,使得它能够在中介中进行使用。

使用数据库。

使用附加队列。

这两种机制都很常用,其中哪一个更好,则依赖于消息交互的详细信息。

使用附加队列的关联

对于存储数据而言,附加队列是一种简单、快捷并且有效的机制,并且它具有以下优点:

简化管理任务。

中介 API 为发送和接收消息提供了各种机制。

如果使用事务,将使一阶段 (one-phase ) 优化成为可能。

总线可以在数据不再有效时自动地对其进行过期处理。

使用附加队列具有以下缺点:

消息选择的性能不及数据库 SQL 选择,特别是在队列中有大量消息的时候。

当通过多个消息传递引擎将附加队列限定为集群总线 (clustered bus) 成员时,应该多加小心,必须确保关联信息位于响应中介访问的队列点。

使用数据库的关联

数据库是存储数据的功能强大的机制,它具有如下优点:

关联信息可以很容易地在应用程序之间共享。

如果存储了大量关联数据,数据库应该具有更高的伸缩性。

如果消息吞吐量高,数据库应该具有更高的伸缩性。

使用数据库具有以下缺点:

对于丢失了的响应需要某种旧数据的过期机制。

当使用事务时,需要使用两阶段 (two-phase) 提交。

与附加队列相比,需要进行更多的配置工作。

结束语

本文详述了如何使用 WebSphere Application Server V6 扩展的消息传递功能来通过中介传递请求/响应消息,并且讨论了关联请求和响应中涉及到的一些更高级的问题。

本文示例源代码或素材下载

Tags:消息 中介 实用

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