DOS script 裡含空白路徑的處理

繼上回 DOS script 裡迴圈的神奇語法, 學到了 :

setlocal enabledelayedexpansion

這回又踢到鐵板了,

跟上回幾乎一樣的 script, 不過路徑變長了, 而且裡頭有空白 ... like

set JAVA_HOME=C:\Program Files (x86)\IBM\WebSphere\AppServer\java

一跑迴圈又掛了,

ref windows批处理中对带空格路径的处理 這篇, 一開始沒讀完整, 只看到用短路徑就搞定, 手動在那兒切了半天取到短路徑, 果然就會 work,

再仔細謮了一下, 原來不用這麻人工, 只要用下列指令 :

set JAVA_HOME=C:\Program Files (x86)\IBM\WebSphere\AppServer\java
rem ----- convert to short name -----
for %%x in ("%JAVA_HOME%") do set JAVA_HOME=%%~sx

就可以把路徑轉換成短路徑 !!

JAVA_HOME=c:\PROGRA~2\IBM\WEBSPH~1\APPSER~1\java

厚, 這 windows 的 script 還真不是普通的麻煩 ~~~

使用 java axis 呼叫 .net web service 全記錄

由於手邊的某個案子需要用 java 去 call .net 的 web service,
上網 google 了半天之後得到一個 workable 的做法 ...

種類 1 - String HelloWorld(String param1) : 

String wsSoapAction = "http://tempuri.org/";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress(wsUrl);
call.setUseSOAPAction(true);
call.setOperationName(new QName(wsSoapAction, "HelloWorld")); // 設置要調用哪個方法
// 設置要傳遞的參數
call.addParameter(
new QName(wsSoapAction, "param1"),
org.apache.axis.encoding.XMLType.XSD_STRING,
javax.xml.rpc.ParameterMode.IN);
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING); // 標準字串
call.setUseSOAPAction(true);
call.setSOAPActionURI(wsSoapAction + "HelloWorld");
String sRtn = (String) call.invoke(new Object[] { "this is a param" }); // 調用方法並傳遞參數

種類 2 - DataSet HelloWorld(String param1) : 這回傳的居然是 .net vb 直接 select database 的 dataSet, 它是以 xml 格式呈現, 同上面只是把 returnType 改成 :

...
call.setReturnType(org.apache.axis.encoding.XMLType.XSD_SCHEMA);  // DataSet (XML)
...
Schema schema = (Schema) call.invoke(new Object[] { "test_id" }); // 調用方法並傳遞參數

回傳的東東用這樣去處理 :
MessageElement[] me = schema.get_any();
List head = me[0].getChildren(); // header/schema
List body = me[1].getChildren(); // data
if (body != null && body.size() > 0) {
NodeList node = me[1].getChildNodes().item(0).getChildNodes();
for (int i=0; i NodeList node1 = node.item(i).getChildNodes();
for (int j=0; jnode1.getLength(); j++) {

Node n = node1.item(j);
String name = n.getNodeName();
String value = n.getFirstChild() == null?"":n.getFirstChild().getNodeValue();
log.debug("name="+name+",value="+value);
}
}
}

這樣取值的原因是 .net 的 dataSet xml 長這樣 ... (第一個 element 是 schema, 第二個 element 是 data)



------------------------------------------------------------------------------
(以上是第一次開發的記錄)

過了兩年之後, 發現了另外一種方法, 可以大幅簡化開發, 就是直接使用 wsdl gen 出 java class :

step 1, 先取得 .net web service 的 wsdl, 在 service 的測試頁


點第一行的 "服務描述", 就可以得到 wsdl, 另存新檔 xxxx.wsdl, 丟進 eclipse 的專案中


step 2, 在 eclipse 裡 gen 出 web service client :


這樣 gen 出對應的 class 之後, 之前相同的 method 只需要這樣寫 :
(那 package name 取決於原始 web service 設定的 namespace, org.tempuri 都是偷懶沒改的)

org.tempuri.Service service = new org.tempuri.ServiceLocator(qsURL);
org.tempuri.ServiceSoap ss = service.getServiceSoap();
String rtn = ss.HelloWorld("this is a param");

簡潔了許多

----------------------------------------------------------------------------
最新的一個難題是 : input 參數中有一個 type 是 DataSet !!

