2014年2月28日 星期五

ANT - 出現錯誤error: constant string too long......Syntax error, parameterized types are only available if source level is 1.5 or greater


今天練習使用Ant 做Build,在compile的時候有錯誤:error: constant string too long
發生問題的訊息如下:

ReadInputDataTest.java:75: error: constant string too long

    [javac_data = "8220100300012013081400         154527          0       2797          0          0       2797        151730          08220100300012013081500         154527          0 
....
原來是_data這個數字assign的數值太長,無法compile,但是在eclipse上compile卻沒有任何問題,後來查詢原來是eclipse所使用的Compile並不是標準的jdk compile,因此會變成eclipse可以過Ant可以過,解決方式就是經查詢有兩種:
1.將原本assign constant的部分改為使用readFile
2.將eclipse所使用的compile

我選了第2個方式,解決方式如下:
1.不要使用eclipse的Ant Build
2.找出ANT_HOME的位置
3.下載ecj-4.2.1.jar 這個檔案(在spring與apache專案中都有<是不是4.2.1每個版本不同,端看使用版本而定>)
4.將ecj-4.2.1.jar此檔案置放於%ANT_HOME%\lib下
5.變更ant build.xml內容加上如下:
  


再來直接執行ant -file build.xml
但此時卻又出現另一個問題:Syntax error, parameterized types are only available if source level is 1.5 or greater

101. ERROR in /Users/wuanne/workspace/eclipse/CTCB_MI/New/CTBC_MI_Util/src/com/ctbc/util/xml/XmlProcess.java (at line 116)
    [javac] public static List<Node> selectNodesWithNameSpaceXML(Element ele,String szXpath,Map<String,String> uris){
    [javac]                    ^^^^
    [javac] Syntax error, parameterized types are only available if source level is 1.5 or greater

我實際上的確是使用jdk 1.7的版本卻報錯誤要我使用1.5以上?
解決方式就是在ant build.xml上加上使用版本的attr如下:
    
    ....
    

在上面直接加上target="1.7" 與source="1.7"的attr,
重新執行就解決囉~

2014年2月27日 星期四

linux - 如何找到佔據port的process並將它關閉?

參考:how to kill process running on particular port in linux?

直接貼解決方式:

Use the command
 netstat -plten |grep java
used grep java as tomcat uses java as their processes.
It will show the list of processes with port number and process id
tcp6       0      0 :::8080                 :::*                    LISTEN      
1000       30070621    16085/java
the number before /java is a process id. Now use kill command to kill the process
kill -9 16085
-9 implies the process will be killed forcefully.


2014年2月20日 星期四

dom4j - 新增,修改,刪除xml namespace屬性

新增:

Namespace ns2 = new Namespace("ns1","http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceBody");
((Element)nodeB).add(ns2);

修改:
Namespace ns2 = new Namespace("ns1","http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceBody");
QName newQName = new QName(nodeB.getName(), ns2);
((Element)nodeB).setQName(newQName);

刪除:
for(Namespace e : ((Element)nodeE).declaredNamespaces()){
  ((Element)nodeE).remove(e);
}

需注意的是,刪除,仍會保留當前使用的該namespace的定義,例如原有XML如下:

<ns0:ServiceEnvelope xmlns:ns0="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceEnvelope" xmlns:ns2="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/BSMF/ccMrchntProfileInqRq/01" xmlns:ns1="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceHeader">
</ns0:ServiceEnvelope >


但因為ServiceEnvelope本身是在ns0之下,因此就算執行了刪除,還是會保留住ns0的定義如下:
<ns0:ServiceEnvelope xmlns:ns0="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceEnvelope"></ns0:ServiceEnvelope >

如何以dom4j使用XPATH尋找擁有namespace的node節點?




<ns0:ServiceEnvelope
xmlns:ns0="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceEnvelope">
<ns1:ServiceHeader
xmlns:ns1="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceHeader">
<ns1:StandardType>BSMF</ns1:StandardType>
<ns1:StandardVersion>01</ns1:StandardVersion>
<ns1:ServiceName>ccMrchntProfileInq</ns1:ServiceName>
<ns1:ServiceVersion>01</ns1:ServiceVersion>
<ns1:SourceID>TWINMI</ns1:SourceID>
<ns1:TransactionID>INMI201402071434225</ns1:TransactionID>
<ns1:RqTimestamp>2014-02-07T14:34:25.11+08:00</ns1:RqTimestamp>
</ns1:ServiceHeader>

<ns1:ServiceBody
xmlns:ns1="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceHeader">
<ns2:ccMrchntProfileInqRq
xmlns:ns2="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/BSMF/ccMrchntProfileInqRq/01">
<ns2:REQHDR>
<ns2:TrnNum>INMI201402071434239</ns2:TrnNum>
<ns2:TrnCode>JCMI</ns2:TrnCode>
</ns2:REQHDR>
<ns2:REQBDY>
<ns2:FunCode>I</ns2:FunCode>
<ns2:MerchNBR>010100028</ns2:MerchNBR>
</ns2:REQBDY>
</ns2:ccMrchntProfileInqRq>
</ns1:ServiceBody>
</ns0:ServiceEnvelope>

(上述XML不知道要怎麼在blog中下語法如之前那樣貼...只好貼無排版純文字了...)

因為上述的<ServiceBody>我需要將其中的namespace換成xmlns:ns1="http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceBody,原先我依照以前使用xPath的方式如下:


      
Node  nodeB = root.selectSingleNode("//ns0:ServiceEnvelope/ns1:ServiceBody");


然而,光直行道selectSingleNode(..)就跳出了exception:

org.dom4j.XPathException: Exception occurred evaluting XPath: /ns0:ServiceEnvelope/ns1:ServiceBody. Exception: XPath expression uses unbound namespace prefix ns1

,參考上述的網站說明,原來這種擁有namespace的,要先告知namespace實際上代表的位置在哪,才能做搜尋,修改後方式如下:

        DefaultXPath xpath = new DefaultXPath("//ns0:ServiceEnvelope/ns1:ServiceBody");
Map uris = new HashMap();
uris.put("ns0","http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceEnvelope");
uris.put("ns1", "http://ns.chinatrust.com.tw/XSD/CTCB/ESB/Message/EMF/ServiceHeader");
xpath.setNamespaceURIs(uris); 
Node nodeB = xpath.selectSingleNode(root.getDocument());  

因為此節點,在//ns0:ServiceEnvelope/ns1:ServiceBody的位置,一共使用了ns0與ns1的namespace,因此在setNamespaceURIs(Map)中要將兩個namespace都置入,才能找到,
若一次要找的是多個Node,使用selectNodes()即可(本例因為ServiceBody只會有一個,因此使用selectSingleNode()即可.


p.s:XML其實不是很好懂呢...這兩天花了不少時間看XSD,XML關於namespace的問題...

2014年2月12日 星期三

XMLHttpRequest執行AJAX 跨網域存取.無法讀取的問題...

參考:彭碰碰同事(XD)


與同事和做了一個小頁面,我負責webServer,但發現一個問題,AJAX執行跨網域時都會失敗...後來同事找到了解決方式,原來只要在response header中加入"Access-Control-Allow-Origin", "*" 就可以了,
因此我就將fiter加上此段:

 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {


  ((HttpServletResponse)response).addHeader("Access-Control-Allow-Origin", "*");

                //...
       }

這樣就可以了~~

一直想說要找個時間來好好把jquery研究一下,可是有時間的話我還是想把Junit那本給先啃完啊......(這段話好像與本文無關)



2014年2月3日 星期一

mybatis - 使用parameterType="String"時出現There is no getter for property named....

參考:Mybatis-There is no getter for property named 'XXX' in 'class java.lang.String'解决办法


問題:
原先mapper.xml如下
 
  
     CREATE TABLE IF NOT EXISTS  ${table}
 (
    SERIALID varchar(20) NOT NULL,
    ACTIONID varchar(10) NOT NULL
 );
    


但執行時會出現以下錯誤:

 Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'table' in 'class java.lang.String'...

(上述方式是因為測試需要在runtime時期建立不同的table,因此為了方便測試才使用這種接字串方式組Query帶值<使用${param}>)

出現:

 Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'table' in 'class java.lang.String'


解法:
將 ${table}修改為${_parameter}就可以了,更改後如下:

 
  
     CREATE TABLE IF NOT EXISTS  ${_parameter}
 (
    SERIALID varchar(20) NOT NULL,
    ACTIONID varchar(10) NOT NULL
 );
    

2014年2月1日 星期六

mybatis - INSERT NULL VALUE時出現:Cause: java.sql.SQLException: Unsupported SQL Type 1111


(這篇拖超久的了,都有點忘記,以後還是要趕快遇到問題馬上筆記啊!!!)

參考:mybatis 需要注意的点 MyBatis 插入空值时,需要指定JdbcType (201

問題:
 INSERT NULL VALUE時出現:Cause: java.sql.SQLException: Unsupported SQL Type 1111...的錯誤

解答:

原先mapper.xml如下:

    
   INSERT INTO MI_JCCKMPFD_MON (POST_YYYYMM, MERCH_ORG,MERCH_ID,GRANT_DATE) 
   VALUES ( #{_POST_YYYYMM}, #{_MERCH_ORG},  #{_MERCH_ID} , #{_GRANT_DATE}
    )
  
檢查了下語法,唯一會insertNull的就是GRANT_DATE 這個column,依照參考資料,在insert時加上指定jdbcType如下:
    
   INSERT INTO MI_JCCKMPFD_MON (POST_YYYYMM, MERCH_ORG,MERCH_ID,GRANT_DATE) 
   VALUES ( #{_POST_YYYYMM}, #{_MERCH_ORG},  #{_MERCH_ID} , #{_GRANT_DATE,jdbcType=DATE}
    )
  

就可以解決問題了~
(詳細說明可看參考網址)
但話說這個錯誤訊息實在很不明顯啊...什麼1111...