/**
?* user java reg to check phone number and replace 86 or +86
?* only check start with "+86" or "86" ex +8615911119999 13100009999 replace +86 or 86 with ""
?* @param phoneNum
?* @return
?* @throws Exception
?*/?
?protected int checkPhoneNum(String phoneNum) throws Exception {
??
??Pattern p1 = Pattern.compile("^((\\+{0,1}86){0,1})1[0-9]{10}");
??Matcher m1 = p1.matcher(phoneNum);
??if (m1.matches()) {
???Pattern p2 = Pattern.compile("^((\\+{0,1}86){0,1})");
???Matcher m2 = p2.matcher(phoneNum);
???StringBuffer sb = new StringBuffer();
???while (m2.find()) {
????m2.appendReplacement(sb, "");
???}
???m2.appendTail(sb);
???return Integer.parseInt(sb.toString());
??} else {
???throw new Exception("The format of phoneNum "+phoneNum+"? is not correct!Please correct it");
??}
?}
1:文件Service.java ServiceImpl.java ServiceServer.java ServiceClient.java? client.policy
結構
?src
??? net.loocky.rmi/ *.java
??? client.policy
文件如下:
Service.java是個interface
package net.loocky.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Service extends Remote {
?public String getName() throws RemoteException;
?public void setName(String name) throws RemoteException;
}
ServiceImpl.java Service的實現
package net.loocky.rmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class ServiceImpl extends UnicastRemoteObject implements Service {
?private static final long serialVersionUID = 1L;
?private String name;
?public ServiceImpl(String name) throws RemoteException {
??this.name = name;
?}
?public String getName() throws RemoteException {
??return name;
?}
?public void setName(String name) throws RemoteException {
??this.name = name;
?}
}
ServiceServer
package net.loocky.rmi;
import java.rmi.Naming;
public class ServiceServer {
?/**
? * @param args
? */
?public static void main(String[] args) {
??try {
???ServiceImpl s1 = new ServiceImpl("my name is john");
???ServiceImpl s2 = new ServiceImpl("my name is loocky");
???Naming.rebind("john", s1);
???Naming.rebind("loocky", s2);
???System.out.println("waiting for clients...");
??} catch (Exception e) {
???e.printStackTrace();
??}
?}
}
ServiceClient
package net.loocky.rmi;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
public class ServiceClient {
?/**
? * @param args
? */
?public static void main(String[] args) {
??System.setSecurityManager(new RMISecurityManager());
??String url = "rmi://127.0.0.1:1099/";
??try {
???Service s1 = (Service) Naming.lookup(url + "john");
???Service s2 = (Service) Naming.lookup(url + "loocky");
???System.out.println(s1.getName());
???s2.setName("my name is not loocky");
???System.out.println(s2.getName());
??} catch (Exception e) {
???e.printStackTrace();
??}
?}
}
client.policy
grant
{
? permission java.security.AllPermission;
// permission java.net.SocketPermission "127.0.0.1:1099","connect";
// permission java.net.SocketPermission "127.0.0.1:80","connect";
};
有了這些文件下面要做的事情是
1:進入bin/? rmic net.loocky.rmi.ServiceImpl 生成STUB
2:dos下面 rmiregistry
3:java net.loocky.rmi.ServiceServer
4: java -Djava.security.policy=client.policy net.loocky.rmi.ServiceClient
5:查看控制臺的結果吧!
<beans>
?<bean id="timer" class="org.springframework.scheduling.timer.TimerFactoryBean">
??<property name="scheduledTimerTasks">
???<list>
????<ref local="testtimertask"/>
???</list>
??</property>
?</bean>
?<bean id="timerbean" class="MyTimerImpl">
?</bean>
?<bean id="testtimertask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
??<property name="timerTask">
???<ref bean="timerbean" />
??</property>
??<property name="delay">
???<value>1000</value>
??</property>
??<property name="period">
???<value>1000</value>
??</property>
?</bean>
</beans>
MyTimerImpl
import java.util.TimerTask;
public class MyTimerImpl? extends TimerTask {
?public void run() {
??System.out.println("aaaaaaaa");
??
?}
TestTimer
import net.loocky.sowq.util.ServiceFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class TestTimer {
?/**
? * @param args
? */
?public static void main(String[] args) throws Exception {
??
????ApplicationContext ctx=new?FileSystemXmlApplicationContext("E:\\work\\Test\\bin\\spring-config.xml");
??Thread.sleep(100000);
?}
}
}
冒泡排序
public class BubbleSort {
?public? static void sort(int[] data, int n) {
??int sortedNum = 0;
??int index;
??while (sortedNum < n) {
???for (index = 1; index < n - sortedNum; index++) {
????if (data[index - 1] > data[index]) {
?????int tmp;
?????tmp = data[index - 1];
?????data[index - 1] = data[index];
?????data[index] = tmp;
????}
???}
???sortedNum++;
??}
?}
}
選擇排序
public class SelectSort {
?public static void sort(int[] data, int n) {
??int sortedNum = 0;
??int index;
??int maxIndex = 0;
??while (sortedNum < n) {
???for (index = 1; index < n - sortedNum - 1; index++) {
????if (data[maxIndex] < data[index]) {
?????maxIndex = index;
????}
???}
???int tmp;
???tmp = data[maxIndex];
???data[maxIndex] = data[n - sortedNum - 1];
???data[n - sortedNum - 1] = tmp;
???sortedNum++;
??}
?}
}
插入排序
public class InsertSort {
?public static void sort(int[] data, int n) {
??int sortedNum = 1;
??int index;
??while (sortedNum < n) {
???int tmp = data[sortedNum];
???for (index = sortedNum; index > 0; index--) {
????if (tmp < data[index - 1]) {
?????data[index] = data[index - 1];
????} else {
?????break;
????}
???}
???//插入的他的位置
???//index就是找TMP的位置
???data[index] = tmp;
???sortedNum++;
???
???for(int i=0;i<n;i++){
????System.out.print(data[i]+",");
???}
???System.out.println("");
??}
?}
}
快速排序
public class QuickSort {
?public static void sort(int[] data, int n) {
??quickSortRescursive(data, 0, n - 1);
?}
?private static void quickSortRescursive(int[] data, int left, int right) {
??int pos;
??if (left >= right)
???return;
??pos = getPos(data, left, right);
??// 排左邊的
??quickSortRescursive(data, left, pos - 1);
??quickSortRescursive(data, pos + 1, right);
?}
?private static int getPos(int[] data, int left, int right) {
??// 想左邊移動
??while (true) {
???//遇到右邊的大就忽略,并且縮小右邊范圍
???while (left < right && data[left] < data[right])
????right--;
???
???//遇到左邊的大就往右邊換
???if (left < right)
????swap(data, left++, right);
???else
????return left;
//???遇到右邊的大就忽略,并且左邊縮小范圍
???while (left < right && data[left] < data[right])
????left++;
???if (left < right)
??? //遇到左邊的大就往右邊換
????swap(data, left, right--);
???// return left;
???else
????return right;
???// return 0;
??}
?}
?private static void swap(int[] data, int i, int j) {
??int tmp = data[i];
??data[i] = data[j];
??data[j] = tmp;
?}
}
8 : SyncML dm package
? SyncML dm 協議包括 2 個階段 初始化階段(認證和終端信息交換的階段)和管理階段,管理階段服務器希望進行重復多次進行管理。 Manage 周期的開始以 package0 開始,本次出發依賴于不可更改的環境,在 SyncML Notifaction 開始的周期里面被指定
下圖是描繪了 2 個階段
?Management 階段包括了幾個協議的交互,從 server 發送到 client 的包的內容決定了這個周期是否進行下去,如果從 server 發送出來的包的管理指令需要得到 client 的回復, client 將會返回針對這些操作指令的回復。這些回復的包開始了新的協議的交互,服務器將發送一個新的管理指令的包并且開始一個新的協議交互的的過程。
???? 當 server 的 package 里面不包含 management operation 的時候, client 將根據服務器發送過來的包回復一個新的包,這個包里面只包含了 status 和 Synchr ,在這種情況下,真個回復的包不能被發送,協議中止。 Server 必須給任何 client 的包進行回復
???? 包的處理可能花費的時間是不可預知的,因此在 SyncML dm 協議中沒有指定 2 者的超時時間。
???? 如果不是 operation command 另有規定,終端和 server 可以不按照 package 中的順序執行指令。因此,在上一條管理指令在執行的順序是必須的,管理指令必須按照他們發送的順序進行執行。 Client 不能發送除了包含 Devinfo 的 REPLACE command 、 Result alert 給 server
8 . 1 session abort
8 . 1 . 1 描述
? ??? 是 server 還是 client 任何時候都可以中止操作。終端操作的原因可能是 server 關閉, client 沒電,或者用戶在 client 上的其他交互操作,或者其他操作。這種情況下,最好的方式是發送一個中止的 ALERT 。推薦的做法是: message 包含了管理指令的任何 stauts 和 result
如果發送一個 session 終端給接受方的 MESSAGE ,那么接收方的回應會忽略,(不會回應把,自己也不理解,有待更正)
有些終端是無法控制的, client 不在覆蓋范圍內或者電池沒有電。 Server 和 client 必須也對沒有信號的情況做好準備。上面提到的需求只要是為了減少一些回應超時,或者沒有回應的情況。
補充說明:
request/response
在傳輸用的角色被倒置的情況,
client
是個傳輸層的
server
,
server
是個傳輸層的
client
,這種情況下
Alert 1223 是無法預知的操作中止的信號標識,發送方的 session 中斷標識包含了 command 的狀態和結果,這些指令將在 abort 之前執行,發送方必須包含一個 FINAL 的標識。當 server 收到 alert 提示的時候,必須在回復的 message 中包含狀態和 SyncHR ,并且不回復新的 MESSAGE
8.2 package 0 , server 發起的初始化 指令
? 許多終端不能持續的偵聽服務器的連接,由于安全原因一些終端只是不想開方一些端口。大部分終端可以接受一些主動提供的 MESSAGE, 稱作通知 (notifaction).
? Server可以用通知的這種能力使終端初始化一個連接回server, SyncML dm 協議規定了幾種管理初始化通知的發送方式。發送者和通知的內容可以參考Notification Initiated Session, Version
? ? ? 需要說明的是:接收一個管理初始化的通知會受其他方面影響。如終端設備可能會允許用戶操作設備去初始化管理周期,另外,終端用戶也可以管理超時的管理周期,一些錯誤得操作也會使終端發起一個管理周期。
8
.3 package1 :客戶端發起初始化指令
??
管理階段跟SyncML dm 數據協議得描述完全相同,客戶端發起包的意圖如下:
??
1
:發送終端信息(廠商,版本,其他)給DM server,終端必須在第一個message中管理周期中發送設備信息
2
:根據SELECTION 9中的規則終端向DM server確認身份
3
:通知dmserver本次SESSION由客戶端發起還是由Dmserver 發起(package0往往不會用到,如果是客戶端發起的話)。
?
客戶端發起得初始化package得具體需求如下:
? 1
:在SyncHdr 元素里面得需求
VerDTD
的值必須是1.1
VerProto
的值必須是“DM/
Sessionid
必須能標明但前Management session 的身份,如果client 回復通知,那么Alert(1200)標識由server發起的,sessionid必須跟notifaction里面的sessionid相同,否則client產生的sessionid不會唯一,sessionid會貫穿整個session
MsgID
必須明確的指出message屬于哪個management session
Target
元素必須指明是個那個目標server
Source
元素指明的是哪個client 的service
Cred element
可能包含再認證的message里面,一般是從client發起,section9將會詳細描述
? 2
:Syncbody中必須包含alert信息無論client發起還是server發起
Alert command
的需求如下
? CmdId
是必須的
?
存放management session type 的Data element或者由server發起(1200)或者由client發起(1201)
? 3
:終端的信息必須在syncbody中包含Relpace command,replace command需求如下
? Cmdid
是必須的
? Dm tree
每個節點的item都可以被找到,在DMSTDOBJ中有詳細描述
? Source element
必須包含一個指定的URI 節點
? Data element
用來裝載device 信息數據
Final element
必須包含在Syncbody 的最后一個message 中
4 :簡介
Dm 協議允許管理指令在節點上執行,跟 SyncML 同步協議和 SyncML 表示協議類似都采用的是包的形式。設備的一個節點表示為一組可配置參數,可以這個節點進行讀和設定參數的鍵、值操作,而終端的應用軟件另外一個節點可能是的正在可運行環境中(意思是不會影響到別的節點的功能),對這類型的節點操作可以對軟件的一部分功能進行下載、升級或者卸載 .
SyncML DM 這些指令代表這些操作,在 SymcML 表現協議和 SyncML 表現協議 DM 的用戶手冊中有描述。這些指令和消息的結構等同于 SyncML 數據同步協議,并且管理協議的 DTM 就是來源于 SyncML 數據同步協議的 DTD
5 :節點處理
每一個節點的路徑就是設備的唯一統一資源標識,這些標識必須遵循這樣一些指定的需求: SyncML DM 樹和描述加以限制和指定
每一個節點都有一個可以決定什么樣的管理內容可以用來設置或者讀的類型,在節點上操作需要實現定義這個類型的值,當節點被讀的時候,這個類型的值將被返回。
舉例說明,有的節點只是一個簡單文本類型,需要設置,而有的節點是 WAP Provisioning document MIME 的復雜類型,甚至其他節點可能象 WAP 設置或者軟件安裝這樣更復雜的值
SyncML DM 協議的指令的 target 和 souce 由 目標和來源 元素分別指定 target 是接納著, source 是來源,這些過程出現的異常都會在管理命令需求中的異常中會被提及
6 :包中的多消息
6 . 1 描述
? DM 管理協議中中提供用多個 MESSAGE 來傳輸一個包的功能,當一個包非常大的時候,分成多個 MESSAGE 進行傳輸是非常有必要的,這樣的局限是可能由傳輸協議或者終端的功能限制決定,(分成多個 MESSAGE 就可以解決這個問題)。
? DM 管理協議中,包作為一個邏輯組的作用是非常有限的,大部分的限制在 MESSAGE 上,而不是在 PACKAGE 上,舉例:一個 COMMAND 必須完全適從一個 MESSAGE 。
為了避免大量客戶端而有限的資源,服務器等待從客戶端的包的 command 返回一個狀態,
如果上一個 COMMAND 沒有返回一個狀態服務器不允許發送一個新的 COMMAND ,換句話來說,大部分 server 發送到客戶端的 COMMAND 都會收到 CMMAND ( package )的返回信息,除非 SERVER 發送一個大的對象或者請求更多的 MESSAGE (用 1222 ALERT )
一個 PACKAGE 包含大對象數據將會被分成很多 MESSAGE 傳輸,在第七部分會詳細描述
? 說明 server 在處于一下一種包的邊界的狀態的時候:
? ?1 : server 有一個完全大的包,在這種狀況下, server 等待從 client 的 COMMAND 返回狀態,由于狀態和結果非常大(如 GET COMMAND 的結果), client 將發送多個 MESSAGE 回 server ,然后結束他的回應
? ?2 : server 從 client 接受到一個完整的包, server 將會發送一個新的 COMMAND 給 client
? ?3 : server 發送了包中的一個或多個指令,但是沒有發送包中的最后一個指令的時候,只有當 package 中的最后一個指令被發送出去的時候,這次狀態才被認為是有效的
由于 SyncML 的傳輸形式是 request/response??? 的形式,無論是客戶端還是服務器端在傳輸消息的時候都不應該包含一個開始命令或者一個結束的標志,以便保證 response/request 循環進行下去(言外之意就是有個這個標志就是開始和結束的時候) .
舉例:當 server 在 STATE1, 他可能收到客戶端的很多 MESSAGE, 這些 MESSAGE 包含了 status 和 result 。 Server 會對任何一個 message 回應,除了對 NEW COMMAND 進行回應外。
Server 對發送的回應在 SyncHdr 中包含了一個 1222 ALERT , client 也指定了,(表示沒有結束還有消息)。 STAUTS 必須對 ALERT 的回應進行發送而不是對 RESULT 的回應進行發送
ALERT1222 可以被 ALERT 1223 替換,因為服務器可以主動結束一個過程
下圖展示了多個 message 被發送
6 . 2 需求
? 如果 SyncML package 分成多個 MESSAGE 被傳送,最后一個 MESSAGE 必須包含一個 FINAL 的標志,其他么 message 一定不能包含 final 標志。 Final element 由 server 發送而不是由 client 發送,最終停止本次的 PACKAGE 操作。
?? Server 在每個 MESSAGE 必須發送 FINAL message ,不過在發送大的對象的時候或者發送 NEXT MESSAGE 的相應的時候不會發送
7 :大對象的處理
? SyncML dm 協議中,大對象不能完全在一個 Message 中傳輸,根據 SyncML data 同步協議指定的大對象處理方案可以分成多個 Message 。規則如下:
第一個限制就是支持大對象處理的終端必須顯示的之處 DevDetail/LrgObj 的標識為 true
第二個限制是在 server 和 client 傳輸的 MaxObjSize 有多大,在 SyncML data 同步協議中 MaxObjSize 會在 Meta information 中指定。 DM 協議中被發送著接受的最大對象的大小( MaxObjSize )包含在 syncHdr 中( message 的 META INFO ) ,syncHdr 中指定的 MaxObjSize ,發送者發送的單個對象都不能超過這個大小,如果 MaxObjSize 沒有被發送,接收者可以自由發送任何大小的 message 給 server 。
需要指出的是: MaxObjSize 會影響整個 DM session ,如果在隨后的 message 中沒有對這個值進行重新設置。新的 MaxObjSize 在后來的 message 指定一個可能的原因是 client 的 free memory 大小的依賴,(有東西創建在 MEMORY 的時候或者刪除的時候 FREE MOMORY 會發生變化)。
第三個限制:在上一個單元結束前終端會檢測新的對象( messge ),終端會回復一個 1225 的 alert
?
?