一樣取得 wsdl gen 出 web service client 之後, 不知道要怎麻組出, .net 認得的 dataSet xml ...
只好拿另一個回傳的 dataSet, show 出 xml, 一個一個比對, 把它兜出來 ...
中間還試過, 直接拿 xml 字串 parse 成 MessageElement, 吐出來的 xml 明明就很像, 可是 service 就是無法執行, like this ...

Document XMLDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xmlString)));
Element element = XMLDoc.getDocumentElement();
_any[0] = new MessageElement(element);

拼拼湊湊了半天, 以下的 code 終於 work, .net web service 可以接下 java 傳過去的 DataSet :

org.tempuri.TestService service = new org.tempuri.TestServiceLocator(qsURL);
org.tempuri.TestServiceSoap ss = service.getTestServiceSoap();

// 取回 dataSet 用來比對我們要產生的 dataSet
TestServiceGetDetailResponseTestServiceGetDetailResult x = ss.TestServiceGetDetail(oSchoolId);

TestSendSDataSet sDataSet = new TestSendSDataSet();
MessageElement[] _any = new MessageElement[2];

// schema declare
_any[0] = new MessageElement("schema", "xs", "http://www.w3.org/2001/XMLSchema");
_any[0].addNamespaceDeclaration("msdata", "urn:schemas-microsoft-com:xml-msdata");
SOAPElement se = _any[0].addChildElement("element");
se.setAttribute("name", "NewDataSet");
se.setAttribute("msdata:IsDataSet", "true");
se.setAttribute("msdata:UseCurrentLocale", "true");
se = se.addChildElement("complexType").addChildElement("choice").addChildElement("element");
se.setAttribute("name", "Table");
se = se.addChildElement("complexType").addChildElement("sequence");
se.addChildElement("element").setAttribute("name", "school_id");
se.addChildElement("element").setAttribute("name", "school_user");

// data
_any[1] = new MessageElement("diffgram", "diffgr", "urn:schemas-microsoft-com:xml-diffgram-v1");
_any[1].addNamespaceDeclaration("msdata", "urn:schemas-microsoft-com:xml-msdata");
se = _any[1].addChildElement("NewDataSet", "", "").addChildElement("Table");
se.addChildElement("school_id").addTextNode("123456");
se.addChildElement("school_user").addTextNode("林木森");
sDataSet.set_any( _any );
System.out.println("xml10="+x.get_any()[0].toString());
System.out.println("xml11="+sDataSet.get_any()[0].toString());
System.out.println("xml20="+x.get_any()[1].toString());
System.out.println("xml21="+sDataSet.get_any()[1].toString());

sRtn = ss.TestSend(sDataSet);

----------------------------------------------------------------------------------------------

下回應該也把我們家對外的 service 介面加個這標準的東東才對,
現在的介面實在太低級了

DOS script 裡迴圈的神奇語法

原本在 linux 上跑得好好的 shell,
突然因為需要得搬到 windows server 上跑
只好把它改成 .bat

一個很 ez 的迴圈 assign classpath 的動作
在 dos 上居然怎麻跑都不對勁,
剛改完的 .bat :

@echo off
set CLASSPATH=.;c:\tomcat\webapps\abc\WEB-INF\classes
set MYDIR=d:\tmp\cd
for %%x in (%MYDIR%\*.jar) do (
  echo %%x
  set CLASSPATH=!CLASSPATH!;%%x
  echo %CLASSPATH%
)
echo %CLASSPATH%
執行結果 :

E:\tmp>test.bat
d:\tmp\cd\common-lib1.jar
.;c:\tomcat\webapps\abc\WEB-INF\classes
d:\tmp\cd\common-lib2.jar
.;c:\tomcat\webapps\abc\WEB-INF\classes
d:\tmp\cd\common-lib3.jar
.;c:\tomcat\webapps\abc\WEB-INF\classes
!CLASSPATH!;d:\tmp\cd\common-lib3.jar
感覺只有最後一次迴圈的 assign 有作用,
google 了半天, 發現這個東東 ...

setlocal enabledelayedexpansion

一加上去馬上 work, 至於解釋, 看嘸, 也懶得看了 >__<

@echo off
setlocal enabledelayedexpansion
set CLASSPATH=.;c:\tomcat\webapps\abc\WEB-INF\classes
set MYDIR=d:\tmp\cd
for %%x in (%MYDIR%\*.jar) do (
  echo %%x
  set CLASSPATH=!CLASSPATH!;%%x
  echo %CLASSPATH%
)
echo %CLASSPATH%

執行結果 :

E:\tmp>test.bat
d:\tmp\cd\common-lib1.jar
.;c:\tomcat\webapps\abc\WEB-INF\classes
d:\tmp\cd\common-lib2.jar
.;c:\tomcat\webapps\abc\WEB-INF\classes
d:\tmp\cd\common-lib3.jar
.;c:\tomcat\webapps\abc\WEB-INF\classes
.;c:\tomcat\webapps\abc\WEB-INF\classes;d:\tmp\cd\common-lib1.jar;d:\tmp\cd\common-lib2.jar;d:\tmp\cd\common-lib3.jar


WTF DOS !!!

無敵健康之世界末日3 ~ 單車篇

跑步跑了一陣子之後, 我發現了幾件事,
其實大尖山的上坡用跑的沒啥意義 @
因為用快走的比用跑的還快, 反而跑的是浪費力氣跟心跳 >___<

然後我的下半身肌耐力不夠, 沒辦法進步
於是我想用騎車的方式來加強, but ............ 我沒有厲害的單車 >___<
so, 我先用家裡唯一的菜藍車來爬大尖山 ......... wahaha
一樣是比照之前跑大尖山的步驟, 用盡全身的力氣, 每天多爬一點點
忘了 n 天之後, 終於是沒命地爬到登山口 ....



-----------------------------------------------------------------------------------
這種殺豬公式的訓練方法實在不行, 我都踩到心臟要停了, 才只有這樣的效果
我得試試用正常的車子才行
問過了恰恰, 它說不用到公路車, 連小折騎起來都比我家這台輕鬆很多
於是我把腦筋動到村仔的小折上,
問了一下它也很久沒騎了, 先借來試試再說 ...
村仔說 ~ 大尖山太硬了, 要我先從汐平公路開始騎

剛好又到了年底 ~ 該是把年假好好的花光的時候
so 我騎了三次, 每次增加一些距離的方式, 用盡了所有的精神及毅力
終於給我要死不活地騎上汐平公路上的觀景台
當看到那幾支石頭做的動物時, 心裡真是超感人的,
沒想到我這雙腳肉腳, 也能踩得上來,
之前開車上來時, 根本沒感覺這是在山頂 @____@,
就是老覺得它沒那麻高 ~~~ 怎麻會怎麻騎都騎不到咧 ~~~~

還有就是那沿路上的野狗, 人家就在踩不動了,
它還呼朋引伴叫來一大群對著你狂叫 ....
真是叫人進退兩難, 騎得心驚膽跳 >______<


2012/12/14 @ 姜子頭展望台
------------------------------------------------------------------------------

下一個目標是傳說的風櫃嘴 ...
這地方也真神奇 ~ 有 n 條路線可以上去
一般人說的是從 故宮那兒上去, wallace 每天騎的是從內湖上去
結果它就是汐萬路上去賣地瓜湯那兒, 指的都是同一地點
過了一個禮拜, 我就去挑戰那兒了,
結果太晚出門, 最後看到這牌子時就回頭了 >___<


2012/12/21 @ 汐萬路, 離目標還有4公里

真不知這是用來鼓勵人, 還是勸人回家的 >_<
下回再戰 ...

------------------------------------------------------------------------------
很快又過了一個禮拜, 已經上完最後一天班要放假放到明年了,

本來只是想試試 ~ 平路單車 40km 能不能騎得完 & 看看騎多久
加上天氣不錯, 於是就沿著基隆河東岸騎,

到了大直橋, 其實已經算是我的折返點了, 到這兒剛好 20km
結果坐下來休息一下之後, 又感覺活力十足 ......
於是就想著再多騎一點好了, 就這麻多一點 ~ 多一點地騎到了北投
想想再一點點就到淡水了, 一直說要騎到淡水的, 錯過了今天, 下回不知何時了,
so ...... 又這麻一路 "ㄌㄨ" 到漁人碼頭 ....




