起因在於有莫名的堅持要弄一個純"Tag"的網頁...因為這郭系統是不做js/ajax的,很傳統的java網站(就是輸入值都要submit到server做檢查的那種~~)
然後講一講後端邏輯的部分不改,就只改前端的view.....造成只好要用自訂tag( custom tag)包掉原本的資料~
原本的資料本來就是動態的撈出來的~所以原本值就已經被struts的tag包起來,學struts包struts那樣子,想說包兩層應該很簡單(包兩層只要一個用小撇('),一個用("),他就會分出來了)~
可是我忘了偶自己寫的不是struts tag阿阿阿阿阿~~~~~
實作自訂Tag時,JSP也很乖的送了一字不漏的struts tag的文字進來了Orz...
最後想不出辦法來,只好硬解tag內容抓值了,就以會傳入的型式自己寫parser了Orz...
1. 先解析struts tag,反正就只抓property 的value
2. 輸入值抓出來後,就依其定義在JSP裡面抓值,只處理像這種情況的取值result.startDt.substring(0, 4),只有一層bean,也不處理array情況,bean也只能get一次,原本的定義應該是用while loop可以一直抓下去的~
request.getAttribute() --> bean --> getter --> substring
3. 前端呼叫的寫法
<my:year format='YYYY' value='<s:property value="result.startDt.substring(0, 4)" />' />
4. tld別忘了要做tag設定才會被讀入~
String getStrutsPropertyValue(String val) {
String re = "";
Document doc = null;
ByteArrayInputStream bis = null;
try {
val = "<root>"+val+"</root>"; //append to a normal xml format
bis = new ByteArrayInputStream(val.getBytes());
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(bis);
NodeList nl = doc.getElementsByTagName("s:property");
if(nl.getLength() > 0) {
String theValue = nl.item(0).getAttributes().getNamedItem("value").getNodeValue();
String[] sp = StringUtils.split(theValue,".");
if(sp.length > 0) {
Object obj0 = pageContext.getRequest().getAttribute(sp[0]);
if(obj0 != null && sp.length > 1) { //attribute is bean
String getter = "get"+sp[1].substring(0,1).toUpperCase()+sp[1].substring(1);
Object obj1 = obj0.getClass().getMethod(getter).invoke(obj0, null);
if(obj1 != null) {
re = obj1.toString();
}
if(sp.length > 2 && obj1 != null) { //string operation with bean property
if(sp[2].indexOf("substring") >= 0) { //support substring
String[] agrs = StringUtils.split(sp[2].substring( sp[2].indexOf("(")+1, sp[2].indexOf(")")),",");
Object obj2 = null;
if(agrs.length == 1) {
obj2 = obj1.getClass().getMethod("substring", int.class).invoke(obj1, Integer.parseInt(agrs[0].trim()));
} else if(agrs.length == 2) {
obj2 = obj1.getClass().getMethod("substring", int.class, int.class).invoke(obj1, Integer.parseInt(agrs[0].trim()), Integer.parseInt(agrs[1].trim()));
}
if(obj2 != null) {
re = obj2.toString();
}
}
}
} else if(obj0 != null) { //only attribute value
re = obj0.toString();
}
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if(bis != null) {
try { bis.close(); } catch(Exception ee) {}
}
}
return re;
}
很久沒用java.lang.reflect,是有點手癢XD...那個package真的很有意思~~
PS:雖然說 jdk後來同意 Integer, int 這種變數的型態可以互通,就是寫程式的時候大I,小i亂塞是被complire認同的~但是在Class的定義上~ Integer.class =/= int.class~所以在找method的時候~ 還是得用正確的型態才能找到喔!
PS:java內建的split還是常常不好用,用apache.commons.lang.StringUtils安定!
PS:原本也想直接找struts的Tag做繼承,不過它看起來還是得自己去解tag字串,要仿做一個完整的就變成要去研究它的source code和呼叫關係才行~這~實在有點麻煩就先用爛解處理了一.一a...反正能動就好!
沒有留言:
張貼留言