WebObjects/Project WONDER/Frameworks/ERIMAdaptor
ERIMAdaptor 使用標準 WOComponents 為您的應用程式提供即時通訊介面。由於 AOL IM 等即時通訊介面固有的限制,此介面卡的架構與普通的 HTTP 介面卡有所不同。
- WOSessions 由好友名稱跟蹤。當好友聯絡伺服器的即時通訊帳戶時,將啟動對話。對話將好友名稱與 WOSession ID 關聯起來。對話具有可配置的過期時間,但預設情況下在 5 分鐘不活動後過期。WOSession 將具有與平時相同的過期時間,但好友名稱與該會話之間的連線將消失,從而有效地使會話變得無用。
- 不同的即時通訊網路可能會對您的元件施加額外的限制。例如,大多數網路限制可以在一條訊息中傳輸的位元組數。目前框架不會自動拆分,但這是一個明顯的改進,可能會在將來新增。
- WORequest 和 WOResponse 的某些功能可能無法與 HTTP 對應部分完全一樣。例如,WORequest 中沒有正常的 HTTP 標頭。
- 好友名稱和訊息以表單值和請求使用者資訊字典的形式出現 - 使用哪種方法更方便。
- 如果您需要直接訪問(強制過期等),則可以透過請求使用者資訊字典訪問 Conversation 物件。
- 實現目前是所有對話的單執行緒。這將很快改變,我只是還沒有時間測試它。
目前有使用 jaimbot 和 daim 庫的 AIM 的 IInstantMessengerFactory 的實現。如果您有興趣獲取有關任一庫的更多資訊,jaimbot 可從http://jaimbot.sourceforge.net 獲得,daim 可從http://daim.dev.java.net 獲得。
ERIMAdaptor 是一個自定義介面卡,因此可以使用 WO 上的 WOAdditionalAdaptors 選項新增它。
-WOAdditionalAdaptors ({WOAdaptor="er.imadaptor.InstantMessengerAdaptor";})
您的屬性檔案中還有一些新的設定可以(或必須)出現。
- IMFactory(可選,預設 er.imadaptor.AimBotInstantMessenger$Factory) - 用於建立即時通訊連線的工廠類。如果您想提供新的即時通訊網路型別,則應為此類提供的任何類實現 IInstantMessengerFactory 介面。
- IMScreenName(必需) - 伺服器應登入的即時通訊帳戶的螢幕名稱
- IMPassword(必需) - 伺服器應登入的即時通訊帳戶的密碼
- IMTimeout(可選,預設 5 分鐘) - 對話超時時間(以毫秒為單位)
- IMAutoLogin(可選,預設“true”) - 介面卡是否應自動登入 AIM。如果為 false,則必須呼叫 adaptor.connect()
- IMConversationActionName(可選,預設“imConversation”) - 啟動對話時要呼叫的 DirectAction 的名稱,預設情況下您必須在 DirectAction 類中建立一個公共 WOActionResults imConversationAction() { .. } 方法。
- IMWatcherEnabled(可選,預設“false”) - 是否希望第二個 AIM 帳戶登入並監視第一個。大多數 AIM 庫在一段時間後可能會出現無法啟動的問題。如果您有兩個 AIM 帳戶,它們可以相互保持活動狀態。
- IMWatcherFactory(可選,預設與 IMFactory 相同) - 如果 IMWatcherEnabled,則要使用的工廠類
- IMWatcherScreenName(可選,如果 IMWatcherEnabled 則必需) - 監視器即時通訊帳戶的螢幕名稱
- IMWatcherPassword(可選,如果 IMWatcherEnabled 則必需) - 監視器即時通訊帳戶的密碼
在您的程式碼中,可以使用以下請求標頭。
- IsIM - Boolean.TRUE 如果當前請求是即時通訊請求(您也可以呼叫 InstantMessengerAdaptor.isIMRequest(WORequest))。
- IMConversation - 與此請求關聯的對話
- BuddyName - 啟動請求的好友的名稱
- Message - 使用者傳送的訊息
以下表單值在請求中可用。
- BuddyName - 啟動請求的好友的名稱
- Message - 使用者傳送的訊息
要啟動,您必須有一個與 IMConversationActionName 值匹配的直接操作方法(預設為“imConversation”)。此方法應返回即時通訊對話的第一個“頁面”。
例如
public WOActionResults imConversationAction() {
return pageWithName(SayHelloPage.class.getName());
}
對於每個請求,IM 介面卡都需要知道後續請求到來時要呼叫哪個操作。在正常的 WOComponent 中,將其視為每個頁面都有一個每次請求到來時都會被點選的“Next”按鈕。您不是使用 WOSubmitButton 或 WOHyperlink,而是使用 IMAction 元素。此元素有一個屬性 - “action”,它指向要在元件上呼叫的操作方法。由於即時通訊介面作為互動方法的固有侷限性,每個頁面只能觸發一個 IMAction(具體來說,是頁面上評估的最後一個 IMAction)。當您將使用者的響應視為要執行的操作時,這是有道理的。WOForm 上沒有“multipleSubmit”的語義等效項。
IMAction 是您可以使用的最簡單的操作,儘管有幾種常見的響應操作,並且 ERIMAdaptor 為它們提供了預設的操作實現。以下是一個使用 IMAction 的非常簡單的對話示例(它只會一遍又一遍地說同樣的話)。
您的 Java 元件看起來像這樣
public class IMComponent extends WOComponent {
public boolean userResponded;
...
public String buddyName() {
return InstantMessengerAdaptor.buddyName(context().request());
}
public WOActionResults processResponse() {
userResponded = true;
return null;
}
}
HTML 將是
<webobject name = "FirstContactConditional"> Hi <webobject name = "BuddyName"></webobject>! </webobject> <webobject name = "UserRespondedConditional"> Welcome back <webobject name = "BuddyName"></webobject>! </webobject> <webobject name = "IMAction"></webobject>
最後,WOD 檔案將包含
FirstContactConditional : WOConditional {
condition = userResponded;
negate = true;
}
UserRespondedConditional : WOConditional {
condition = userResponded;
}
BuddyName : WOString {
value = buddyName;
}
IMAction : IMAction {
action = processResponse;
}
以下是一個示例對話記錄可能的樣子
Mike> Hey server! Server> Hi Mike! Mike> How's it going? Server> Welcome back Mike! Mike> Uh. OK. Server> Welcome back Mike! ...
IMConfirmation 只有一個繫結“confirmed”。如果來自即時通訊好友的響應與一組常見的“yes”、“no”等詞語中的任何一個匹配,則 confirmed 將設定為適當的值。如果未找到 yes 和 no 詞語,則 confirmed 將設定為 null。您應該將其繫結到 Boolean 而不是 boolean,以便您可以正確檢測第三種狀態並重新提出問題。請注意,這不是國際化的,因此目前它具有“yes”、“y”、“yep”、“true”、“no”、“n”、“nope”、“nah”作為已知值。
- confirmed = 三態 Boolean,當 Boolean.TRUE 時,響應為肯定,當 Boolean.FALSE 時,響應為否定,當為 null 時,響應與已知的真/假值都不匹配。
- action = 接收響應時要執行的操作方法
AreYouSureAction : IMConfirmationAction {
confirmed = yesOrNo;
action = nextStep;
}
在上面的示例中,繫結“yesOrNo”是一個 Boolean,它將包含使用者響應是否為確認。處理響應後,將呼叫“nextStep”操作,以便您可以評估“yesOrNo”值並相應地做出響應。
IMSearchMessageAction 允許您將 AIM 訊息響應中出現的子字串對映到其他物件。例如,您可以傳遞一個選項字典,將單詞“hi”對映到物件 Greeting,或將單詞“bug”對映到物件 BugReport。如果 AIM 響應中出現單詞“hi”,它將返回匹配的物件作為其值。
- value = 用於寫入第一個匹配值的繫結
- values = (必須指定“value”或“values”中的至少一個,但您也可以同時使用兩者)用於寫入所有匹配值的陣列的繫結
- optionsDictionary = 響應中要查詢的子字串與這些子字串關聯的任意物件的對映
- optionsArray = 要查詢的已知子字串的列表
- optionKeyPath = (僅適用於 optionsArray)不是在 optionsArray 中查詢值,而是在 optionsArray 中每個值的此鍵路徑的值中查詢;例如,optionsArray 可能包含 Person 物件,optionKeyPath 可能為“firstName”,因此這將匹配人員列表中的第一個名字。
- quicksilver = 類似 Quicksilver 的匹配方式(“NPE”匹配“NullPointerException”)
- action = 接收響應時要執行的操作方法
PickRequestTypeAction : IMSearchMessageAction {
value = selectedOption;
optionsDictionary = options;
action = nextStep;
}
在上面的示例中,“optionsDictionary”包含一個對映,其中鍵是響應中要查詢的子字串,而值是與它們關聯的物件。例如,來自我們的錯誤跟蹤系統的字典看起來像 {“bug”=>BugReportType 物件,“request”=>ServiceRequestType 物件}。“action”是在使用者響應返回時要觸發的 method,而“value”將包含與使用者響應匹配的值。
當用戶響應時,響應將由提供的 action 解釋,“selectedOption”欄位將包含與使用者響應匹配的任何物件,或者如果沒有匹配,則為 null,“nextStep” action method 將被呼叫。“nextStep”是一個正常的 action method,與任何其他 method 相同,只是它可以訪問 Request 部分中描述的額外的 AIM 僅請求引數。
IMSearchOptionsAction,IMSearchMessageAction 的邪惡孿生兄弟,允許您搜尋您的選項以查詢收到的 AIM 響應(而不是 SearchMessage 搜尋 AIM 響應以查詢您的選項——反過來)。例如,您可以傳遞一個選項字典,將單詞“Company XYZ”對映到物件 CompanyXYZ,或將單詞“Company ABC”對映到物件 CompanyABC。如果 AIM 了單詞“XYZ”,它將返回匹配的 CompanyXYZ 物件作為其值。
- value = 用於寫入第一個匹配值的繫結
- values = (必須指定“value”或“values”中的至少一個,但您也可以同時使用兩者)用於寫入所有匹配值的陣列的繫結
- optionsDictionary = 響應中要查詢的子字串與這些子字串關聯的任意物件的對映
- optionsArray = 要查詢的已知子字串的列表
- optionKeyPath = (僅適用於 optionsArray)不是在 optionsArray 中查詢值,而是在 optionsArray 中每個值的此鍵路徑的值中查詢;例如,optionsArray 可能包含 Person 物件,optionKeyPath 可能為“firstName”,因此這將匹配人員列表中的第一個名字。
- quicksilver = 類似 Quicksilver 的匹配方式(“NPE”匹配“NullPointerException”)
- action = 接收響應時要執行的操作方法
PickCompanyAction : IMSearchOptionsAction {
optionsArray = companies;
optionKeyPath = "name";
value = company;
values = companies;
quicksilver = true;
action = nextStep;
}
上面的來自我們的錯誤報告系統的示例允許使用者選擇一個公司與錯誤關聯。“optionsArray”包含一個 Company 物件的陣列。“optionKeyPath”指定響應應該與 Companies 的“name”鍵路徑的值進行比較。第一個匹配的結果 Company 物件將儲存在“company”繫結中(如“value”所定義),如果有多個匹配,它們都將出現在“companies”列表中。Quicksilver 匹配在上面啟用,響應處理完並設定繫結後,“nextStep” action 將被呼叫。
一個非常常見的用例是您想要向用戶呈現一個選項列表,並讓使用者從該列表中選擇。IMPickList 為此行為提供了一個方便的實現。而之前的 action 是“無頭”的,IMPickList 實際上完全自行呈現列表。一個典型的用例是繼續呈現 IMPickList,直到使用者的選擇縮減到一個為止。
一個示例對話可能看起來像
Server> Pick a company: Server> 1) Company XYZ Server> 2) Company VWX Server> 3) Company ABC User> X // note this matches #1 and #2 Server> Pick a company: Server> 1) Company XYZ Server> 2) Company VWX User> V // Company VWX is now selected Server> ...
或者
Server> Pick a company: Server> 1) Company XYZ Server> 2) Company VWX Server> 3) Company ABC User> 1 // picking by number uniquely identifies Company XYZ
或者
Server> Pick a company: Server> 1) Company XYZ Server> 2) Company VWX Server> 3) Company ABC User> XYZ // XYZ uniquely matches Company XYZ
- displayStringKeyPath = 用於顯示列表中每個物件的字串的鍵路徑。該值應放在“引號”中。
- list = 要從中選擇的選項列表的 NSArray
- quicksilver = 是否對使用者響應使用 Quicksilver 風格的匹配(“NPE”匹配“NullPointerException”)
- selections = 匹配的選擇列表
- selection = 單個匹配的選擇(如果只有一個)
- action = 接收響應時要執行的操作方法
PickProductAction : IMPickListAction {
list = products.@sort.name;
selection = product;
selections = products;
displayStringKeyPath = "name";
quicksilver = true;
action = nextStep;
}
上面的示例讓使用者從 Products 列表(來自“list”繫結)中選擇。“displayStringKeyPath”繫結指定 Product 的“name”鍵路徑應該在列表中顯示。當用戶唯一標識單個 Product 時,Product 物件將繫結到“product”變數。如果有多個匹配,匹配的 NSArray 將繫結到“products”變數。Quicksilver 匹配已啟用。響應處理完後,“nextStep” method 將被呼叫。請注意,在此示例中,“products”陣列既是“list”繫結,也是“selections”繫結。當頁面首次載入時,“products”NSArray 初始化了所有產品。nextStep method 繼續返回同一個頁面,直到只有一個產品被選中。在此之前,列表將使用與使用者部分響應匹配的產品進行重置(如上面 IMPickList 的示例記錄中)。
IMTextAction 是最簡單的 IMAction 實現之一。它將使用者的響應儲存在 String 繫結中,並呼叫 action method。
- value = 用於儲存使用者響應的變數
- allowBlanks = 如果為 false,空字串(response.trim.length == 0)將變為 null
- action = 接收響應時要執行的操作方法
AskNameAction : IMPickListAction {
value = userName;
allowBlanks = false;
action = nextStep;
}
上面的示例將使用者的響應儲存在“userName”變數中,並且不允許空白值(即它們變為 null)。當響應處理完後,“nextStep” action method 將被呼叫。