2012/12/29 @ 淡水漁人碼頭

快 20 年沒回來這兒,
瞄了一眼當兵時的部隊, 勤務連還是一樣的建築,
倒是青溪樓好像打掉蓋新的, 更像是飯店了

東晃晃西晃晃地拍個照, 其實到這兒已經花了快 3 小時了
也來不及在這兒吃個東東又急著沿原路騎回家
怕是太晚了路會太暗不好走 ...

沿途一座橋一座橋地慢慢數回家, 雙腿覺得有愈來愈沒力的感覺 >___<
屁屁也愈來愈痛, 停下來休息都只是為了讓屁屁動一下 ...
之前賢龍老是叫說風大騎不動, 我都還笑它騙阿才, 今天算是真的見識到
只不過怪的是, 怎麻我去程也逆風, 回程也逆風, 那有人家這樣 ...

整路也看到很多在練長跑的人, 真是不錯, 可惜我前一天沒跑成 ... :D
使出最後吃奶的力氣拼回家, 最後直接抄近路走新台五路
今日距離 : 86km, 5h50m, waha >___<

無敵健康之世界末日2 - 大尖山路跑

話說從日月潭回來之後, 一直覺得牽車那段實在是 ~~ 太遜了
為了要一雪前恥, 於是我又開始了另一階段的 ~~ 運動
想說既然是腿這麻沒力, 就來加強腿力吧
於是我決定開始認真跑步, 套一句九把刀的話 :
我這個人認真起來可是連自己都會害怕的, waha
挑的路線就是我走了 30 多年的大尖山 ...
(說起來還真有點白吃 ....)

第一天, 我只跑了 50 公尺吧 .... >______<
從剛一開始上坡開始算, 連第一個轉彎都還沒過
剩下的全都用走的

第二回, 跑到了賣甕仔雞那兒 ... (~ 150m)

過了快兩個禮拜 ~~ 我終於可以一口氣跑到登山口的廟那裡 ... (也不過才 300m)

中間穿插了弟弟的報到, 中斷了好長一段時間沒跑
後來等弟弟滿月了後, 才又有餘力可以開始跑 ~~

原本大尖山都是一大早跑的 ~~
有時興致來了 ~ 晚上也去大操場跟著一大堆人繞圈圈 (晚上人超多)
漸漸地圈圈愈繞愈多圈, 可是又覺得太無聊
於是又跑到國泰後面的河濱跑, 一樣不少人在那兒運動咧
而且那兒跑起來覺得比較快 ...

大約就這樣跑又了兩個月,
平地的距離達到 10km 的目標, 大尖山也愈爬愈高了 ....
從原來的登山口 ~ 進步到 馥記山莊, 再進步到 涼亭一號
(可惜這似乎是我的極限了, 本來我的目標是要一口氣跑到天秀宮的 >__<)
--------------------------------------------------------------------

興奮的是有一天在 01 發現了 ~~~ "大尖山路跑賽" !!
這條我的私房路線居然可以辦路跑咧, 當然我就給它報名體驗一下了 (5km 快樂組)
沒想到活動當天 ...................................
居然是這個冬天最冷的一天還沒關係 ~~ 它還下雨 >____<
半夜四點就醒過來 ~ 開始內心交戰到 6 點,
去/不去/去/不去/去/不去 ......
還好最後還是決定穿上雨衣 ~~ 沒做出讓自己後悔的事

12度的雨天, 清晨 6:30 天都還是暗的,
沒想到一走進秀峰國小, 就被滿滿的人潮感動到了
原來還有這麻多比我更熱血的人, 突然間 ~ 我後悔了, 後悔沒報 17.5km 的 >___<
有將近 2000 個人一同跑這熟悉的路線, 感覺真是奇妙
雖然是冷到雙手都要沒知覺了, 還是比平常時間快了一點 "走完" 這5km
拿了紀念品就馬上衝回家 ~ 等下還得趕去彤彤教會的活動
happy 的是, 我只要5分鐘就可以回家洗熱水澡了 ~~~ wahaha







2012/12/23 @ 大尖山路跑

看著其它人的熱血紀錄, 熱血17.5k一號熱血17.5k二號, 明年真想來挑戰一下呀

next ~ 單車篇