锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
//鍏佽杈撳叆瀛楁瘝銆佺偣銆佸洖閫閿佹暟瀛?br /> if (((int)e.KeyChar >= (int)'a' && (int)e.KeyChar <= (int)'z') || (((int)e.KeyChar > 48 && (int)e.KeyChar < 57) || (int)e.KeyChar == 8 || (int)e.KeyChar == 46))
{
e.Handled = false;
}
else e.Handled = true;
//鍏佽杈撳叆瀛楁瘝銆佸洖閫閿佹暟瀛?br /> if (((int)e.KeyChar >= (int)'a' && (int)e.KeyChar <= (int)'z') || (((int)e.KeyChar > 48 && (int)e.KeyChar < 57) || (int)e.KeyChar == 8))
{
e.Handled = false;
}
else e.Handled = true;
// 鍙兘杈撳叆瀛楁瘝鏁板瓧浠ュ強涓枃瀛?br /> if ((e.KeyChar != '\b') && (!Char.IsLetter(e.KeyChar)) && (!char.IsDigit(e.KeyChar)))
{
e.Handled = true;
}
//鍙緭鍏ユ暟瀛?br /> if (e.KeyChar != 8 && (!Char.IsDigit(e.KeyChar)))
{
e.Handled = true;
}
鍙兘杈撳叆鏁板瓧浠ュ強瀛楁瘝X
if (e.KeyChar != 88 && e.KeyChar != 8 && (!Char.IsDigit(e.KeyChar)))
{
e.Handled = true;
}
]]>
Install-Package NLog -Version 3.2.1
]]>only_full_group_by
鐨勯敊璇紝鍙互鍦╯ql_mode涓叧闂粬錛岀綉涓婃煡鎵劇殑瑙?/span>
]]>
Path %MYSQL_HOME%\bin
鍏堝惎鍔ㄦ湇鍔★細
net start MySQL銆愭垨鑰呮槸MySQL57銆?/code>
use mysql; GRANT ALL ON *.* TO root@'%' IDENTIFIED BY '瀵嗙爜' WITH GRANT OPTION; flush privileges;
REST API浣跨敤緇熶竴璧勬簮鏍囪瘑絎︼紙URI錛夋潵瀵誨潃璧勬簮銆傚湪褰撲粖浜掕仈緗戜笂錛屽厖鏂ョ潃鍚勭鍚勬牱鐨刄RI璁捐瑙勫垯錛屾棦鏈夊儚//api.example.com/louvre/leonardo-da-vinci/mona-lisa榪欐牱鑳藉娓呮鐨勪紶杈続PI璧勬簮妯″瀷鐨勬枃绔狅紝涔熸湁寰堥毦鐞嗚В鐨勬枃绔狅紝渚嬪錛?a style="box-sizing: border-box; background-color: transparent; color: #337ab7; text-decoration: none;">//api.example.com/68dd0-a9d3-11e0-9f1c-0800200c9a66 錛汿im Berners-Lee鍦ㄤ粬鐨?#8220;Axioms of Web Architecture”涓鏂囦腑灝哢RI鐨勪笉閫忔槑搴︽葷粨鎴愪竴鍙ヨ瘽錛?/p>
鍞竴鍙互浣跨敤鏍囪瘑絎︾殑鏄紩鐢ㄥ璞°傚湪涓嶅彇娑堝紩鐢ㄦ椂錛屽氨涓嶅簲璇ユ煡鐪婾RI瀛楃涓茬殑鍐呭浠ヨ幏鍙栧叾浠栦俊鎭?nbsp;
——钂傚·浼撼鏂?- 鏉?/a>
瀹㈡埛绔繀欏婚伒寰猈eb鐨勯摼鎺ヨ寖渚嬶紝灝哢RI瑙嗕負涓嶉忔槑鏍囪瘑絎︺?/p>
REST API璁捐浜哄憳搴旇鍦ㄨ冭檻灝哛EST API璧勬簮妯″瀷浼犺揪緇欐綔鍦ㄧ殑瀹㈡埛绔紑鍙戣呯殑鍓嶆彁涓嬶紝鍒涢燯RI銆傚湪榪欑瘒鏂囩珷涓紝鎴戝皢灝濊瘯涓篟EST API URI 寮曞叆涓濂?a style="box-sizing: border-box; background-color: transparent; color: #337ab7; text-decoration: none;">璁捐瑙勫垯銆?/p>
鍏堣煩榪囪鍒欙紝URI鐨勯氱敤璇硶涔熼傜敤涓庢湰鏂囦腑鐨刄RI銆?a style="box-sizing: border-box; background-color: transparent; color: #337ab7; text-decoration: none;">RFC 3986瀹氫箟浜嗛氱敤URI璇硶錛屽涓嬫墍紺猴細
URI = scheme “://” authority “/” path [ “?” query ][ “#” fragment ]
榪欐槸浣滀負URI璺緞涓鐞嗕腑鏈閲嶈鐨勮鍒欎箣涓錛屾鏂滄潬錛?錛変笉浼氬鍔犺涔夊鹼紝涓斿彲鑳藉鑷存販娣嗐俁EST API涓嶅厑璁鎬竴涓熬閮ㄧ殑鏂滄潬錛屼笉搴旇灝嗗畠浠寘鍚湪鎻愪緵緇欏鎴風鐨勯摼鎺ョ殑緇撳熬澶勩?/p>
璁稿Web緇勪歡鍜屾鏋跺皢騫崇瓑瀵瑰緟浠ヤ笅涓や釜URI錛?nbsp;
http://api.canvas.com/shapes/
http://api.canvas.com/shapes
浣嗘槸錛屽疄闄呬笂URI涓殑姣忎釜瀛楃閮戒細璁″叆璧勬簮鐨勫敮涓韜喚鐨勮瘑鍒腑銆?/span>
涓や釜涓嶅悓鐨刄RI鏄犲皠鍒頒袱涓笉鍚岀殑璧勬簮銆傚鏋淯RI涓嶅悓錛岄偅涔堣祫婧愪篃鏄姝わ紝鍙嶄箣浜︾劧銆傚洜姝わ紝REST API蹇呴』鐢熸垚鍜屼紶閫掔簿紜殑URI錛屼笉鑳藉蹇嶄換浣曠殑瀹㈡埛绔皾璇曚笉綺劇‘鐨勮祫婧愬畾浣嶃?/p>
鏈変簺API紕板埌榪欑鎯呭喌錛屽彲鑳借璁′負璁╁鎴風閲嶅畾鍚戝埌鐩稿簲娌℃湁灝炬枩鏉犵殑URI錛堜篃鏈夊彲鑳戒細榪斿洖301 - 鐢ㄦ潵璧勬簮閲嶅畾鍚戯級銆?/p>
URI鐨勮礬寰勪腑鐨勬鏂滄潬錛?錛夊瓧絎︾敤浜庢寚紺鴻祫婧愪箣闂寸殑灞傛鍏崇郴銆?/p>
渚嬪錛?nbsp;
(http://api.canvas.com/shapes/polygons/quadrilaterals/squares 錛?/p>
涓轟簡浣挎偍鐨刄RI瀹規槗璁╀漢浠悊瑙o紝璇蜂嬌鐢ㄨ繛瀛楃錛?- 錛夊瓧絎︽潵鎻愰珮闀胯礬寰勪腑鍚嶇О鐨勫彲璇繪с傚湪璺緞涓紝搴旇浣跨敤榪炲瓧絎︿唬絀烘牸榪炴帴涓や釜鍗曡瘝 銆?/p>
渚嬪錛?nbsp;
http://api.example.com/blogs/guy-levin/posts/this-is-my-first-post
涓浜涙枃鏈煡鐪嬪櫒涓轟簡鍖哄垎寮鴻皟URI錛屽父甯鎬細鍦║RI涓嬪姞涓婁笅鍒掔嚎銆傝繖鏍蜂笅鍒掔嚎錛坃錛夊瓧絎﹀彲鑳借鏂囨湰鏌ョ湅鍣ㄤ腑榛樿鐨勪笅鍒掔嚎閮ㄥ垎鍦伴伄钄芥垨瀹屽叏闅愯棌銆?/p>
涓洪伩鍏嶈繖縐嶆販娣嗭紝璇蜂嬌鐢ㄨ繛瀛楃錛?- 錛夎屼笉鏄笅鍒掔嚎
鏂逛究鏃訛紝URI璺緞涓閫夊皬鍐欏瓧姣嶏紝鍥犱負澶у啓瀛楁瘝鏈夋椂浼氬鑷翠竴浜涢棶棰樸俁FC 3986灝哢RI瀹氫箟涓哄尯鍒嗗ぇ灝忓啓錛屼絾scheme 鍜?host components闄ゅ銆?/p>
渚嬪錛?nbsp;
http://api.example.com/my-folder/my-doc
HTTP://API.EXAMPLE.COM/my-folder/my-doc
榪欎釜URI寰堝ソ銆俇RI鏍煎紡瑙勮寖錛圧FC 3986錛夎涓鴻URI涓嶶RI錛?鐩稿悓銆?/p>
http://api.example.com/My-Folder/my-doc
鑰岃繖涓猆RI涓嶶RI 1鍜?涓嶅悓錛岃繖鍙兘浼氬鑷翠笉蹇呰鐨勬販娣嗐?/p>
鍦╓eb涓婏紝錛?錛夊瓧絎﹂氬父鐢ㄤ簬鍒嗛殧URI鐨勬枃浠跺悕鍜屾墿灞曞悕銆?nbsp;
REST API涓嶅簲鍦║RI涓寘鍚漢閫犳枃浠舵墿灞曞悕錛屾潵鎸囩ず閭歡瀹炰綋鐨勬牸寮忋傜浉鍙嶏紝浠栦滑搴旇渚濊禆閫氳繃Content-Type涓殑header浼犻抦edia type錛屾潵紜畾濡備綍澶勭悊姝f枃鐨勫唴瀹廣?/p>
http://api.college.com/students/3248234/courses/2005/fall.json
http://api.college.com/students/3248234/courses/2005/fall
濡備笂鎵紺猴細涓嶅簲浣跨敤鏂囦歡鎵╁睍鍚嶆潵琛ㄧず鏍煎紡銆?/p>
搴旈紦鍔盧EST API瀹㈡埛绔嬌鐢℉TTP鎻愪緵鐨勬牸寮忛夋嫨鏈哄埗Accept request header銆?/p>
涓轟簡鏄摼鎺ュ拰璋冭瘯鏇寸畝鍗曪紝REST API搴旇鏀寔閫氳繃鏌ヨ鍙傛暟鏉ユ敮鎸佸獟浣撶被鍨嬬殑閫夋嫨銆?/p>
keep-it-simple鐨勫師鍒欏湪榪欓噷鍚屾牱閫傜敤銆傝櫧鐒朵竴浜?#8221;璇硶瀛﹀”浼氬憡璇変綘浣跨敤澶嶆暟鏉ユ弿榪拌祫婧愮殑鍗曚釜瀹炰緥鏄敊璇殑錛屼絾瀹為檯涓婁負浜嗕繚鎸乁RI鏍煎紡鐨勪竴鑷存у緩璁嬌鐢ㄥ鏁板艦寮忋?/p>
鏈潃API鎻愪緵鍟嗘洿瀹規槗瀹炴柦鍜孉PI浣跨敤鑰呮洿瀹規槗鎿嶄綔鐨勫師鍒欙紝鍙互涓嶅繀綰犵粨涓浜涘鎬殑澶嶆暟錛坧erson/people錛実oose/geese錛夈?/p>
浣嗘槸搴旇鎬庝箞澶勭悊灞傜駭鍏崇郴鍛紵濡傛灉涓涓叧緋誨彧鑳藉瓨鍦ㄤ簬鍙︿竴涓祫婧愪腑錛孯ESTful鍘熷垯灝變細鎻愪緵鏈夌敤鐨勬寚瀵箋傛垜浠潵鐪嬩竴涓嬭繖涓緥瀛愩傚鐢熸湁涓浜涜紼嬨傝繖浜涜紼嬪湪閫昏緫涓婃槧灝勫埌瀛︾敓緇堢錛屽涓嬫墍紺猴細
http://api.college.com/students/3248234/courses - 媯绱d涓?248234鐨勫鐢熷涔犵殑鎵鏈夎紼嬬殑娓呭崟銆?nbsp;
http://api.college.com/students/3248234/courses/physics -媯绱㈣瀛︾敓鐨勭墿鐞嗚紼?/p>
褰撲綘鍦?a style="box-sizing: border-box; background-color: transparent; color: #337ab7; text-decoration: none;">璁捐REST API鏈嶅姟鏃訛紝鎮ㄥ繀欏繪敞鎰忚繖浜涚敱URI瀹氫箟鐨勮祫婧愩?/p>
姝e湪鏋勫緩鐨勬湇鍔′腑鐨勬瘡涓祫婧愬皢鑷沖皯鏈変竴涓猆RI鏍囪瘑瀹冦傝繖涓猆RI鏈濂芥槸鏈夋剰涔夌殑錛屼笖鑳藉厖鍒嗘弿榪拌祫婧愩俇RI搴旈伒寰彲棰勬祴鐨勫眰嬈$粨鏋勶紝鐢ㄦ潵鎻愰珮鍏跺彲鐞嗚В鎬э紝鍙敤鎬э細鍙嫻嬬殑鎰忎箟鍦ㄤ簬瀹冧滑鏄竴鑷寸殑錛屽畠鐨勫眰嬈$粨鏋勫湪鏁版嵁鍏崇郴涓婃槸鏈夋剰涔夌殑銆?/p>
RESTful API鏄負浣跨敤鑰呯紪鍐欑殑銆俇RI鐨勫悕縐板拰緇撴瀯搴旇鑳藉鍚戜嬌鐢ㄨ呬紶杈炬洿娓呮櫚鐨勫惈涔夈傞氳繃閬靛驚涓婅堪瑙勫垯錛屾偍灝嗗垱寤轟竴涓洿娓呮櫚鐨勭殑REST API涓庢洿鍙嬪ソ鐨勫鎴風銆傝繖浜涘茍涓嶆槸REST鐨勮鍒欐垨綰︽潫錛屼粎浠呮槸API鐨勫寮哄拰琛ュ厖銆?/p>
鎴戜篃寤鴻浣犳潵鐪嬬湅http://blog.restcase.com/5-basic-rest-api-design-guidelines/榪欑瘒鏂囩珷銆?/p>
鏈鍚庯紝鏈涘ぇ瀹剁墷璁幫細浣犲湪涓轟綘鐨勫鎴風璁捐API URI錛岃屼笉浠呬粎鏄負浣犵殑鏁版嵁銆?/p>
浠?/span>classpath鏍圭洰褰曚笅鍔犺澆鎸囧畾鍚嶇О鐨勬枃浠?/span>
* this.getClass().getResourceAsStream("testVariables.bpmn")
浠庡綋鍓嶅寘涓嬪姞杞芥寚瀹氬悕縐扮殑鏂囦歡
* this.getClass().getResourceAsStream("/testVariables.bpmn")
浠?/span>classpath鏍圭洰褰曚笅鍔犺澆鎸囧畾鍚嶇О鐨勬枃浠?/span>
activiti緋葷粺涓鍏辨湁23涓〃錛屽寘鎷祦紼嬪畾涔夎〃銆佷竴鑸暟鎹俊鎭〃銆佹祦紼嬭繍琛屽疄渚嬭〃銆佹祦紼嬪巻鍙茶褰曡〃銆佺敤鎴風敤鎴風粍琛ㄣ?/p>
嫻佺▼瀹氫箟琛紝嫻佺▼瀹氫箟琛ㄤ篃鍙互鍙仛鏄潤鎬佽祫婧愬簱錛岄潤鎬佽祫婧愬寘鎷浘鐗囥佸畾涔夎鍒欑瓑銆傚畠鏈夐儴緗蹭俊鎭〃銆佹祦紼嬫ā鍨嬭〃銆佹祦紼嬪畾涔夎〃
1銆丄CT_RE_DEPLOYMENT錛堥儴緗蹭俊鎭〃錛?/p>
鍖呮嫭錛氶儴緗叉祦紼嬪悕縐般佺被鍨嬨侀儴緗叉椂闂?/p>
2銆丄CT_RE_MODEL錛堟ā鍨嬭〃錛?/p>
鍚嶇О,key銆佺被鍨嬨佸垱寤烘椂闂淬佹渶鍚庝慨鏀規椂闂淬佺増鏈佹暟鎹簮淇℃伅銆侀儴緗睮D銆佺紪杈戞簮鍊糏D銆佺紪杈戞簮棰濆鍊糏D錛堝閿瓵CT_GE_BYTEARRAY 錛?/p>
3銆丄CT_RE_PROCDEF錛堟祦紼嬪畾涔夎〃錛?nbsp;
鍖呮嫭嫻佺▼瀹氫箟銆佺被鍨嬨佹祦紼嬪悕縐般佹祦紼媖ey銆佺増鏈彿銆侀儴緗睮D銆佽祫婧愬悕縐般佸浘鐗囪祫婧愬悕縐般佹弿榪頒俊鎭佹槸鍚︿粠key鍚姩銆佹殏鍋滅姸鎬併?/p>
榪愯瀹炰緥琛ㄨ褰曟祦紼嬫祦杞繃紼嬩腑浜х敓鐨勬暟鎹紝涓鑸暟鎹垎涓轟袱涓儴鍒嗘祦紼嬫暟鎹佷笟鍔℃暟鎹傛祦紼嬫暟鎹槸鎸嘺ctiviti嫻佺▼寮曟搸嫻佽漿榪囩▼涓殑鏁版嵁錛屽寘鎷祦紼嬫墽琛屽疄渚嬫暟鎹帴銆佷換鍔℃暟鎹佹墽琛屼換鍔′漢鍛樹俊鎭佸彉閲忎俊鎭備笟鍔℃暟鎹垯鏄祦紼嬭繃紼嬩腑淇濆瓨鐨勮〃鍗曟暟鎹紝渚嬪錛氬璇峰亣鐨勮鍋囧崟鏁版嵁銆佹姤閿鍗曟暟鎹佸鎵規剰瑙佷俊鎭瓑錛屾閮ㄥ垎鏁版嵁涓鑸渶瑕佽嚜宸卞緩鏁版嵁琛ㄨ繘琛屼繚瀛橈紝鍦ㄤ箣鍓嶇殑jbpm4涓病鏈変繚瀛樹笟鍔℃暟鎹?/p>
1銆丄CT_RU_EVENT_SUBSCR錛堜簨浠跺瓙鑴氭湰錛変綔鐢ㄦ湭鐭?/p>
浜嬩歡鍚嶇О錛圗VENT_NAME_錛夈佷簨浠剁被鍨?EVENT_TYPE_)銆佹祦紼嬫墽琛孖D(EXECUTION_ID_)銆佹祦紼嬪疄渚婭D(PROC_INST_ID_)銆佹椿鍔↖D(ACTIVITY_ID_)銆侀厤緗俊鎭?CONFIGURATION_)銆佸垱寤烘椂闂達紙CREATED_錛?/p>
2銆丄CT_RU_EXECUTION錛堟墽琛屼腑嫻佺▼鎵ц錛夋牳蹇冩垜鐨勪唬鍔炰換鍔℃煡璇㈣〃
嫻佺▼瀹炰緥ID錛圥ROC_INST_ID_錛夛紝涓氬姟key錛圔USINESS_KEY_錛夈佺埗鎵ц嫻佺▼錛圥ARENT_ID_錛夈佹祦紼嬪畾涔塈d錛堝閿甈ROC_DEF_ID_錛夈佸疄渚媔d錛圓CT_ID_錛夈佹縺媧葷姸鎬侊紙IS_ACTIVE_錛夈佸茍鍙戠姸鎬侊紙is_concurrent錛夈乮s_scope銆乮s_evnet_scope銆佹殏鍋滅姸鎬侊紙suspension_state錛夈佺紦瀛樼粨鏉熺姸鎬侊紙cached_end_state錛?/p>
3銆丄CT_RU_IDENTITYLINK錛堣韓浠借仈緋伙級
鐢ㄦ埛緇勶緝錛わ紙GROUP_ID_錛夈佺敤鎴風粍綾誨瀷(TYPE_)銆佺敤鎴稩D(USER_ID_)銆佷換鍔d錛堝閿細TASK_ID_錛夈佹祦紼嬪疄渚婭D錛堝閿細PROC_INST_ID_錛夈佹祦紼嬪畾涔塈d錛堝閿?PROC_DEF_ID_錛?/p>
4銆丄CT_RU_JOB(榪愯涓殑浠誨姟)
5銆丄CT_RU_TASK錛堟墽琛屼腑瀹炴椂浠誨姟錛変唬鍔炰換鍔℃煡璇㈣〃
瀹炰緥id錛堝閿瓻XECUTION_ID_錛夈佹祦紼嬪疄渚婭D錛堝閿甈ROC_INST_ID_錛夈佹祦紼嬪畾涔塈D錛圥ROC_DEF_ID_錛夈佷換鍔″悕縐幫紙NAME_錛夈佺埗鑺備換鍔D錛圥ARENT_TASK_ID_錛?/p>
銆佷換鍔℃弿榪幫紙DESCRIPTION_錛夈佷換鍔″畾涔塳ey錛圱ASK_DEF_KEY_錛夈佹墍灞炰漢錛圤WNER_錛夈佷唬鐞嗕漢鍛?(ASSIGNEE_)銆佷唬鐞嗗洟錛圖ELEGATION_錛夈佷紭鍏堟潈錛圥RIORITY_錛夈佸垱寤烘椂闂達紙CREATE_TIME_錛夈佹墽琛屾椂闂達紙DUE_DATE_錛夈佹殏鍋滅姸鎬侊紙SUSPENSION_STATE_錛?/p>
6銆丄CT_RU_VARIABLE錛堝疄鏃跺彉閲忥級
鍙橀噺鍚嶇О錛圢AME_錛夈佺紪鐮佺被鍨?TYPE_)銆佹墽琛屽疄渚婭D(EXECUTION_ID_)銆佹祦紼嬪疄渚婭d(PROC_INST_ID_)銆佷換鍔d(TASK_ID_)銆佸瓧鑺傜粍ID錛圔YTEARRAY_ID_錛夈丏OUBLE_銆丩ONG_銆乀EXT_銆乀EXT2_
嫻佺▼鍘嗗彶淇℃伅琛紝activiti鍘嗗彶璁板綍琛ㄥ寘鎷妭鐐逛俊鎭〃銆侀檮浠朵俊鎭〃銆佸巻鍙插鎵硅褰曡〃銆佺悊鎯寵緇嗕俊鎭〃銆佸巻鍙茶韓浠戒俊鎭〃銆佹祦紼嬪疄渚嬪巻鍙茶〃銆佷換鍔″巻鍙茶〃銆佸巻鍙插彉閲忚〃銆傦紙鑺傜偣淇℃伅琛ㄣ侀檮浠朵俊鎭〃銆佸巻鍙插鎵硅褰曡〃銆佺悊鎯寵緇嗕俊鎭〃銆佸巻鍙茶韓浠戒俊鎭〃錛夎繖浜涜〃鐩墠榪樻湭鐭ユ槸濡備綍鐢ㄧ殑銆傦紙嫻佺▼瀹炰緥鍘嗗彶琛ㄣ佷換鍔″巻鍙茶〃銆佸巻鍙插彉閲忥級涓変釜琛ㄥ彲浠ユ煡璇㈡垜宸插畬鎴愪換鍔°佷換鍔¤拷韙瓑銆?/p>
1銆丄CT_HI_ACTINST錛堟椿鍔ㄥ疄渚嬩俊鎭級
嫻佺▼瀹氫箟ID錛圥ROC_DEF_ID_錛夈佹祦紼嬪疄渚婭D錛圥ROC_INST_ID_錛夈佹祦紼嬫墽琛孖D錛圗XECUTION_ID_錛夈佹椿鍔↖D錛圓CT_ID_錛夈佹椿鍔ㄥ悕縐幫紙TASK_ID_錛夈佹椿鍔ㄧ被鍨嬶紙ACT_TYPE_錛夈佷換鍔D銆侊紙TASK_ID_錛夈佽姹傛祦紼嬪疄渚婭D錛圕ALL_PROC_INST_ID_錛夈佷唬鐞嗕漢鍛橈紙ASSIGNEE_錛夈佸紑濮嬫椂闂達紙START_TIME_錛夈佺粨鏉熸椂闂?END_TIME_)銆佹椂闀匡紙DURATION_錛?/p>
2銆丄CT_HI_ATTACHMENT錛堥檮浠朵俊鎭級
鐢ㄦ埛id錛圲SER_ID_錛夈佸悕縐幫紙NAME_錛夈佹弿榪幫紙DESCRIPTION_錛夈佺被鍨嬶紙TYPE_錛夈佷換鍔d錛圱ASK_ID_錛夈佹祦紼嬪疄渚婭D錛圥ROC_INST_ID_錛夈佽繛鎺ワ紙URL_錛夈佸唴瀹笽d錛圕ONTENT_ID_錛?/p>
3銆丄CT_HI_COMMENT錛堝巻鍙插鎵逛俊鎭級
綾誨瀷錛圱YPE_錛夈佹椂闂達紙TIME_錛夈佺敤鎴稩d錛圲SER_ID_錛夈佷換鍔d錛圱ASK_ID_錛夈佹祦紼嬪疄渚婭d錛圥ROC_INST_ID_錛夈佹椿鍔紙ACTION_錛夈佹秷鎭紙MESSAGE_錛夈佸叏閮ㄦ秷鎭紙FULL_MSG_錛?/p>
4銆丄CT_HI_DETAIL錛堝巻鍙茶緇嗕俊鎭級
鏁版嵁綾誨瀷錛圱YPE_錛夈佸垱寤烘椂闂?TIME_)銆佸悕縐?NAME_)銆佹祦紼嬪疄渚婭D錛圥ROC_INST_ID_錛夈佹墽琛屽疄渚婭d(EXECUTION_ID_)銆佷換鍔d(TASK_ID_)銆佹椿鍔ㄥ疄渚婭d(ACT_INST_ID_)銆佸彉閲忕被鍨?VAR_TYPE_)銆佸瓧鑺傛暟緇処d銆丏OUBLE_銆丩ONG_銆佸鹼紙TEXT_錛夈佸?錛圱EXT2_錛?/p>
5銆丄CT_HI_IDENTITYLINK錛堝巻鍙茶韓浠戒俊鎭級
浠誨姟Id錛圱ASK_ID_錛夈佹祦紼嬪疄渚婭d錛圥ROC_INST_ID_錛夈乽serId錛圲SER_ID_錛夈佺敤鎴風粍綾誨瀷Type錛圱YPE_錛夈佺敤鎴風粍ID錛圙ROUP_ID_錛?/p>
6銆丄CT_HI_PROCINST錛堝巻鍙叉祦紼嬪疄渚嬩俊鎭級鏍稿績琛?/p>
嫻佺▼瀹炰緥ID錛圥ROC_INST_ID_錛夈佷笟鍔ey錛圔USINESS_KEY_錛夈佹祦紼嬪畾涔塈d錛圥ROC_DEF_ID_錛夈佸紑濮嬫椂闂達紙START_TIME_錛夈佺粨鏉熸椂闂達紙END_TIME_錛夈佹椂闀匡紙DURATION_錛夈佸彂璧蜂漢鍛業d錛圫TART_USER_ID_錛夈佸紑濮嬭妭鐐癸紙START_ACT_ID_錛夈佺粨鏉熻妭鐐癸紙END_ACT_ID_錛夈佽秴綰ф祦紼嬪疄渚婭d錛圫UPER_PROCESS_INSTANCE_ID_錛夈佸垹闄ょ悊鐢憋紙DELETE_REASON_錛?/p>
7銆丄CT_HI_TASKINST錛堝巻鍙蹭換鍔℃祦紼嬪疄渚嬩俊鎭級鏍稿績琛?/p>
嫻佺▼瀹炰緥ID錛圥ROC_INST_ID_錛夈佷換鍔″畾涔塊ey錛圔USINESS_KEY_錛夈佹祦紼嬪畾涔塈d錛圥ROC_DEF_ID_錛夈佹墽琛孖D錛圗XECUTION_ID_錛夈佸悕縐幫紙NAME_錛夈佺埗浠誨姟iD錛圥ARENT_TASK_ID_錛夈佹弿榪幫紙DESCRIPTION_錛夈佹墍灞炰漢錛圤WNER_錛夈佷唬鐞嗕漢錛圓SSIGNEE_錛夈佸紑濮嬫椂闂達紙START_TIME_錛夈佺粨鏉熸椂闂達紙END_TIME_錛夈佹椂闀匡紙DURATION_錛夈佸垹闄ょ悊鐢憋紙DELETE_REASON__錛夈佷紭鍏堢駭錛圥RIORITY_錛夈佸簲瀹屾垚鏃墮棿錛圖UE_DATE_錛夈佽〃鍗昸ey錛團ORM_KEY_錛?/p>
8銆丄CT_HI_VARINST錛堝巻鍙插彉閲忎俊鎭級
嫻佺▼瀹炰緥ID錛圥ROC_INST_ID_錛夈佹墽琛孖D錛圗XECUTION_ID_錛夈佷換鍔d銆佸悕縐幫紙NAME_錛夈佸彉閲忥紙TASK_ID_錛夈佺被鍨嬶紙VAR_TYPE_錛夈佸瓧鑺傛暟緇処D錛圔YTEARRAY_ID_錛夈丏OUBLE_銆丩ONG_銆乀EXT_銆乀EXT2_
1銆丄CT_GE_BYTEARRAY錛堝瓧鑺傛暟鎹〃錛?/p>
鍚嶇О錛圢AME_錛夈侀儴緗睮d錛圖EPLOYMENT_ID_錛夈佸瓧鑺傛暟鎹紙BYTES_錛夈佸彂鐢熺殑錛圙ENERATED_錛?/p>
2銆丄CT_GE_PROPERTY錛堜竴鑸睘鎬ц〃錛?/p>
鍚嶇О錛圢AMe_錛夈佸?VALUe_)
Activit 鐨勭敤鎴風敤鎴風粍琛紝鍖呮嫭鐢ㄦ埛淇℃伅銆佺敤鎴風粍淇℃伅銆佺敤鎴蜂笌鐢ㄦ埛緇勯棿鐨勫叧緋匯佺敤鎴蜂俊鎭笌鐢ㄦ埛涔嬮棿鐨勫叧緋匯傚湪瀹為檯寮鍙戜腑鏈噰鐢紝鐢ㄧ殑瀹為檯緋葷粺涓敤鎴楓?/p>
1銆丄CT_ID_GROUP錛堢敤鎴風粍琛級
鍚嶇О錛圢AME_錛夈佺被鍨?TYPE_)
2銆丄CT_ID_USER錛堢敤鎴瘋〃錛?/p>
濮?FIRST_)銆佸悕縐?LAST_)銆侀偖浠?EMAIL_)銆佸瘑鐮?PWD_)銆佸ご鍍廔d (PICTURE_ID_)
3銆丄CT_ID_INFO錛堢敤鎴蜂俊鎭〃錛?/p>
鐢ㄦ埛Id(USER_ID_)銆佺被鍨?TYPE_)銆乫ormINPut鍚嶇О(KEY_)銆佸?VALUE_)銆佸瘑鐮?PASSWORD_)銆佺埗鑺傜偣(PARENT_ID_)
4銆丄CT_ID_MEMBERSHIP錛堢敤鎴風敤鎴風粍鍏寵仈琛級
鐢ㄦ埛Id(user_ID_)銆佺敤鎴風粍Id錛坓roup_Id錛?/p>
Activiti琛ㄧ粨鏋勫垎鏋愬畬鎴愶紝鑺變簡5涓皬鏃訛紝榪樻湁寰堝闂涓嶆槑鐧姐傚悗緇參鎱㈠紑鍙戣繃紼嬩腑鍐嶇悊涓嬈¤〃涔嬮棿鍏崇郴鍚э紝鍒濇鎯蟲硶鍦ㄧ郴緇熶腑闇瑕佹墿寤鴻〃錛屾妸涓氬姟鏁版嵁鍜屾祦紼嬫暟鎹垎寮銆?/p>
Druid鏄竴涓狫DBC緇勪歡錛屽畠鍖呮嫭鍥涗釜閮ㄥ垎錛?/p>
DruidDriver錛屾槸涓涓狿roxyJdbcDriver錛屽畠鎻愪緵浜咶ilter-Chain妯″紡鐨勬墿灞曟満鍒訛紝浣垮緱鍦↗dbc鎵╁睍緙栫▼鐗瑰埆鏂逛究銆?/p>
Druid鎻愪緵浜嗕竴浜涘唴緗殑鎵╁睍鏈哄埗錛屽寘鎷?u>Stat銆?u>Log銆?u>Trace銆丠A絳夋墿灞曘?/p>
DruidDataSource鏄竴涓暟鎹簱榪炴帴姹犵殑瀹炵幇錛屽畠鐨勮璁$洰鏍囨槸鎻愪緵涓涓綋鍓嶆渶濂界殑鏁版嵁搴撹繛鎺ユ睜錛屽湪鎬ц兘銆佹墿灞曟х瓑鏂歸潰鍙栧緱鏈鍚堥傜殑騫寵 錛屽彇浠BCP銆丆3P0絳夎繛鎺ユ睜銆?/p>
榪欐槸DruidDataSource鐨勮璁″浘紺猴細
http://code.alibabatech.com/svn/druid/trunk/doc/druid-pool.txt
濡傛灉鍙戠幇鏈変貢鐮侊紝璇烽夋嫨utf-8鐨勭紪鐮佹柟寮忔煡鐪嬨?/p>
Druid鎻愪緵涓涓墜宸ョ紪鍐欑殑楂樻ц兘鐨勬柟渚挎墿灞曠殑SQL Parser銆傚皢浼氭敮鎸丮ySQL銆丱racle絳夋祦琛屽叧緋繪暟鎹簱鐨凷QL Parser銆?/p>
Parser緇勪歡鍖呮嫭濡備笅鍑犱釜閮ㄥ垎錛?/p>
Druid鎻愪緵浜嗗己澶х殑鐩戞帶鍔熻兘錛岃兘澶熺洃鎺ц繛鎺ユ睜琛屼負鍜孲QL鎵ц鎯呭喌錛岃浣犺兘澶熻緇嗕簡瑙e簲鐢ㄧ殑鏁版嵁搴撹闂涓恒?/p>
涓轟簡浣跨緇忕綉緇滄湁鏁堬紝鎴戜滑蹇呴』瀵規暟鎹繘琛屾鎬佸寲銆傝繖鏄縺媧誨嚱鏁扮殑姝g‘璁$畻鎵闇瑕佺殑銆傛鎬佸寲鏄竴縐嶆暟瀛﹀鐞嗭紝灝嗘暟鎹漿鎹負 0..1 鎴?-1..1 鐨勮寖鍥淬傛鎬佸寲鍚庣殑鏁版嵁鍙互榪涜鍘繪鎬佸寲錛屽嵆杞崲鍥炲師鏉ョ殑鑼冨洿銆?br />
The cron4j main entity is the scheduler. With a it.sauronsoftware.cron4j.Scheduler instance you can execute tasks at fixed moments, during all the year. A scheduler can execute a task once a minute, once every five minutes, Friday at 10:00, on February the 16th at 12:30 but only if it is Saturday, and so on.
The use of the cron4j scheduler is a four steps operation:
Consider this simple example:
import it.sauronsoftware.cron4j.Scheduler; public class Quickstart { public static void main(String[] args) { // Creates a Scheduler instance. Scheduler s = new Scheduler(); // Schedule a once-a-minute task. s.schedule("* * * * *", new Runnable() { public void run() { System.out.println("Another minute ticked away..."); } }); // Starts the scheduler. s.start(); // Will run for ten minutes. try { Thread.sleep(1000L * 60L * 10L); } catch (InterruptedException e) { ; } // Stops the scheduler. s.stop(); } }
This example runs for ten minutes. At every minute change it will print the sad (but true) message "Another minute ticked away...".
Some other key concepts:
A UNIX crontab-like pattern is a string split in five space separated parts. Each part is intended as:
The star wildcard character is also admitted, indicating "every minute of the hour", "every hour of the day", "every day of the month", "every month of the year" and "every day of the week", according to the sub-pattern in which it is used.
Once the scheduler is started, a task will be launched when the five parts in its scheduling pattern will be true at the same time.
Scheduling patterns can be represented with it.sauronsoftware.cron4j.SchedulingPattern instances. Invalid scheduling patterns are cause of it.sauronsoftware.cron4j.InvalidPatternExceptions. The SchedulingPattern class offers also a static validate(String) method, that can be used to validate a string before using it as a scheduling pattern.
Some examples:
5 * * * *
This pattern causes a task to be launched once every hour, at the begin of the fifth minute (00:05, 01:05, 02:05 etc.).
* * * * *
This pattern causes a task to be launched every minute.
* 12 * * Mon
This pattern causes a task to be launched every minute during the 12th hour of Monday.
* 12 16 * Mon
This pattern causes a task to be launched every minute during the 12th hour of Monday, 16th, but only if the day is the 16th of the month.
Every sub-pattern can contain two or more comma separated values.
59 11 * * 1,2,3,4,5
This pattern causes a task to be launched at 11:59AM on Monday, Tuesday, Wednesday, Thursday and Friday.
Values intervals are admitted and defined using the minus character.
59 11 * * 1-5
This pattern is equivalent to the previous one.
The slash character can be used to identify step values within a range. It can be used both in the form */c and a-b/c. The subpattern is matched every c values of the range 0,maxvalue or a-b.
*/5 * * * *
This pattern causes a task to be launched every 5 minutes (0:00, 0:05, 0:10, 0:15 and so on).
3-18/5 * * * *
This pattern causes a task to be launched every 5 minutes starting from the third minute of the hour, up to the 18th (0:03, 0:08, 0:13, 0:18, 1:03, 1:08 and so on).
*/15 9-17 * * *
This pattern causes a task to be launched every 15 minutes between the 9th and 17th hour of the day (9:00, 9:15, 9:30, 9:45 and so on... note that the last execution will be at 17:45).
All the fresh described syntax rules can be used together.
* 12 10-16/2 * *
This pattern causes a task to be launched every minute during the 12th hour of the day, but only if the day is the 10th, the 12th, the 14th or the 16th of the month.
* 12 1-15,17,20-25 * *
This pattern causes a task to be launched every minute during the 12th hour of the day, but the day of the month must be between the 1st and the 15th, the 20th and the 25, or at least it must be the 17th.
Finally cron4j lets you combine more scheduling patterns into one, with the pipe character:
0 5 * * *|8 10 * * *|22 17 * * *
This pattern causes a task to be launched every day at 05:00, 10:08 and 17:22.
The simplest manner to build a task is to implement the well-known java.lang.Runnable interface. Once the task is ready, it can be scheduled with the it.sauronsoftware.cron4j.Scheduler.schedule(String, Runnable) method. This method throws an it.sauronsoftware.cron4j.InvalidPatternException when the supplied string does not represent a valid scheduling pattern.
Another way to build a task is to extend the it.sauronsoftware.cron4j.Task abstract class, which is more powerful and let the developer access some other cron4j features. This is better discussed in the "Building your own task" paragraph. Task instances can be scheduled with the schedule(String, Task) and the schedule(SchedulingPattern, Task) methods.
Scheduling methods available in the scheduler always return an ID used to recognize and retrieve the scheduled operation. This ID can be used later to reschedule the task (changing its scheduling pattern) with the reschedule(String, String) or the reschedule(String, SchedulingPattern) methods, and to deschedule the task (remove the task from the scheduler) with the deschedule(String) method.
The same ID can also be used to retrieve the scheduling pattern associated with a scheduled task, with the getSchedulingPattern(String) method, or to retrieve the task itself, with the getTask(String) method.
System processes can be easily scheduled using the ProcessTask class:
ProcessTask task = new ProcessTask("C:\\Windows\\System32\\notepad.exe"); Scheduler scheduler = new Scheduler(); scheduler.schedule("* * * * *", task); scheduler.start(); // ...
Arguments for the process can be supplied by using a string array instead of a single command string:
String[] command = { "C:\\Windows\\System32\\notepad.exe", "C:\\File.txt" }; ProcessTask task = new ProcessTask(command); // ...
Environment variables for the process can be supplied using a second string array, whose elements have to be in the NAME=VALUE form:
String[] command = { "C:\\tomcat\\bin\\catalina.bat", "start" }; String[] envs = { "CATALINA_HOME=C:\\tomcat", "JAVA_HOME=C:\\jdks\\jdk5" }; ProcessTask task = new ProcessTask(command, envs); // ...
The default working directory for the process can be changed using a third parameter in the constructor:
String[] command = { "C:\\tomcat\\bin\\catalina.bat", "start" }; String[] envs = { "CATALINA_HOME=C:\\tomcat", "JAVA_HOME=C:\\jdks\\jdk5" }; File directory = "C:\\MyDirectory"; ProcessTask task = new ProcessTask(command, envs, directory); // ...
If you want to change the default working directory but you have not any environment variable, the envs parameter of the constructor can be set to null:
ProcessTask task = new ProcessTask(command, null, directory);
When envs is null the process inherits every environment variable of the current JVM:
Environment variables and the working directory can also be set by calling the setEnvs(String[]) and setDirectory(java.io.File) methods.
The process standard output and standard error channels can be redirected to files by using the setStdoutFile(java.io.File) and setStderrFile(java.io.File) methods:
ProcessTask task = new ProcessTask(command, envs, directory); task.setStdoutFile(new File("out.txt")); task.setStderrFile(new File("err.txt"));
In a siminal manner, the standard input channel can be read from an existing file, calling the setStdinFile(java.io.File) method:
ProcessTask task = new ProcessTask(command, envs, directory); task.setStdinFile(new File("in.txt"));
The cron4j scheduler can also schedule a set of processes from a file.
You have to prepare a file, very similar to the ones used by the UNIX crontab, and register it in the scheduler calling the scheduleFile(File) method. The file can be descheduled by calling the descheduleFile(File) method. Scheduled files can be retrieved by calling the getScheduledFiles() method.
Scheduled files are parsed every minute. The scheduler will launch every process declared in the file whose scheduling pattern matches the current system time.
Syntax rules for cron4j scheduling files are reported in the "Cron parser" paragraph.
A java.lang.Runnable object is the simplest task ever possible, but to gain control you need to extend the it.sauronsoftware.cron4j.Task class. In the plainest form, implementing Runnable or extending Task are very similar operations: while the first requires a run() method, the latter requires the implementation of execute(TaskExecutionContext). The execute(TaskExecutionContext) method provides a it.sauronsoftware.cron4j.TaskExecutionContext instance, which the Runnable.run() method does not provide. The context can be used in the following ways:
A task can communicate with its executor, by notifying its internal state with a textual description. This is called status tracking. If you are interested in supporting status tracking in your task, you have to override the supportsStatusTracking() method, which should return true. Once this has been done, within the execute(TaskExecutionContext) method you are enabled to call the context setStatusMessage(String) method. This will propagate your task status message to its executor. The status message, through the executor, can be retrieved by an external user (see the "
A task can communicate with its executor, by notifying its completeness level with a numeric value. This is called completeness tracking. If you are interested in supporting completeness tracking in your task, you have to override the supportsCompletenessTracking() method, which should return true. Once this has been done, within the execute(TaskExecutionContext) method you are enabled to call the context setCompleteness(double) method, with a value between 0 and 1. This will propagate your task completeness level to its executor. The completeness level, through the executor, can be retrieved by an external user (see the "
A task can be optionally paused. If you are interested in supporting pausing and resuming in your task, you have to override the canBePaused() method, which should return true. Once this has been done, within the execute(TaskExecutionContext) method you have to periodically call the context pauseIfRequested() method. This will pause the task execution until it will be resumed (or stopped) by an external user (see the "
A task can be optionally stopped. If you are interested in supporting stopping in your task, you have to override the canBeStopped() method, which should return true. Once this has been done, within the execute(TaskExecutionContext) method you have to periodically call the context isStopped() method. This will return true when the execution has be demanded to be stopped by an external user (see the "
Through the context, the task can retrieve the scheduler, calling getScheduler().
Through the context, the task can retrieve its executor, calling getTaskExecutor().
A custom task can be scheduled, launched immediately or returned by a task collector.
You can build and plug within the scheduler your own task source, via the task collector API.
The cron4j scheduler supports the registration of one or more it.sauronsoftware.cron4j.TaskCollector instances, with the addTaskCollector(TaskCollector) method. Registered collectors can be retrieved with the scheduler getTaskCollectors() method. A previously registered collector can be removed from the scheduler with the removeTaskCollector(TaskCollector) method. Collectors can be added, queried or removed at every moment, also when the scheduler is started and it is running.
Each registered task collector is queried by the scheduler once a minute. The scheduler calls the collector getTasks() method. The implementation must return a it.sauronsoftware.cron4j.TaskTable instance. A TaskTable is a table that associates tasks and scheduling patterns. The scheduler, once the table has been retrieved, will examine the reported entries, and it will execute every task whose scheduling pattern matches the current system time.
A custom collector can be used to tie the scheduler with an external task source, i.e. a database or a XML file, which can be managed and changed in its contents also at run time.
The it.sauronsoftware.cron4j.SchedulerListener API can be used to listen to scheduler events.
The SchedulerListener interface requires the implementation of the following methods:
taskLaunching(TaskExecutor)
This one is called every time a task is launched by the scheduler.
taskSucceeded(TaskExecutor)
This one is called every time a task execution has been successfully completed.
taskFailed(TaskExecutor, Throwable)
This one is called every time a task execution fails due to an uncaught exception.
See the " Once your SchedulerListener instance is ready, you can register it on a Scheduler object by calling its addSchedulerListener(SchedulerListener) method. Already registered listeners can be removed by calling the removeSchedulerListener(SchedulerListener) method. The scheduler can also give back any registered listener, with the getSchedulerListeners() method. SchedulerListeners can be added and removed at every moment, also while the scheduler is running.
The scheduler, once it has been started and it is running, can be queried to give back its executors. An executor is similar to a thread. Executors is used by the scheduler to execute tasks.
By calling the Scheduler.getExecutingTasks() method you can obtain the currently ongoing executors.
You can also obtain an executor through a SchedulerListener instance (see the "Building your own scheduler listener" paragraph).
Each executor, represented by a it.sauronsoftware.cron4j.TaskExecutor instance, performs a different task execution.
The task can be retrieved with the getTask() method.
The executor status can be checked with the isAlive() method: it returns true if the executor is currently running.
If the executor is running, the current thread can be paused until the execution will be completed, calling the join() method.
The supportsStatusTracking() method returns true if the currently executing task supports status tracking. It means that the task communicates to the executor its status, represented by a string. The current status message can be retrieved by calling the executor getStatusMessage() method.
The supportsCompletenessTracking() method returns true if the currently executing task supports completeness tracking. It means that the task communicates to the executor its own completeness level. The current completeness level can be retrieved by calling the executor getCompleteness() method. Returned values are between 0 (task just started and still nothing done) and 1 (task completed).
The canBePaused() method returns true if the currently executing task supports execution pausing. It means that the task execution can be paused by calling the executor pause() method. The pause status of the executor can be checked with the isPaused() method. A paused executor can be resumed by calling its resume() method.
The canBeStopped() method returns true if the currently executing task supports execution interruption. It means that the task execution can be stopped by calling the executor stop() method. The interruption status of the executor can be checked with the isStopped() method. Stopped executors cannot be resumed.
The getStartTime() method returns a time stamp reporting the start time of the executor, or a value less than 0 if the executor has not been yet started.
The getScheduler() method returns the scheduler which is the owner of the executor.
The getGuid() method returns a textual GUID for the executor.
Executors offer also an event-driven API, through the it.sauronsoftware.cron4j.TaskExecutorListener class. A TaskExecutorListener can be added to a TaskExecutor with its addTaskExecutorListener(TaskExecutorListener) method. Listeners can be removed with the removeTaskExecutorListener(TaskExecutorListener) method, and they can also be retrieved with the getTaskExecutorListeners() method. A TaskExecutorListener must implement the following methods:
executionPausing(TaskExecutor)
Called when the executor is requested to pause the ongoing task. The given parameter represents the source TaskExecutor instance.
executionResuming(TaskExecutor)
Called when the executor is requested to resume the execution of the previously paused task. The given parameter represents the source TaskExecutor instance.
executionStopping(TaskExecutor)
Called when the executor is requested to stop the task execution. The given parameter represents the source TaskExecutor instance.
executionTerminated(TaskExecutor, Throwable)
Called when the executor has completed the task execution. The first parameter represents the source TaskExecutor instance, while the second is the optional exception that has caused the task to be terminated. If the task has been completed successfully, the given value is null.
statusMessageChanged(TaskExecutor, String)
Called every time the execution status message changes. The first parameter represents the source TaskExecutor instance, while the second is the new message issued by the task.
completenessValueChanged(TaskExecutor, double)
Called every time the execution completeness value changes. The first parameter represents the source TaskExecutor instance, while the second is the new completeness value (between 0 and 1) issued by the task.
If the scheduler is started and running, it is possible to manually launch a task, without scheduling it with a pattern. The method is Scheduler.launch(Task). The task will be immediately launched, and a TaskExecutor instace is returned to the caller. The returned object can be used to control the task execution (see the "
Scheduler instances, by default, work with the system default Time Zone. I.e. a scheduling pattern whose value is 0 2 * * * will activate its task at 02:00 AM according to the default system Time Zone. The scheduler can be requested to work with a different Time Zone, which is not the system default one. Call Scheduler.setTimeZone(TimeZone) and Scheduler.getTimeZone() to control this feature.
Once the default Time Zone has been changed, system current time is adapted to the supplied zone before comparing it with registered scheduling patterns. The result is that any supplied scheduling pattern is treated according to the specified Time Zone. Suppose this situation:
The scheduler, before comparing system time with patterns, translates 10:00 from GMT+1 to GMT+3. It means that 10:00 becomes 12:00. The resulted time is then used by the scheduler to activate tasks. So, in the given configuration at the given moment, any task scheduled as 0 12 * * * will be executed, while any 0 10 * * * will not.
The Java Virtual Machine exits when the only threads running are all daemon threads. The cron4j scheduler can be configured to spawn only daemon threads. To control this feature call the Scheduler.setDaemon(boolean) method. This method must be called before the scheduler is started. Default value is false. To check the scheduler current daemon status call the Scheduler.isDaemon() method.
The it.sauronsoftware.cron4j.Predictor class is able to predict when a scheduling pattern will be matched.
Suppose you want to know when the scheduler will execute a task scheduled with the pattern 0 3 * jan-jun,sep-dec mon-fri. You can predict the next n execution of the task using a Predictor instance:
String pattern = "0 3 * jan-jun,sep-dec mon-fri"; Predictor p = new Predictor(pattern); for (int i = 0; i < n; i++) { System.out.println(p.nextMatchingDate()); }
The it.sauronsoftware.cron4j.CronParser class can be used to parse crontab-like formatted file and character streams.
If you want to schedule a list of tasks declared in a crontab-like file you don't need the CronParser, since you can do it by adding the file to the scheduler, with the Scheduler.scheduleFile(File) method.
Consider to use the CronParser if the Scheduler.scheduleFile(File) method is not enough for you. In example, you may need to fetch the task list from a remote source which is not representable as a java.io.File object (a document on a remote server, a DBMS result set and so on). To solve the problem you can implement your own it.sauronsoftware.cron4j.TaskCollector, getting the advantage of the CronParser to easily parse any crontab-like content.
You can parse a whole file/stream, but you can also parse a single line.
A line can be empty, can contain a comment or it can be a scheduling line.
A line containing no characters or a line with only space characters is considered an empty line.
A line whose first non-space character is a number sign (#) is considered a comment.
Empty lines and comment lines are ignored by the parser.
Any other kind of line is parsed as a scheduling line.
A valid scheduling line respects the following structure:
scheduling-pattern [options] command [args]
After the scheduling pattern item, other tokens in each line are space separated or delimited with double quotation marks (").
Double quotation marks delimited items can take advantage of the following escape sequences:
The options token collection can include one or more of the following elements:
It is also possible to schedule the invocation of a method of a Java class in the scope of the parser ClassLoader. The method has to be static and it must accept an array of strings as its sole argument. To invoke a method of this kind the syntax is:
scheduling-pattern java:className#methodName [args]
The #methodName part can be omitted: in this case the main(String[]) method will be assumed.
Please note that static methods are invoked within the scheduler same JVM, without spawning any external process. Thus IN, OUT, ERR, ENV and DIR options can't be applied.
Invalid scheduling lines are discarded without blocking the parsing procedure, but an error message is sent to the application standard error channel.
Valid examples:
0 5 * * * sol.exe 0,30 * * * * OUT:C:\ping.txt ping 10.9.43.55 0,30 4 * * * "OUT:C:\Documents and Settings\Carlo\ping.txt" ping 10.9.43.55 0 3 * * * ENV:JAVA_HOME=C:\jdks\1.4.2_15 DIR:C:\myproject OUT:C:\myproject\build.log C:\myproject\build.bat "Nightly Build" 0 4 * * * java:mypackage.MyClass#startApplication myOption1 myOption2
闃塊噷浜戞槸鏈榪戞柊鍑虹殑涓涓暅鍍忔簮銆傚緱鐩婁笌闃塊噷浜戠殑楂橀熷彂灞曪紝榪欎箞澶х殑闇姹傦紝鑲畾浼氭帹鍑鴻嚜宸辯殑闀滃儚婧愩?br style="padding: 0px; margin: 0px;" />闃塊噷浜慙inux瀹夎闀滃儚婧愬湴鍧錛歨ttp://mirrors.aliyun.com/
CentOS緋葷粺鏇存崲杞歡瀹夎婧?br style="padding: 0px; margin: 0px;" />絎竴姝ワ細澶囦喚浣犵殑鍘熼暅鍍忔枃浠訛紝浠ュ厤鍑洪敊鍚庡彲浠ユ仮澶嶃?/p>
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
絎簩姝ワ細涓嬭澆鏂扮殑CentOS-Base.repo 鍒?etc/yum.repos.d/
CentOS 5
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-5.repo
CentOS 6
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
絎笁姝ワ細榪愯yum makecache鐢熸垚緙撳瓨
yum clean all
yum makecache
CentOS/RHEL 7.x:
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm |
CentOS/RHEL 6.x:
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm rpm -Uvh https://mirror.webtatic.com/yum/el6/latest.rpm |
CentOS/RHEL 5.x:
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-5.noarch.rpm rpm -Uvh http://mirror.webtatic.com/yum/el5/latest.rpm |
Now you can install PHP 5.5’s mod_php SAPI (along with an opcode cache) by doing:
yum install php55w php55w-opcache |
You can alternatively install PHP 5.5’s php-fpm SAPI (along with an opcode cache by doing: