锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
]]>
浣嗘槸鏈変簺鏃跺橨SF鐨勪嬌鐢ㄨ繕鏄笉鏄崄鍒嗘柟渚? 灝ゅ叾鏄浜庡垵瀛﹁呰岃█, 甯稿父琚竴浜涜帿鏄庡叾濡欑殑闂鎼炲緱鏅曞ご杞悜.
鐩鎬俊寰堝鍒濆鑰呴兘瑙佸埌榪囪繖涓狤xception鍚?
涓ラ噸: Servlet.service() for servlet jsp threw exception
javax.servlet.jsp.JspException: Cannot find FacesContext
褰撴垜鍦ㄥ涔燡SF鐨勬椂鍊?鐪嬪埌榪欎釜Exception鎴戞壘浜嗗崐澶╅兘娌℃湁鍙戠幇鎴戠殑浠g爜鍝噷閿欎簡(浠g爜涓嶅彲鑳藉嚭閿?鍥犱負鏄洿鎺opy鐨勪功涓殑婧愪唬鐮?鍛靛懙), 鍚庢潵涓嶇粡鎰忛棿鎵嶅彂鐜板師鏉ヨ闂〉闈㈢殑URL閿欎簡, 鍦↗SF閰嶇疆鏂囦歡涓厤緗殑servlet鏄犲皠涓?jsf,鎵浠ヨ闂殑URL搴旇鏄?.... index.jsf, 鑰屼笉鏄?... index.jsp., 灝辮繖涔堜竴鐐圭枏蹇藉氨璁╀漢鐧藉繖媧諱簡鍗婂ぉ. 閮侀椃鍝?
闅忕潃瀛︿範鐨勬繁鍏?榪欑鍩烘湰閿欒鏄緢灝戝啀鍑虹幇浜?灝辯畻鍑虹幇涔熷彲浠ラ┈涓婄煡閬撻棶棰樼殑鏍規湰), 浣嗘槸JSF鍏朵粬鐨勪竴浜涢檺鍒跺張鏄浜烘劅鍒板緢閮侀椃鐨? 姣斿 Form鏁版嵁鐨勬彁浜? JSF瑙勮寖涓負浜嗙淮鎶ゆ湇鍔$鐨勭粍浠舵爲 鍙兘浣跨敤Post鎻愪氦, 鑰屼笉鍙互浣跨敤Get. 鑰孏et鏂規硶鍦ㄥ緢澶氬湴鏂硅繕鏄潪甯告湁鐢ㄧ殑.
鍙﹀榪樻湁Faces API浣跨敤璧鋒潵涓嶆槸鍗佸垎鐩存帴鐨勯棶棰? 瑕佹妸涓涓暟鎹斁鍏ュ埌session涓氨瑕佷竴澶т覆鐨勬搷浣? FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(name, val); ),璁╀漢鎰熻寰堜笉鐖?
....
濡傛灉浣犵粡甯擱亣鍒拌繖浜涢棶棰? 閭d箞鐜板湪鎴戝皢鍛婅瘔浣犱竴涓ソ娑堟伅, 鏈変簡Frails 榪欎簺闂閮藉彲浠ヨ交鑰屾槗涓劇殑瑙e喅浜?
鎴戜滑鍏堟潵鐪嬬湅Frails鏄粈涔?
鍦‵rails涓婚〉涓婂畾涔?http://frails.hexiao.cn/what-is-frails.html
what is frails?
Frails 鏄熀浜嶫SF涓婄殑涓涓紑鍙戞晥鐜囧拰RoR鍙互鍚戝緹庣殑JavaEE妗嗘灦 !
Ruby On Rails(RoR)鍥犱負鍦ㄥ紑鍙憌eb紼嬪簭鐨勯珮鏁堟ц岄琛屼竴鏃?鍙兘鐜板湪浠嶇劧寰堢儹), 閭d簺RoR鐨勬敮鎸佽呰, RoR鍙互姣攋ava鐨勫紑鍙戞晥鐜囬珮鍑?0鍊嶄互涓?鎴戜滑瀵規瑙傜偣鎸佹鐤戠殑鎬佸害. 鎴戜滑鐩鎬俊,濡傛灉鏈夋紜殑寮鍙戞柟娉曟潵鏀寔鐜板湪鐨凧ava web framework,鍒?Java web寮鍙戠殑鏁堢巼 涓嶄細濡傛鐨勪綆涓?鎵浠?鎴戜滑鐮旂┒浜嗕竴涓婻oR鐨勫疄鐜版満鍒?鏉ュ疄鐜版垜浠琂ava妗嗘灦涓殑RoR. 鍥犳, 鎴戜滑鎻愪緵涓涓湪寮鍙戞晥鐜囦笂鍜孯oR鍙互濯茬編鐨凧avaEE寮鍙戞鏋?-- Frails !
鐭ラ亾浜咶rails鏄粈涔堝悗, 鎴戜滑鍐嶆潵鐪嬬湅Frails鏈変粈涔堢壒鎬? 鑳界粰JSF甯︽潵浠涔堝姛鑳戒笂鐨勫寮?
鍦‵rails涓婚〉涓婂垪涓句簡Frails鐨勫涓嬩富瑕佺壒鎬? http://frails.hexiao.cn/frails-features.html
Frails(Java Server Faces On Rails)鍩轟簬Java Server Faces (JSF),騫跺皢鎻愪緵瀵?Hibernate鍜孲pring鐨勬敮鎸? 涓昏鐗瑰緛濡備笅:
Frails 璁╁紑鍙戣呬嬌鐢ㄧ害瀹?涔犳儻)鍜屾敞瑙?annotations)鏉ョ渷鐣ュ湪 faces-config.xml 鏂囦歡涓?managed-bean 鍜?navigation-rule鐨勯厤緗?
Frails 鎻愪緵涓涓洿綆鍗曠殑鏂規硶鏉ヤ嬌鐢?Faces API.
Frails 閲嶅畾鍚戦潪 faces 璇鋒眰涓轟竴涓?faces 璇鋒眰,榪欐牱鍙互閬垮厤鍥犱負URL杈撳叆鐨勭枏蹇藉鑷寸殑寮傚父.
Frails 鎻愪緵涓浜涢瀹氫箟鐨?Managed Bean 鍩虹被璁╁紑鍙戣呮墿灞?.
Frails 鍙互璁╁紑鍙戣呭湪 Managed Bean 涓嬌鐢ㄦ敞瑙?Annotation)鏉ユ敮鎸丄OP鍔熻兘 ,濡?鍑芥暟鎷︽埅(method interception).
Frails 鎻愪緵 Managed Bean 灞炴х殑injection 鍜?outjection
Frails 涓殑Hibernate GenericDao 瀵硅薄鎻愪緵浜嗗熀鏈殑 CRUD 鍑芥暟 鍜?鍏朵粬涓浜涙湁鐢?甯哥敤)鐨勬暟鎹闂嚱鏁?
Frails 榪樻彁渚涗簡涓浜涙湁鐢ㄧ殑娉ㄨВ(annotations)鏉ョ畝鍖朖SF鐨勫紑鍙?
Frails 瀹屽叏鏀寔 jsf 1.1 鍜?jsf 1.2 瑙勮寖,騫朵笖鍙互鑷姩鐨勬帰嫻嬩綘浣跨敤鐨勭増鏈?
Frails 鎻愪緵浜嗗action Method 鍜?Listener 鍑芥暟鐨勫寮?鍦ㄨ繖浜涘嚱鏁頒腑鐜板湪浣犲彲浠ヤ紶閫掑弬鏁頒簡.
鐭ラ亾榪欒繖涔堝Frails鐨勪笢涓? 閭d箞浣犱笉紱佽闂?濡備綍浣跨敤Frails鍛?
榪欎釜鏄緢綆鍗曠殑. 聽 浣犲彧闇瑕佸湪web.xml鏂囦歡涓坊鍔犱笅闈㈢殑閰嶇疆:
<filter>
<filter-name>FacesFilter</filter-name>
<filter-class>net.sf.frails.filters.FacesFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FacesFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
鐒跺悗鎶婁綘涓嬭澆鐨刦rails4jsf1.X.jar 鏀懼埌綾昏礬寰勪腑灝卞彲浠ヤ嬌鐢ㄤ簡.
鐜板湪鍙互浣跨敤浜? 浣犱笉紱佽闂? 濡傛灉鍦ㄤ嬌鐢ㄨ繃紼嬩腑鎴戦亣鍒頒簡闂, 瑕佸埌鍝噷寰楀埌甯姪鍛?濡傛灉鎴戞湁濂界殑Frails鏀硅繘寤鴻瑕佸埌鍝噷鎻愯鍛?
鍏充簬frails鐨勬湇鍔¢棶棰? 浣犲彲浠ュ埌JavaCafe http://www.hexiao.cn/jsf/ 璁哄潧鐨凢rails涓撳尯涓彇寰楀府鍔?
ok, 榪欐Frails 綆浠嬪氨鍏堝埌榪欓噷, 甯屾湜Frails鑳藉湪浣犲紑鍙慗ava web app鏃剁粰浣犲甫鏉ヤ竴涓濇竻鐖?
璧勬簮:
Frails鑻辨枃涓婚〉 http://frails.sf.net
Frails涓枃涓婚〉 http://frails.hexiao.cn
Frails涓枃璁哄潧 http://www.hexiao.cn/jsf
]]>
"Unableto create the selected preference page
Reason:
Plug-inorg.Maven.ide.eclipsewasunabletoloadclass
org.maven.ide.eclipse.preferences.Maven2PreferencePage"
緇忚繃澶氭柟鏌ユ壘璧勬枡鍙戠幇, 鍏堝畨瑁?.0.5 鐒跺悗鍗囩駭灝卞彲浠ヨВ鍐寵闂浜?
涓嶇煡閬撲負浠涔堣榪欎箞楹葷儲,
]]>
涓婇潰鐨勬枃绔犱粙緇嶇殑姣旇緝璇︾粏, 涔熸槸jsf鐨勪竴涓猘jax鎵╁睍欏圭洰, 鍏跺疄瀵逛簬浣跨敤myfaces鐨勭敤鎴鋒潵璇磋繕鏈変釜鏇寸殑閫夋嫨:浣跨敤MyFaces Sandbox 涓殑聽InputSuggestAjax聽聽
http://myfaces.apache.org/sandbox/inputSuggestAjax.html聽
鐢ㄦ硶濡備笅:
1.鍒涘緩涓涓猰anaged bean:
package test;
import java.util.ArrayList;
import java.util.List;
public class Bean {聽聽聽聽
聽聽聽聽聽聽聽聽聽聽聽 //In that function all what you had to do is to
聽聽聽聽聽聽聽聽聽聽聽 //Specify what will be displayed in the list
聽聽聽聽聽聽聽聽聽聽聽 //Note that the keyword is the text entered by the user
聽聽聽聽聽聽聽聽聽聽聽 public List getSuggestedWords(String keyword) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 List list = new ArrayList();
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 list.add(keyword + " Ahmed Saleh");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 list.add(keyword + " Kahki");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 list.add(keyword + " Kourany");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 list.add(keyword + " Kiki");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 list.add(keyword + " Saleh Abouetta");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 list.add(keyword + " Hashim");
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return list;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 public String getCurrentValue() {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return currentValue;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 public void setCurrentValue(String currentValue) {
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 this.currentValue = currentValue;
聽聽聽聽聽聽聽聽聽聽聽 }
聽聽聽聽聽聽聽聽聽聽聽 String currentValue;
}
2.聽聽聽聽 jsp 欏甸潰浠g爜
<%@ taglib uri="
<%@ taglib uri="
<%@ taglib uri="
<html> <head> <title>Ajax JSF sample (InputSuggestAjax)</title> </head> <body> <f:view> 聽<h:form> 聽 <h:outputText value="Enter your name : "/> 聽聽 <s:inputSuggestAjax suggestedItemsMethod="#{bean.getSuggestedWords}" 聽聽聽 value="#{bean.currentValue}" /> 聽聽 <br /> 聽聽 <h:commandButton action="" value="Submit"/> 聽聽 <br /> 聽聽 <h:outputText value="Your name is #{bean.currentValue}"/> 聽</h:form> </f:view> </body>聽聽聽聽 </html>聽 聽3.聽 web.xml閰嶇疆 <context-param> 聽 <param-name>javax.faces.STATE_SAVING_METHOD</param-name> 聽 <param-value>client</param-value> </context-param> //Instead of server make the state saving method on the client to make it works 聽4. 杈撳嚭欏甸潰: 鐗堟湰涓郝?聽1.1.4 紺轟緥浠g爜鎻愪緵Hazem聽http://bbs.hexiao.cn/聽 濡傛灉浣犱笉鎯崇湅鍒拌寮傚父, 涔熶笉鎯充繚瀛榮ession. 閭d箞浣犲彲浠ュ湪欏圭洰閮ㄧ講鎻忚堪鏂囦歡涓?濡? test.xml,)(instead of just exploding the war)聽 鐨?聽<Context> tags涓棿 鍔犱笂聽:
聽 璇曡瘯鐪? 緲昏瘧:icess http://blog.matrix.org.cn/page/icess聽璁ㄨ 濡傛灉浣犲惉璇磋繃聽GWT,閭d箞浣犱竴瀹氫篃鍚榪囧畠鐨勪竴涓牳蹇冪壒鎬у氨鏄?AJAX聽鏀寔.鍦?GWT涓? the "X" part,鍦ㄥ鎴風鍜屾湇鍔″櫒绔潵鍥炰紶閫掓暟鎹? 璇ュ姛鑳芥槸閫氳繃RPC (Remote Procedure Call) 鏈哄埗瀹炵幇鐨勮屼笉鏄嬌鐢?XMLHttpRequest object. 涓嶇榪欎簺,浣犳兂鍦ㄦ湇鍔″櫒绔仛浠涔堟槸鏈変綘鍐沖畾鐨? Google縐板畠涓?Server Agnostic". 璁╂垜浠湅鐪嬪浣曟坊鍔?AJAX聽鏂瑰紡鐨勫紓姝ラ氫俊鍒版垜浠殑紼嬪簭涓? 鍦ㄤ笅涓樁孌典腑,鎴戜滑灝嗘敼鍙樿紼嬪簭鐨勭幆澧?鎴戜滑娣誨姞涓涓敤鎴峰彲浠ヨ緭鍏ュ鍚嶇殑鏂囨湰鍩?涓鏃︽寜閽鐐瑰嚮浜?璇鋒眰灝嗕細鍙戦佸埌鏈嶅姟鍣ㄧ.鏈嶅姟鍣ㄥ皢榪斿洖鍑虹幇鍦ㄥ脊鍑虹獥鍙g殑娑堟伅.涓轟簡璺熻釜璇鋒眰鍜屽搷搴?鎴戜滑娣誨姞涓涓枃鏈爣絳炬潵鏄劇ず璇鋒眰鐨勭姸鎬? 涓轟簡鍦ㄦ湇鍔″櫒鍜屽鎴風浼犻佹暟鎹?鎴戜滑浣跨敤涓や釜Java beans. 聽鈥撀犱竴涓妸鏁版嵁甯﹀洖鏈嶅姟鍣ㄧ,涓涓妸鍝嶅簲甯﹀洖瀹㈡埛绔? . 28.聽鍦↗avaSource涓垱寤轟竴涓?demo.gwt.client.EventData 綾?鍐呭濡備笅: package demo.gwt.client; 鐢ㄦ潵鍦ㄥ鎴風鍒版湇鍔″櫒绔紶閫佹暟鎹殑綾?鍙戦佷簨浠?搴旇緇ф壙 G4jsf鐨劼燝wtFacesEvent綾? 29.聽鍒涘緩鍙﹀涓涓被 demo.gwt.client.ResultGreeting. 鍐呭濡備笅: package demo.gwt.client; 浠庢湇鍔″櫒绔甫鏉ュ搷搴旂殑綾誨簲璇ョ戶鎵縂4jsf鐨?GwtFacesResult 綾? 聽GwtFacesEvent 鍜孏wtFacesResult 閮藉疄鐜頒簡 聽com.google.gwt.user.client.rpc.IsSerializable 鎺ュ彛,鐢ㄦ潵搴忓垪鍖栧湪瀹㈡埛绔拰鏈嶅姟鍣ㄧ浼犻掔殑琚獹WT浣跨敤鐨勬暟鎹? 璁╂垜浠洿鏂版垜浠殑widget 綾? 30. 鎵撳紑demo.gwt.client.HelloWidgetEntryPoint 浣跨敤涓嬮潰浠g爜鏇挎崲瀹? package demo.gwt.client; 榪欓噷鏈?涓噸瑕佺殑閮ㄥ垎.1.緇勪歡鐨勫竷灞.鎴戜滑鍒涘緩浜嗕竴涓按騫抽潰鏉?鐒跺悗娣誨姞浜嗕竴涓猧nput box,button,鍜宼ext label. 2.澹版槑浜嗗紓姝ユ湇鍔″拰浜嬩歡,瀹冪戶鎵胯嚦寮傛妯″瀷鐨凙JAX璇鋒眰. ... 聽 鎴戜滑娣誨姞ClickListener 鍒癰utton涓? 褰?On Click 浜嬩歡鍙戠敓鏃?鎴戜滑鍒涘緩騫朵笖浣跨敤杈撳叆鐨勬暟鎹~鍏?聽EventData bean聽鐒跺悗浣跨敤寮傛鏈嶅姟鍙戦佽浜嬩歡.鍦ㄤ唬鐮佺殑緇勫悗涓琛?鎴戜滑璁劇疆text label鐨勬枃鏈負 "Loading鈥?,鍥犳鍦?聽AJAX request 寮濮嬬殑鏃跺?鐢ㄦ埛鍙互鐪嬪埌鍙樺寲 . 3.鍙戦佷簨浠?鎴戜滑娉ㄥ唽浜嗕竴涓洖璋冨嚱鏁?聽 ......... Callback 鏄?Google toolkit涓瑼syncCallback聽 綾葷殑涓涓帴鍙?鎴戜滑瀹炵幇浜嗕袱涓柟娉?onSucess and onFailure. 鍦╫nSuccess鎯呭喌涓? 鎴戜滑娣誨姞浜嗕竴涓檮鍔犵殑媯嫻嬪埌鏉ョ殑緇撴灉.濡傛灉鎴戜滑娌℃湁鍙楀埌涓涓湡鏈涚殑綾?鎴戜滑鏍囪鍦ㄧ姸鎬佹枃鏈腑.聽 鐜板湪鎴戜滑瀹屾垚浜嗗鎴風鐨勪唬鐮?濡傛灉浣犱嬌鐢?聽Hosted Mode (with the "ant shell" command)鏉ュ惎鍔ㄧ▼搴?聽浣犲皢鐪嬪埌 "Request finished, but the result is empty", 鍥犱負鎴戜滑榪樻病鏈夊啓鏈嶅姟鍣ㄧ浠g爜. Server-Side Coding 鍦℉osted Mode涓殑鏈嶅姟鍣ㄧ浠g爜, 鍦╯erver鍖呬腑鐨勪竴涓被鎵紨浜嗕竴涓噸瑕佽鑹? 31. 鎵撳紑JavaSource涓殑demo.gwt.server.MockHelloWidget java 鏂囦歡. 聽sendEvent 鍑芥暟澶嶆潅鍙戦佸搷搴斿埌瀹㈡埛绔? 32. 鎶妔endEvent鍑芥暟鏇挎崲涓轟笅闈㈢殑鍐呭.: public GwtFacesResult sendEvent(GwtFacesEvent event){ 33. 瀵煎叆闇瑕佺殑綾? import demo.gwt.client.ResultGreeting; The parameter of the method points to the event content that came from the client. What we do here is create the Result bean filling it with a greeting message and then returning. 34.鍦℉osted Mode涓惎鍔╝nt:
澶勭悊JSF鐨勪簨浠跺拰Hosted Mode鐨勪唬鐮佸樊涓嶅. 瀹㈡埛绔唬鐮佷笉鍙?鍦ㄦ湇鍔″櫒绔?,聽G4jsf浣跨敤 JSF聽鐩戝惉鍣ㄦ満鍒舵潵澶勭悊 Ajax events. 35.聽鎵撳紑 WebContent/pages/Base.xhtml騫舵坊鍔犵洃鍚櫒緇勪歡澹版槑. <widget:component id="main" buttonLabel="#{bundle.buttonLabel}" 聽聽gwtListener 鍏冪礌鏈変袱涓睘鎬? "method"浣跨敤JSFEL鎸囧悜澶勭悊鍣?"event"鐢ㄦ潵瀹氫箟浜嬩歡綾誨瀷.聽浜嬩歡綾誨瀷鏄被鐨勫叏闄愬畾鍚?.鏈鍚庝竴姝ユ槸瀹炵幇璇ュ嚱鏁? 36. 鎵撳紑demo.gwt.app.GreetingBean娣誨姞涓嬮潰鐨勪唬鐮? public ResultGreeting takeGreeting(EventData event) { 37. 鍜岄渶瑕佸鍏ョ殑綾? import demo.gwt.client.ResultGreeting; 璇ュ嚱鏁扮殑絳懼悕(signature聽 )寰堝鏄撹浣?璇ュ嚱鏁頒嬌鐢ㄦ潵鑷簬瀹㈡埛绔殑浜嬩歡浣滀負浠栫殑鍞竴涓涓弬鏁?榪斿洖鍊間負 鐢ㄦ潵榪斿洖緇撴灉鐨勪簨浠剁被鍨?type of the method equals is just the type of the class used to return the result).鍦ㄨ繖涓嚱鏁頒腑,鎴戜滑鍚堟垚鍝嶅簲鏁版嵁騫朵笖榪斿洖瀹? 38. 鍒涘緩war鏂囦歡,閮ㄧ講瀹? 濡傛灉浣犲惎鍔ㄦ湇鍔″櫒,鍙互鐪嬪:
灝卞浣犵湅鍒扮殑,閫氳繃G4JSF浣跨敤涓ょ浜掕ˉ鐨勬妧鏈?GWT and JSF)鍙互鍋氬緢澶氭紓浜殑浜嬫儏. 浣嗘槸,浠嶇劧榪樻湁寰堝涓滆タ鍙互榪涗竴姝ユ坊鍔犲埌G4jsf涓?浣滀負涓涓紑婧愰」鐩? , G4jsf渚濋潬涓涓紑婧愮ぞ鍖烘潵鏀寔鍜屽紑鍙戝畠.濡傛灉浣犲彧鏄嬌鐢ㄥ畠,閭f槸寰堝ソ鐨?浣嗘槸浣犱篃鍙互鍔犲叆鍒癎4JSF紺懼尯涓潵, 甯姪G4JSF璁╀粬鍋氱殑鏇村ソ. 聽Come visit us at: Sergey Smirnov is Senior Product Manager at Exadel where he oversees the development of major products including Exadel Visual Components Platform and Exadel Studio. He has more than 15 years of in-depth development experience, primarily in the area of Web applications. His experience with JSF goes back to the very early days. For two years, he has served as a member of the JSF expert group. In addition to this, he manages a site for JSF-related resources, www.jsftutorials.net. Finally, Sergey is the co-lead of the open source project Ajax4jsf (https://ajax4jsf.dev.java.net). He can be reached at ssmirnov@exadel.com.
]]>
<Manager className="org.apache.catalina.session.PersistentManager"
saveOnRestart="false"/>
榪欐牱 tomcat 鍦ㄥ叧闂殑鏃跺欏氨涓嶄細淇濆瓨session璧勬簮浜?
浣犱篃鍙互鍦╯erver.xml涓寚瀹氫笂闈㈢殑鍊? 榪欎篃鎵鏈夌殑紼嬪簭閮戒嬌鐢ㄨ繖涓緗簡.
]]>AJAX, AJAX, AJAX
Asynchronous Communication in Hosted Mode
Client-Side Coding
import org.ajax4jsf.gwt.client.GwtFacesEvent;
public class EventData extends GwtFacesEvent {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import org.ajax4jsf.gwt.client.GwtFacesResult;
public class ResultGreeting extends GwtFacesResult {
String greetingText;
public String getGreetingText() {
return this.greetingText;
}
public void setGreetingText(String greetingText) {
this.greetingText = greetingText;
}
}
聽
import java.util.Map;
import org.ajax4jsf.gwt.client.ComponentEntryPoint;
import org.ajax4jsf.gwt.client.GwtFacesServiceAsync;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class HelloWidgetEntryPoint extends ComponentEntryPoint {
Label status;
TextBox input;
protected Widget createWidget(final String id) {
Map m = getWidgetParams(id);
final String buttonLabel = (String) m.get("buttonLabel");
HorizontalPanel panel = new HorizontalPanel();
input = new TextBox();
status = new Label("Loaded.");
final GwtFacesServiceAsync service = createFacesService(id);
final AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Object result) {
if (null != result) {
status.setText("Loaded");
String greeting =聽 ((ResultGreeting)result).getGreetingText();
Window.alert(greeting);
} else {
status.setText("Request finished, but the result is empty");
}
}
public void onFailure(Throwable caught) {
status.setText("Error call :" + caught.getMessage());
}
};
Button btn = new Button(buttonLabel, new ClickListener() {
public void onClick(Widget sender) {
EventData eventData = new EventData();
eventData.setName(input.getText());
service.sendEvent(eventData, callback);
status.setText("Loading...");聽聽聽聽聽
聽聽聽聽聽 }
});
panel.add(input);
panel.add(btn);
panel.add(status);
return panel;
}
}
final GwtFacesServiceAsync service = createFacesService(id);
...
Button btn = new Button(buttonLabel, new ClickListener() {
public void onClick(Widget sender) {
EventData eventData = new EventData();
eventData.setName(input.getText());
service.sendEvent(eventData, callback);
status.setText("Loading...");聽聽聽聽聽
聽聽聽聽聽 }
});
...
:
.........
final AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Object result) {
if (null != result) {
status.setText("Loaded");
String greeting =聽 ((ResultGreeting)result).getGreetingText();
Window.alert(greeting);
} else {
status.setText("Request finished, but the result is empty");
}
}
public void onFailure(Throwable caught) {
status.setText("Error call :" + caught.getMessage());
}
};
...........
...........
聽聽聽聽聽聽聽 ResultGreeting result = new ResultGreeting();
聽聽聽聽聽聽聽 result.setGreetingText( "Hello " +
((EventData)event).getName() );
聽聽聽聽聽聽聽聽聽聽聽聽聽聽 return result;
}
聽
import demo.gwt.client.EventData;Adding JSF Listeners for Run-Time Mode
greeting="Hello #{greetingBean.name}!" >
聽聽 <gwt:gwtListener method="#{greetingBean.takeGreeting}"
聽聽 event ="demo.gwt.client.EventData"/>
</widget:component>
聽
name = event.getName();
ResultGreeting result = new ResultGreeting();
result.setGreetingText("Hello " + name + " from JSF!");
return result;
}
聽
import demo.gwt.client.EventData;
The Last Word
About the Author
]]>
緲昏瘧:icess http://blog.matrix.org.cn/page/icess聽璁ㄨ
聽
鍦ㄦ垜浠簲鐢ㄧ▼搴忕殑絎竴涓増鏈腑,鎴戜滑紜紪鐮佹爣絳懼瓧絎﹀埌紼嬪簭涓?鍦ㄤ笅涓涓増鏈腑,鎴戜滑灝嗕繚鎸佽鏂囨湰涓巎ava浠g爜鍒嗙.
涓縐嶆柟寮忔槸浣跨敤GWT鏉ュ畾涔塴abel 鍜宮essage.
13. 鎵撳紑demo.gwt.client.HelloWidgetEntryPoint.java 鏂囦歡鐢ㄤ笅闈㈢殑浠g爜鏇挎崲createWidget 鏂規硶.
protected Widget createWidget(final String id) {
Map m = getWidgetParams(id);
final String buttonLabel = (String) m.get("buttonLabel");
final String greeting = (String) m.get("greeting");
Button btn = new Button(buttonLabel, new ClickListener() {
public void onClick(Widget sender) {
聽聽聽聽聽 Window.alert(greeting);
聽聽聽聽聽 }
});
return btn;
}
聽
14. 淇濆瓨鏂囦歡.
15.聽鎵撳紑 JavaSource\demo\gwt\public\index.html 鏂囦歡.
璇ユ枃浠跺凡緇忓寘鍚簡涓涓浣曞畾涔夊弬鏁扮殑紺轟緥,鎴戜滑鍙渶瑕佷慨鏀逛竴涓嬪氨鍙互浜? :
16. 淇敼涓哄涓嬬殑浠g爜:
<html>
<head>
<meta name="gwt:module" content="demo.gwt.HelloWidget">
<meta name="gwt:property" content="viewid=hello">
<meta name="gwt:property" content="action=/gwtFacesServlet">
<title>gwt-jsf integration</title>
</head>
<body bgcolor="white">
<script language="javascript" src="gwt.js"></script>
<iframe id="__gwt_historyFrame"
style="width:0;height:0;border:0"></iframe>
<span id="_id1" class="demo.gwt.HelloWidget">
<span id="_id1:_data" style="display:none;">
<span聽 title="buttonLabel">Say Hello</span>
<span聽 title="greeting">Hello GWT!</span>
</span>
<input type="hidden" id="javax.faces.ViewState"
name="javax.faces.ViewState" value="_id0:_id0" />
</span>
</body>
</html>
17.聽鍦?Hosted Mode 涓惎鍔╝nt:
鐒惰?濡傛灉浣犳兂鍒涘緩涓涓獁ar鏂囦歡,鐒跺悗閮ㄧ講瀹?浣犲皢鐪嬩笉鍒扮浉鍚岀殑緇撴灉.榪欐槸鍥犱負 public/index.html浠呬粎鍦℉osted Mode涓叾浣滅敤.鍦?Run-Time Mode,鎴戜滑闇瑕佷嬌鐢?JSF page.
鐪嬩竴涓媁ebContent\pages\Base.xhtml鏂囦歡.瀹冨寘鍚涓嬩唬鐮?聽
<widget:component id="main"聽 />
榪欏疄闄呬笂鏄竴涓狦WT widget 鐨劼燡SF 鍖呰.
18. 瀹氫箟緇勪歡鐨?buttonLabel" 鍜?greeting" 鍙傛暟 :
<widget:component id="main"聽 buttonLabel ="Click Me!"
greeting="Hello, GWT and JSF"/>
19. 鍦≧un-Time Mode涓繍琛岃欏圭洰.
鐪嬬湅緇撴灉. 鐒惰岃繖鏄笉鏄お綆鍗曚簡, 涓嬮潰鏉ョ湅鐪嬪浣曚嬌鐢?聽JSF EL鏉ヤ嬌瀹冩洿鍔ㄦ佷竴浜?
20.鐜板湪鍏抽棴XHTML聽鏂囦歡.
聽
21. 鍦↗avaSource聽 鏂囦歡澶逛笅鍒涘緩demo/gwt/app/bundle/Labels.properties鏂囦歡,鍖呭惈涓嬮潰鐨勫唴瀹?
#
buttonLabel=Say Hello!
聽
22. 鍦↗avaSource涓垱寤轟竴涓被demo.gwt.app.GreetingBean聽 .浣跨敤涓嬮潰鐨勪唬鐮?
package demo.gwt.app;
public class GreetingBean {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
23. 鍦╓EB-INF/faces-context.xml 涓敞鍐岃bean.
The faces-context.xml should contain
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.
//DTD JavaServer Faces Config 1.1//EN"
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<managed-bean>
聽 <managed-bean-name>greetingBean</managed-bean-name>
聽 <managed-bean-class>demo.gwt.app.GreetingBean</managed-bean-class>
聽 <managed-bean-scope>session</managed-bean-scope>
聽 <managed-property>
聽聽 <property-name>name</property-name>
聽聽 <property-class>java.lang.String</property-class>
聽聽 <value>GWT and JSF</value>
聽 </managed-property>
</managed-bean>
聽 <application>
聽 <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config>
聽
瑕佽EL宸ヤ綔.鎴戜滑瑕佸湪緇勪歡綾諱腑娣誨姞灞炴у埌灞炴ap涓?
24. 鎵撳紑demo.gwt.jsf.UIHelloWidget,聽鎵懼埌 getWidgetParameters() 鏂規硶,浣跨敤涓嬮潰鐨勪唬鐮佹浛鎹?
public Map getWidgetParameters() {
HashMap params = new HashMap();
params.put("greeting",getAttributes().get("greeting"));
params.put("buttonLabel",getAttributes().get("buttonLabel"));
return params;
}
25. 娣誨姞涓嬮潰鐨刬mport璇彞:
import java.util.HashMap;
鐜板湪鍥炲埌聽pages/Base.xhtml鏂囦歡涓?
26. 鎶婅祫婧愬0鏄庢斁鍒拌鏂囦歡鐨勯《閮?
<f:loadBundle basename="demo.gwt.app.bundle.Labels" var="bundle"/>
27. 淇敼widget:component鐨勫睘鎬? 聽
<widget:component id="main" buttonLabel ="#{bundle.buttonLabel}"
greeting="Hello #{greetingBean.name}!" />
聽聽聽
聽
鐜板湪涓や釜灞炴ч兘閫氳繃el鏉ヤ駭鐢熶簡,涓涓潵鑷簬 bundle resource file, 涓涓潵鑷簬 backing bean.
濡傛灉浣犲垱寤?閮ㄧ講,鍚姩璇ョ▼搴?浣犲彲浠ョ湅鍒拌紼嬪簭鐜板湪浣跨敤鐨勬寜閽爣絳句簡:
OK,鎴戜滑宸茬粡鍦↗SF鐜涓弬鏁板寲浜咷WT widget鐨勬暟鎹? 鍥犳浣犲彲浠ヤ嬌鐢ㄥ悓鏍風殑鏂規硶鐢ㄦ暟鎹垵濮嬪寲璇?聽widget聽 .鐒惰岀洰鍓嶈繖涓鍒囩湅璧鋒潵鎯充竴寮犲崟紼嬭濺紲? one-way ticket).鎴戜滑榪樻病鏈夋彁鍒頒竴涓潪甯擱噸瑕佺殑鏂歸潰 .
緲昏瘧:icess http://blog.matrix.org.cn/page/icess聽 璁ㄨ
Google Web Toolkit (GWT) 鍚稿紩浜嗕竴浜涘紑鍙戣呯殑娉ㄦ剰.鍥犱負浣跨敤瀹冧綘鍙互寰堝鏄撶殑娣誨姞AJAX Web 2.0鍔熻兘鍒頒綘鐨勭▼搴忎腑. GWT鐨勮璁″笀鍔姏闅旂粷鐢ㄦ埛鍜孞avaScript鎵撲氦閬?浣犲彧瑕佷嬌鐢℅WT灝卞彲浠ヤ簡,涓嶉渶瑕佺煡閬撳浣曚嬌鐢↗S. GWT 閫氳繃浠巎ava浠g爜鏉ヤ駭鐢烰S浠g爜鐨刓鏂瑰紡 瀹炵幇浜嗗垱寤洪珮綰у鎴風JS灝忕粍浠?client-side JavaScript widgets)鐨勪換鍔?
涓庢鍚屾椂, JavaServer Faces (JSF)鑱氶泦浜嗘剤鏉ユ剤澶氱殑鎴愪負閫氱敤鏈嶅姟绔痺eb妗嗘灦鐨勮绱?JSF鎴愬姛鐨勪富瑕佸師鍥犳槸:鑷《鍚戜笅鐨勫熀浜庣粍浠剁殑鏂瑰紡鏉ュ紑鍙憌eb紼嬪簭. 鍚屾椂JSF甯︽湁鑷繁鏍囧噯鐨勯殢鏃跺彲鐢?out-of-the-box)鐨刄I緇勪歡 , 瀹冭璁捐涓虹畝鍗曠殑鍖呭惈鍏朵粬緇勪歡搴?it is designed for the easy inclusion of other component libraries).
鐒惰?榪欎袱欏規妧鏈槸涓嶅彲鎬濊鐨勪嬌浠栦滑鑷繁鑾風泭,浠栦滑涓や釜鐩鎬簰緇撳悎鐨勯潪甯稿ソ(鐩鎬簰浜掕ˉ). GWT聽涓嶇煡閬撴湇鍔$鐨勭姸鎬? server-side-agnostic),鐒惰?JSF's鍩轟簬緇勪歡鐨勭粨鏋勫彲浠ュ緢瀹規槗鐨勯傚簲浠諱綍緇勪歡鐨勬覆鏌?鍦ㄨ繖綃囨枃绔犱腑,鎴戜滑灝嗚璁?(棣栧厛閫氳繃涓涓猻tep-by-step 鐨勪緥瀛?涓涓績榪涜繖涓や釜鎶鏈簰琛ョ殑鏂版鏋?
聽聽G4jsf 宸茬粡鎴愪負Ajax4jsf寮婧愰」鐩殑涓涓瓙欏圭洰浜?(https://ajax4sf.dev.java.net) ,鏈夊畠鏉ヤ駭鐢熻繖縐嶉泦鎴愬簱.
GWT鍜孞SF涔嬮棿鐪嬭搗鏉ユ槸鐩鎬簰绔炰簤鐨勬妧鏈?鑰屼嬌鐢℅4JSF鍒欑湅璧鋒潵鏄緢鑷劧鐨勪簰琛ユ妧鏈?鑰孏4JSF鐨勪換鍔″氨鏄嬌榪欑浜掕ˉ鍏崇郴鐨勬妧鏈湅璧鋒潵鏇磋嚜鐒朵竴浜?
搴撴枃浠跺寘鍚袱涓儴鍒?
G4jsf 娉ㄦ剰浜咼SF 鍜?GWT 涓ょ鎶鏈殑鍙戝睍榪囩▼\.瀵逛簬 GWT, 聽widgets浠嶇劧鍦ㄤ富鏈烘ā鍨嬩腑寮鍙?騫朵笖鍦ㄤ嬌鐢?Google browser鏉ヨ皟璇? 聽GWT聽欏圭洰緇撴瀯鍖呭惈 /client, /public,聽鍜?/server 鍖? 騫朵笖榪樺湪緇х畫緇存姢.
聽G4jsf 緇勪歡寮鍙戝寘(G4jsf CDK)浜х敓鐨勭粍浠跺寘鍚袱涓儴鍒?涓鏄?鍖呭惈瀹㈡埛绔涓虹殑GWT widget聽.浜屾槸璐熻矗 GWT widget聽鍜?JSF 鐜涔嬮棿鐨勯氫俊闂.
G4jsf CDK 浣跨敤Facelets鏂瑰紡鏉ュ啓JSF緇勪歡. 瀹冩瘮涓嶅悓鐨凧SP鏂瑰紡瑕佺畝鍗? 浣跨敤鏅氱殑鏂瑰紡瑕佸垱寤轟竴涓猅LD鏂囦歡鍜屼竴涓猅ag綾?浣跨敤Facelets鐨勬柟寮忔槸鐩稿綋鐩存帴鐨?
鍦ㄨ繖綃囨枃绔犱腑,鎴戜滑灝嗕竴姝ヤ竴姝ョ殑閫氳繃涓涓畝鍗曠殑"Hello, World"聽渚嬪瓙鏉ヨ榪癎4JSF鐨勪富瑕佸姛鑳?鎴戜滑涔熷垱寤轟竴涓疄闄呯殑渚嬪瓙,a4j-gwtdemo.聽鍦ㄨ繖閲?http://livedemo.exadel.com/a4j-gwtdemo/聽鍙互鐪嬪埌璇ヤ緥瀛?
浣犲彲浠ヤ粠Ajax4jsf紺轟緥欏甸潰涓婁笅杞藉埌紺轟緥鐨勬簮浠g爜鍜寃ar閮ㄧ講鏂囦歡 .璇?/font>http://code.google.com/webtoolkit/download.html.
2. 淇濆瓨GWT SDK聽 .
3. 鎶奊4JSF CDK涓殑聽聽build.properties.sample聽閲嶅懡鍚嶄負 build.properties,鎵撳紑瀹?鎶奼wt.home鏀逛負浣犵殑鏈湴GWT 涓葷洰褰?
渚嬪,浣犳妸 Google Web Toolkit SDK 瑙e帇鍒?
gwt.home=D:/gwt-windows-1.1.0
4. 緙栬緫,淇濆瓨鏂囦歡
鍒濆鍖栧伐浣滃凡緇忓仛濂戒簡,涓嬮潰鏉ヤ駭鐢熼」鐩鏋?
鍦ㄥ垰鎵嶇殑鐩綍涓嬬殑build鏂囦歡涓湁涓?"create-component" target. 瀹冮渶瑕佷咯涓繍琛屽弬鏁?
out |
浜х敓鐨勯」鐩唬鐮佹枃浠跺瓨鏀劇殑鐩綍.璺緞鐨勬渶鍚庝竴閮ㄥ垎涓洪」鐩殑鍚嶅瓧 |
m odule |
聽GWT module鐨勫叏闄愬畾鍚? 浜х敓鐨凧SF 緇勪歡綾誨瀷灝嗘湁鍚屾牱鐨勫悕瀛? |
璁╂垜浠懡鍚嶆ā鍨嬩負聽demo.gwt.HelloWidget 淇濆瓨欏圭洰鐨勫悕瀛椾負, KickStart, 鍦―:/workspace/ 鏂囦歡澶逛笅. (Of course, you can change any of these.)
5.浣跨敤涓嬮潰鐨勫懡浠よ繍琛宎nt:
璁╂垜浠潵嬋媧繪垜浠殑欏圭洰.鎴戜滑鍦ㄦ爣鍑嗙殑GWT Hosted Mode涓潵鐪嬬湅鏁堟灉,鍦ㄤ笅涓儴鍒嗕腑灝嗗湪servlet container涓?鏉ュ厑璁歌渚嬪瓙. 7.鎵撳紑 JavaSource/demo/gwt/client/HelloWidgetEntryPoint.java鏂囦歡. 瀹冨寘鍚竴涓燞elloWidgetEntryPoint 綾? 閲岄潰鏈変釜榪斿洖null鐨勬柟娉? 8. 浣跨敤涓嬮潰鐨勪唬鐮佹浛鎹㈣鏂規硶: 9. 淇濆瓨鏂囦歡,鍒癮nt鏂囦歡澶逛笅闈? 10. 浣跨敤shell鐩爣鍚姩ant:
聽聽Google Toolkit Development shell 鍜?Google browser 鍚姩浜?鍦╞rowser涓樉紺轟簡鎴戜滑鍒氭墠鍒涘緩鐨刡utton.濡傛灉浣犵偣鍑籦utton ,涓涓甫闂欐秷鎭殑璀﹀憡妗嗗嚭鐜頒簡. 聽Google browser鍖呭惈涓涓?聽"Compile/Browser"聽鎸夐挳.濡傛灉浣犵偣鍑誨畠,浣犲彲浠ュ湪浣犻粯璁ょ殑嫻忚鍣ㄤ腑鏌ョ湅璇ョず渚? 聽 鐩墠榪樻病鏈変換浣旿SF浠g爜鎼鍚堣繘鏉?鍒版涓轟箣鎴戜滑鍙槸鍦ㄤ嬌鐢?"Hosted Mode."浣犲彲浠ュ湪璇ユā寮忎笅寮鍙戝拰璋冭瘯浣犵殑 GWT widget . 濡傛灉浣犲凡緇忔湁浜嗗紑鍙懧燝WT鐨勭粡楠屼簡,閭d箞浣犲簲璇ュ緢鐔熸倝瀹冧簡. G4jsf銆錛o激錛鐨勫鐞嗚繃紼嬪拰榪欓噷鏄竴鏍風殑. 涓嬩竴姝ユ槸鍦↗SF 鐜涓繍琛岃紺轟緥. 11.浣跨敤 "war" target鍚姩ant:
榪愯璇ラ」鐩?灝卞彲浠ョ湅鍒板悓鏍風殑鏁堟灉,浣嗘槸榪愯鍦↗SF鐜涓垜浠О瀹冧負 聽"Run-Time Mode."鎴戜滑宸茬粡鎶?聽GWT widget 鍖呰涓篔SF 緇勪歡浜?榪欐墠鏄泦鎴愮殑絎竴姝? 聽public class HelloWidgetEntryPoint extends ComponentEntryPoint {
protected Widget createWidget(final String id) {
Button btn = new Button("Click me", new ClickListener() {
public void onClick(Widget sender) {
Window.alert("Hello, World");
}
});
return btn;
}
}
Hosted Mode
Run-Time Mode
璁ㄨ
]]>
from:R.J. Lorimer聽
鍦ㄧ淮鎶ら」鐩殑涓涓櫘閫氱殑浠誨姟灝辨槸鍗囩駭搴撴枃浠?渚嬪, 浣犲湪浣跨敤 commons-collections
鍦ㄤ綘鐨勯」鐩腑,鐜板湪浣跨敤鐨勬槸3.1,浣嗘槸鐜板湪 3.2 鍙戝竷浜? 浣犳兂浣跨敤瀹? 鎵浠ヤ綘闇瑕佷嬌鐢ㄦ柊鐨刯ar鏉ユ浛鎹㈡棫鐨刯ar搴撴枃浠?鍦╡clipse3.2鍙戝竷浠ュ墠浣犻渶瑕佸仛涓嬮潰鐨勫嚑姝ユ潵瀹屾垚瀹?:
[right-click project]->Properties...->Java Build Path->Libraries (tab)鏉ュ垹闄ょ被璺緞涓殑鏃ar鏂囦歡
榪欐牱鍋氭槸寰堥儊闂風殑. 灝ゅ叾鏄綘浣跨敤涓涓嬌鐢ㄥ緢澶氱涓夋柟jar鏂囦歡鐨勫伐鍏鋒椂(濡?Hibernate,spring) 褰撲綘鍗囩駭榪欎簺欏圭洰鏃?浣犺鍋氬緢澶氫笂闈㈢殑鏀瑰姩. 鏄笉鏄緢鏃犺叮鍛??
鏉ョ湅鐪婨clipse 3.2 緇欐垜浠甫鏉ヤ簡浠涔堝惂.鏈変竴涓柊鐨勭壒鎬у彨 'Migrate JAR File',鐢ㄦ潵鍗囩駭jar鏂囦歡.瑕佷嬌鐢ㄨ鍔熻兘,鍦ㄨ鏇挎崲鐨刯ar鏂囦歡涓婂彸鍑?榪涘叆 Build Path
瀛愯彍鍗曢夋嫨 'Migrate JAR file':
浣犱細鐪嬪埌涓嬮潰鐨勫璇濇:
濡傛灉浣犱笉璧拌繍涔熻鏍規敼jar鏂囦歡鍚嶇殑璇?淇濇寔鍘熸潵鐨勫悕瀛椾笉鍙?浣犲彲浠ラ変腑閭d釜澶嶉夋..
鐒跺悗鐐瑰嚮finish, 浣犲皢鐪嬪埌浣犵殑jar鏂囦歡宸茬粡鍗囩駭浜?
灝芥儏浜彈鍚? http://bbs.hexiao.cn/聽