萬用網路服務框架設計

技術背景分析:

設計構想:

開發環境:

運行環境:

Session EJB:

基本服務程式:

服務請求程式:

    • 為每一種業務需求,撰寫相應之 Web Service〈以下簡稱 WS〉程式,實在耗時且不易維護。
    • WS 大多為同步調用〈Synchronous Call〉,當請求量多時,常易造成 J2EE 容器〈Container〉因資源耗盡而中斷服務。
    • WS 本質上為傳輸層〈Transport Layer〉,透過 WS 介面調用功能,並將其處理後之返回值〈Return Value〉回傳至請求者程式。
    • Enterprise Java Bean 以下簡稱 EJB,是 J2EE 容器之商業元件機制,透過其生命週期管理,使得J2EE 容器資源運用更靈活穩定。
    • Java 映射機制〈Reflection〉可以動態調用不特定類別〈Class〉方法〈Method〉。
    • 程式員僅需依照本框架規定撰寫 Java 類別,封裝成 JAR 檔,並部署於J2EE 容器 CLASSPATH 所指向之目錄即可。
    • 當服務請求程式透過 WS 調用功能時,本框架會自動接引請求,同時動態載入相應之 Java 類別,並將其處理後之返回值回傳至請求者程式。
    • 本框架大幅簡化程式員對相關技術背景倚賴,快速部署服務,並有效地運用 J2EE 容器資源。

netbeans

J2EE-WS-Generic

jBoss Application Server 6

package com.emprogria; import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.Stateless; @Stateless public class GenericCall implements GenericCallLocal { public String Call(String className, String methodName, String methodParam) { String retVal = ""; if (com.emprogria.GenericCore.isEmpty(className) || com.emprogria.GenericCore.isEmpty(methodName)) { retVal = com.emprogria.GenericCore.Now(methodParam);

} else { try { Class myClass = Class.forName(className); if (methodParam != null) { // 方法 - 引數 資料型態 Class paramTypes[] = new Class[1]; paramTypes[0] = String.class; // 取得 方法 介面 Method myMethod = myClass.getMethod(methodName, paramTypes); // 真實引數值 Object argList[] = new Object[1]; argList[0] = methodParam; // 調用 方法 retVal = (String) myMethod.invoke(new GenericCall(), argList);

} else { // 方法 - 引數 資料型態 Class paramTypes[] = null; // 取得 方法 介面 Method myMethod = myClass.getMethod(methodName, paramTypes); // 真實引數值 Object argList[] = null; // 調用 方法 retVal = (String) myMethod.invoke(new GenericCall(), argList);

}

} catch (Exception ex) { Logger.getLogger(GenericCall.class.getName()).log(Level.SEVERE, null, ex);

}

} return retVal;

} public String Call(String className, String methodName, String methodParam, boolean base64Encoded) { String myMethodParam = methodParam; if (base64Encoded) { myMethodParam = new String(org.jboss.util.Base64.decode(methodParam));

} return this.Call(className, methodName, myMethodParam);

}

}

package com.emprogria; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; public class GenericCore implements java.io.Serializable { static public boolean isEmpty(Object s) { if (s == null) { return true;

} if (s instanceof String) { return ((String) s).isEmpty();

} return false;

} static public String UUID() { java.util.UUID uuid = java.util.UUID.randomUUID(); return uuid.toString();

} static public String Now(String formatDateTime) { Calendar myCalendar = GregorianCalendar.getInstance(); SimpleDateFormat mySimpleFormat = null; if (isEmpty(formatDateTime)) { mySimpleFormat = new SimpleDateFormat();

} else { mySimpleFormat = new SimpleDateFormat(formatDateTime);

} return mySimpleFormat.format(myCalendar.getTime());

}

}

利用 JAX-WS 產生 WS 請求所需之相關類別程式,大幅簡化應用程式調用 WS 之複雜性:

    • Call.java
    • CallResponse.java
    • GenericWS.java
    • GenericWSService.java
    • ObjectFactory.java
    • package-info.java

package GenericWSClient; import java.net.URL; import java.util.logging.Level; import java.util.logging.Logger; public class Main { static public String Call(com.emprogria.GenericWS portWebService, String className, String methodName, String methodParam) { String retVal = ""; try { retVal = portWebService.call(className, methodName, methodParam);

} catch (Exception ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);

} return retVal;

} static public String Call2(com.emprogria.GenericWS portWebService, String className, String methodName, String methodParam, boolean base64Encoded) { String retVal = ""; try { retVal = portWebService.call2(className, methodName, methodParam, base64Encoded);

} catch (Exception ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);

} return retVal;

} static public void Debug(String className, String methodName, String methodParam, String retVal) { System.out.println(String.format("%s.%s(%s) = %s", new Object[]{className, methodName, methodParam, retVal}));

} /** * @param 命令列引數 */ public static void main(String[] args) { String entryPoint = "localhost:8080"; String className = "com.emprogria.GenericCore"; String methodName = "Now"; String methodParam = ""; String retVal = ""; if (args.length > 0) { entryPoint = args[0];

} if (args.length > 1) { className = args[1]; methodName = args[2];

} if (args.length > 3) { methodParam = args[3];

} try { URL endPoint = new URL("http://" + entryPoint + "/GenericWS-war//GenericWS?wsdl"); com.emprogria.GenericWSService myWebService = new com.emprogria.GenericWSService(endPoint); com.emprogria.GenericWS portWebService = myWebService.getGenericWSPort(); // 測試無引數調用基本功能 retVal = Call(portWebService, null, null, "yyyy-MM-dd hh:mm:ss.S Z"); Debug("com.emprogria.GenericCore", "Now", "", retVal); // 測試基本功能 - UUID retVal = Call(portWebService, "com.emprogria.GenericCore", "UUID", null); Debug("com.emprogria.GenericCore", "UUID", "", retVal); // 調用指定類別方法 retVal = Call(portWebService, className, methodName, methodParam); Debug(className, methodName, methodParam, retVal); // 調用指定類別方法 使用 Base64 編碼引數 className = "com.emprogria.GenericCore"; methodName = "Now"; // 使用 jBoss Base64 編碼程式庫 methodParam = org.jboss.util.Base64.encodeBytes(methodParam.getBytes()); retVal = Call2(portWebService, className, methodName, methodParam, true); Debug(className, methodName, methodParam, retVal);

} catch (Exception ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);

}

}

}