【第0092期2005/9/10】

本週主題

最新消息

 
  • IBM Lotus Notes/ Domino/SameTime/Quickplace/Workflow/Document Manager 7正式版已經正式上市.

詳細資訊請參閱以下網址:

http://www.lotus.com/lotus/general.nsf/wdocs/nd7content

Top

文章分享

Lotus Notes/Domino 7 Web Services

英文原文:http://www.ibm.com/developerworks/lotus/library/nd7-webservices/

Web Services Lotus Notes/Domino 7 的新特性。本文介紹新 Web Services 設計元素,展示如何在 Domino Designer 中建立這種設計元素,並描述了如何用 LotusScript Java 程式碼範例來實現 Web Services

[編者注:本文描述 Lotus Notes/Domino 7 Beta 2 Web Services 實現。它可能並不準確反映 Lotus Notes/Domino 7 Gold 版本的特性或功能。]

 

在很多公司中,業務軟體平臺是否有用取決於能夠用該工具開發的應用程式。基於此,IBM 推出了基於標準的開發工具 IBM Workplace Designer 2.5,讓開發人員快速方便地為 IBM Workplace 產品家族 2.5 版建立元件。可以從任何 Web 瀏覽器在 IBM Workplace 應用程式中使用這些元件。

 

Web 服務是可以透過在 Internet 上發送訊息來調用的遠端操作的檔案。Web 服務供應商發佈用於查詢和使用的 Web 服務,而 Web 服務消費者調用來自這些服務的操作。Web 服務供應商提供了定義服務介面的 WSDLWeb Services Description LanguageWeb 服務描述語言)文件。WSDL 文件是 XML 格式的。介面的底層由供應商實現,但大多數供應商將介面對應為支援的程式語言的程序呼叫。來自消費者的入站請求傳遞給底層程式碼,然後結果返回給消費者。

 

Lotus Domino WSDL 介面對應為可以用 LotusScript Java 程式的類似代理程式的 Web 服務設計元素。要被使用,Web 服務必須位於啟用 HTTP Domino 伺服器上。(我們可以透過 Notes 用戶端預覽中的 HTTP 網頁測試 Web 服務。)透過下列 Domino URL 命令之一進行存取:

  • ?OpenWebService 調用 Web 服務以回應透過 HTTP POST 發送的 SOAP 編碼訊息。HTTP GET(例如,瀏覽器查詢)返回服務的名稱及其操作。
  • ?WSDL 返回 WSDL 文件以回應 HTTP GET

本文描述 Lotus Notes/Domino 7 中的 Web 伺服器設計元素,並提供了設計元素的 LotusScript Java 範例。本文假設您是瞭解 LotusScript Java 的經驗豐富的 Notes 應用程式開發人員。

 

範例


讓我們看一個簡單的範例。給定資料庫名稱、視界名稱和文件位置編號,我們的操作返回 Subject 欄位的內容。我們將調用操作 getNthSubject

1. getNthSubject 圖表

要讓該操作可用於外部世界,將其發佈在名為 GetSubject Web 服務中。GetSubject 可以包含任意數目的操作。例如,可能發現 getFirstSubject getLastSubject 都有用。但現在只處理範例操作 getNthSubject。下列程式碼段摘自描述包含這樣一個操作的 Web 服務的 WSDL 文件。下面看一下程式碼段及其註釋。

 

<wsdl:message name="getNthSubjectRequest"> (4) 
  <wsdl:part name="dbname" type="xsd:string"/> (5) 
  <wsdl:part name="viewname" type="xsd:string"/> (5) 
  <wsdl:part name="n" type="xsd:int"/> (5) 
</wsdl:message>
<wsdl:message name="getNthSubjectResponse"> (4) 
 <wsdl:part name="getNthSubjectReturn" type="xsd:string"/> (6) 
</wsdl:message>
<wsdl:portType name="GetSubjectPortType"> (1) 
  <wsdl:operation name="getNthSubject" 
   parameterOrder="dbname viewname n"> (2) 
  <wsdl:input message="impl:getnthSubjectRequest" name="GetNthSubjectRequest"/> (3) 
  <wsdl:output message="impl:getNthSubjectResponse" name="GetNthSubjectResponse"/> (3) 
  </wsdl:operation>
</wsdl:portType>

 

Top

 

首先看 portType 元素 (1),它定義了服務的操作集合。我們的服務只有一個 portType,它只有一個操作 getNthSubject (2)。該操作有兩個“訊息” (3):一個用於輸入,一個用於輸出。訊息在訊息元素 (4) 中定義。我們看到,輸入訊息有三個部分 (5):兩個名為 dbname viewname 的字串,一個名為 n int。輸出訊息只有一個部分 (6),即名為 getNthSubjectReturn 的字串。

 

所以,我們的操作有三個輸入部分和一個輸出部分,這非常巧妙地對應為具有三個唯讀參數和一個返回值的過程。在 LotusScript 中,這樣的過程將透過下列函數來定義:

Public Function getNthSubject(dbname As String, viewname As String, n As Long) As String

Java 中,透過下列方法來定義:

public String getNthSubject(String dbname, String viewname, int n)

Web 服務設計元素


Domino Designer 中建立 Web 服務設計元素有多種可行方法。可以完全用 LotusScript Java 來編碼。在這種情況下,儲存設計元素會產生反映 LotusScript Java 程式碼的 WSDL 文件。或者可以導入現有的 WSDL 文件。在這種情況下,在導入的 WSDL 中會產生反映操作的 LotusScript Java 程式碼。Web 服務設計元素儲存 WSDL 文件以及程式碼。如果公共介面未更改,則 WSDL 文件保持不變。如果在編碼中更改了影響公共介面的部分,則會產生新的 WSDL

 

Domino Designer 中,Web 服務設計元素駐留在 Shared 程式碼中的 Agents 之下。Web 服務設計視窗的外觀與代理程式設計視窗非常相似。按下“New Web Service”按鈕以建立新 Web 服務。點擊現有 Web 服務以對其進行編輯。

2. New Web Service

Web Services Property 框有三個類似代理程式的選項頁。下面是 Basics 選項頁:

3. Web Services Property

名稱是必需的。別名和備註可以提供也可以不提供。如果編碼更改引起新 WSDL 的產生,則會收到警告訊息。

 

PortType Class是定義對應為 WSDL 操作的過程的Class名。這些過程在 LotusScript 中必須是公共函數或副程式,在 Java 中必須是公共方法。私有函數、副程式和方法不透過 Web 服務介面暴露。不能在屬性框中輸入 PortType Class,除非已經透過編碼或導入 WSDL 建立了該Class。稍後將詳細介紹程式碼。

 

Security 選項頁幾乎與代理程式 Security 選項頁完全一樣。稍後將詳細介紹 Security

 

Top

Advanced 選項頁具有用於定義 Web 服務和產生 WSDL 的其他資訊。稍後將詳細介紹。

 

編輯器窗格與代理程式的編輯器窗格相似。在右下拉清單中,可以選擇 LotusScript Java。下面顯示的是選擇 Java。左邊是 Objects Reference 窗格。

4. Web 服務 (Java)

使用“Import WSDL”按鈕以基於現有 WSDL 建立新 Web 服務。“Show WSDL”按鈕編譯對 Web 服務的任何更改,並顯示定義公共介面的 WSDL 文件。“Export WSDL”按鈕編譯對 Web 服務的任何更改,並導出定義公共介面的 WSDL 文件。還可以透過儲存或關閉 Web 服務來編譯。僅當公共介面更改時,才會重新產生 WSDL

 

基本編碼


Web
服務的程式碼具有下列元素:

  • 實現程式碼的Class定義。該Class必須成為屬性框的 Basics 選項頁中命名的 PortType Class,且必須是公共的。
  • Class中,Web 服務中每個操作的過程(函數、副程式或方法)定義。這些過程必須是公共的。不想放在介面中的支援過程必須是私有的。
  • LotusScript lsxsd.lss 的包含。Java lotus.domino.types.* 的導入。
  • 存取 Domino Objects 物件時 NotesSession (LotusScript) Session (Java) 的初始化。對於 LotusScriptobject,此操作最好是在建構程式中完成,對於 Java,最好是在無建構函數中完成。對於 Java,使用 WebServiceBase.getCurrentSession() 來獲得 Session 物件。我們可能還想使用 Session.getAgentContext() 來獲得 AgentContext 物件。WebServiceBase 等同於 JavaAgent,但 Web 服務不能存取物件。惟一有用的方法是靜態 getCurrentSession()

下面是 LotusScript 程式碼的範本,其中 Web 服務包含一個操作。該操作是上述具有三個輸入參數和一個返回值的範例操作。

 

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class GetSubject
  Sub NEW
    Set s = New NotesSession
  End Sub
  Function getNthSubject(dbname As String, viewname As String, n As Long) As String
        ! Code for doing the operation goes here
  End Function
End Class

 

Top

 

下面是 Java 程式碼的範本,其中 Web 服務包含一個操作。建構函數必須是預設建構函數(無參數)。其他建構函數被忽略。

 

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {
  Session s;
  public GetSubject() {
    s = WebServiceBase.getCurrentSession();
  }
  public String getNthSubject(String dbname, String viewname, int n) {
        // Code for doing operation goes here
  }
}

 

 

現在我們將擴展範例以包括工作程式碼。下面是 LotusScript 程式碼:

 

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class GetSubject
  Sub NEW
    Set s = New NotesSession
  End Sub
  Function getNthSubject(dbname As String, viewname As String, n As Long) As String
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim doc As NotesDocument
    Set db = s.GetDatabase("", dbname)
    If Not(db.IsOpen) Then
      getNthSubject = "Cannot open database " & dbname
      Exit Function
    End If
    Set view = db.GetView(viewname)
    If view Is Nothing Then
      getNthSubject = "Cannot open view " & viewname
      Exit Function
    End If
    Set doc = view.GetNthDocument(n)
    If doc Is Nothing Then
      getNthSubject = "Cannot get document " & n
      Exit Function
    End If
    If doc.HasItem("Subject") Then
      getNthSubject = doc.GetItemValue("Subject")(0)
    Else
      getNthSubject = "Document does not have Subject"
    End If
  End Function
End Class

 

Top

下面是 Java 程式碼:

 

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {
  Session s;
  public GetSubject() {
    s = WebServiceBase.getCurrentSession();
  }
  public String getNthSubject(String dbname, String viewname, int n) {
    String subject = null;
    try {
      Database db = s.getDatabase(null, dbname);
      if (!db.isOpen()) subject = "Cannot open database " + dbname;
      else {
        View view = db.getView(viewname);
        if (view == null) subject = "Cannot open view " + viewname;
        else {
          Document doc = view.getNthDocument(n);
          if (doc == null) subject = "Cannot get document " + n;
          else {
            if (doc.hasItem("Subject"))
              subject = doc.getItemValueString("Subject");
            else subject = "Document does not have Subject";
          }
        }
      }
    }
    catch(Exception e) {
      subject = e.toString();
      e.printStackTrace();
    }
    return subject;
  }
}

 

調用和測試 Web 服務


最終,Web 服務設計元素必須駐留在執行 HTTP Domino 7 伺服器上。我們可以測試駐留於 Domino Designer 上的 Web 服務設計元素。首先必須在啟動 HTTP 的任何位置(比如,表單)選擇 Web Browser 中的 Design - Preview。如果消費者與 Notes 用戶端位於同一機器上,則使用 127.0.0.1 作為電腦位址。要扮演 Web 服務的消費者,必須在 HTTP 請求中向 Domino Web 服務的 URL 發送一條 SOAP 訊息。URL 如下:

http://rperron300pl.notesdev.ibm.com/Webservices2.nsf/GetSubject?OpenWebService

SOAP 訊息如下:

 

Top  

<SOAP-ENV:Envelope
 ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 <SOAP-ENV:Body>
  <ns0:getNthSubject (1) 
   SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
   xmlns:ns0="urn:DefaultNamespace">
   <dbname xsi:type="xsd:string">Webservices2</dbname> (2) 
   <viewname xsi:type="xsd:string">Main View</viewname> (2) 
   <n xsi:type="xsd:int">2</n> (2) 
  </ns0:getNthSubject>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

 

在本例中,SOAP 訊息 (1) 標識操作,(2) 並提供輸入部分的值。顯示在 SOAP-ENV:body 中的特定元素由 WSDL binding特徵確定,尤其是 SOAP 訊息格式。(詳細資訊請參閱下文的“進階屬性”)。

Web 服務的 WebSphere SDK 提供了調用 Web 服務和查看結果的工具。此 SDK 執行於 Eclipse 中。必須安裝:

WebSpere SDK(截止撰寫本文時)不與 Eclipse 3.0 一起使用。還可以使用 WebSphere Studio Application Developer 來調用 Web 服務。最新版本是 v5.1.2

要支援 WebSphere SDK 工具,打開 Eclipse 並選擇 Run - Launch the Web Services ExplorerWeb Services Explorer 載入後:

1.       按下 WSDL Page 圖示。它是右上角右箭頭之後的第三個圖示。WSDL Main 鏈結顯示在左邊的 Navigator 窗格中。

2.       按下 WSDL Main 鏈結。Open WSDL 框顯示在右窗格中。

3.       用命令 ?WSDL 輸入 Web 服務的 URL,例如,http://rperron300pl.notesdev.ibm.com/Webservices2.nsf/GetSubject?WSDL,然後按下 Go。我們想要 ?WSDL(而非 ?OpenWebService),因為此處 Web Services Explorer 閱讀 WSDL 文件。

4.       WSDL Binding Details 框顯示在右窗格中,它包含到 Web 服務定義的操作的鏈結。

5.       按下操作名稱,例如 getNthSubject。顯示 Invoke a WSDL Operation 框。

6.       輸入輸入部分(參數)的值,然後按下 Go

回應返回在底部 (Status) 窗格中。調用範例 Web 服務之後,Web Services Explorer 的外觀如下。

Top

 

5. Web Services Explorer

 

Actions 框的右上角有 Source 鏈結。按下 Source 顯示實際 SOAP 訊息。可以修改 SOAP 訊息,然後按下 Go 將其發送。按下右上角的 Form 以返回到原始顯示。Status 框也有 Source 鏈結,該鏈結允許查看 SOAP 回應,如果狀態指示沒有要顯示的內容(且期望回應),則程式碼可能失敗了。

執行 Web 服務之後,檢查伺服器控制臺或 log.nsf 以獲得錯誤訊息。可以透過插入 MessageBox 語句來登錄或測試,從而列印到伺服器控制臺或 log.nsf。(不要使用 Beta 2 中的 Print 列印語句。這些語句轉到代理程式的 HTTP 網頁並破壞 SOAP 回應。)

 

進階屬性


屬性框的 Advanced 選項頁影響 WSDL 文件反映的 Web 服務定義。

6. Web Services Property 框的 Advanced 選項頁

 

可以提供想要為埠類型、服務元素和服務埠命名的名稱。例如,可以將 GetSubject 用作所有名稱。為了清晰,使用反映元素類型的尾碼。在屬性框中提供名稱時,這些名稱插入到產生的 WSDL 文件中。如果導入 WSDL 文件,則 WSDL 文件中的名稱自動插入到屬性框中。

 

下面是 GetSubject 範例完整的 WSDL 文件。註釋部分是 Web Services Property 框的 Advanced 選項頁反映的內容。

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="urn:DefaultNamespace" 
xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" 
xmlns:impl="urn:DefaultNamespace" xmlns:intf="urn:DefaultNamespace" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <wsdl:message name="getNthSubjectResponse">
  <wsdl:part name="getNthSubjectReturn" type="xsd:string"/> (6) 
 </wsdl:message>
 <wsdl:message name="getNthSubjectRequest">
 <wsdl:part name="dbname" type="xsd:string"/> (6) 
 <wsdl:part name="viewname" type="xsd:string"/> (6) 
 <wsdl:part name="n" type="xsd:int"/> (6) 
</wsdl:message>
 <wsdl:portType name="GetSubjectPortType"> (1) 
  <wsdl:operation name="getNthSubject"
        parameterOrder="dbname viewname n">
   <wsdl:input message="impl:getNthSubjectRequest"
                  name="getNthSubjectRequest"/>
   <wsdl:output message="impl:getNthSubjectResponse"
                   name="getNthSubjectResponse"/>
  </wsdl:operation>
 </wsdl:portType>
 <wsdl:binding name="GetSubjectPortSoapBinding"
               type="impl:GetSubjectPortType">
  <wsdlsoap:binding style="rpc" (4) 
                transport="http://schemas.xmlsoap.org/soap/http"/>
  <wsdl:operation name="getNthSubject">
   <wsdlsoap:operation soapAction=""/> (7) 
   <wsdl:input name="getNthSubjectRequest">
    <wsdlsoap:body
      encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" (5) 
      namespace="urn:DefaultNamespace" use="encoded"/> (5) 
  </wsdl:input>
   <wsdl:output name="getNthSubjectResponse">
    <wsdlsoap:body
      encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" (5) 
      namespace="urn:DefaultNamespace" use="encoded"/> (5) 
  </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
 <wsdl:service name="GetSubjectElement"> (2) 
  <wsdl:port binding="impl:GetSubjectPortSoapBinding"
                name="GetSubjectPort"> (3) 
   <wsdlsoap:address location="http://localhost"/>
  </wsdl:port>
 </wsdl:service>
</wsdl:definitions>

Top

 

(1) 埠類型定義一組操作。WSDL 文件包含 wsdl:portType 的名稱屬性,對應於 Port 類型名稱進階屬性。

 

(2) 服務標識支援的埠。WSDL 文件包含 wsdl:service 的名稱屬性,對應於 Service 元素名稱進階屬性。如果 WSDL 是透過 Export WSDLShow WSDL Domino Designer 中的瀏覽器預覽獲得的,則 wsdlsoap:address 的位置屬性不正確;如果 WSDL 是透過 ?WSDL URL 命令從伺服器中獲得的,則位置屬性是正確的。

 

(3) 埠標識binding,而binding又反過來標識埠類型並提供了其他資訊。WSDL 文件包含 wsdl:service wsdl:port 的名稱屬性。Domino 允許一個服務,並且每個服務允許一個埠。

 

(4) 兩種程式開發模型和四種 SOAP 訊息格式可用。RPC 程式開發模型允許四種 SOAP 訊息格式:RPC/encodedRPC/literalDoc/literal WrappedDoc/encoded 的實用程式是第五種可用格式,但因為不好理解,所以此處不支援)。Message 程式開發模型強制 Doc/literal 訊息格式,但只作為提示;在基於 Message Web 服務中傳遞的實際 SOAP 訊息格式沒有發佈,但透過消費者和供應商之間的私有合同來規定。 wsdlsoap:binding 的樣式屬性設定如下:

  • 對於 RPC/encoded RPC/literalwsdlsoap:binding style="rpc"
  • 對於 Doc/literal Wrappedwsdlsoap:binding style="document"

(5) wsdl:binding 下的輸入和輸出元素中,wsdlsoap:body 的使用屬性設定如下:

  • 對於 RPC/encodedwsdlsoap:body use="encoded"。在這一情況下,有一個 encodingStyle 屬性。
  • 對於 RPC/literalDoc/literal Wrappedwsdlsoap:body use="literal"。在這些情況下,沒有 encodingStyle 屬性。

(6) 對於 RPC/encoded RPC/literal,每個訊息部分透過直接引用 XMLSchema 名稱空間(例如,type="xsd:string" type="xsd:int")或 WSDL "types" 部分(本例未顯示)中定義的複雜類型來定義資料類型。

對於 Doc/literal,每個訊息部分引用先前定義的資料元素。下面是帶有指定 Doc/literal 的範例 WSDL 中的程式碼段。在 wsdl:types 下,每個輸出部分在按照過程程式碼中相應參數命名的元素中定義,輸出部分在按照過程加“Return”命名的元素中定義。

 

<wsdl:types>
 <schema targetNamespace="urn:DefaultNamespace"
          xmlns="http://www.w3.org/2001/XMLSchema">
   <element name="dbname" type="xsd:string"/>
   <element name="viewname" type="xsd:string"/>
   <element name="n" type="xsd:int"/>
   <element name="getNthSubjectReturn" type="xsd:string"/>
  </schema>
</wsdl:types>
<wsdl:message name="getNthSubjectResponse">
  <wsdl:part element="impl:getNthSubjectReturn"
             name="getNthSubjectReturn"/>
</wsdl:message>
<wsdl:message name="getNthSubjectRequest">
  <wsdl:part element="impl:dbname" name="dbname"/>
  <wsdl:part element="impl:viewname" name="viewname"/>
  <wsdl:part element="impl:n" name="n"/>
</wsdl:message>

 

 

對於 Wrapped,每個訊息有一個部分,該部分引用先前定義的 complexType 類型的元素,元素按照使用它且無屬性的操作命名。下面是具有指定 Wrapped WSDL 程式碼段。

 

<wsdl:types>
  <schema targetNamespace="urn:DefaultNamespace"
          xmlns="http://www.w3.org/2001/XMLSchema">
   <element name="getNthSubject">
    <complexType>
     <sequence>
      <element name="dbname" type="xsd:string"/>
      <element name="viewname" type="xsd:string"/>
      <element name="n" type="xsd:int"/>
     </sequence>
    </complexType>
   </element>
   <element name="getNthSubjectResponse">
    <complexType>
     <sequence>
      <element name="getNthSubjectReturn" type="xsd:string"/>
     </sequence>
    </complexType>
   </element>
  </schema>
</wsdl:types>
<wsdl:message name="getNthSubjectResponse">
  <wsdl:part element="impl:getNthSubjectResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getNthSubjectRequest">
  <wsdl:part element="impl:getNthSubject" name="parameters"/>
</wsdl:message>

Top

 

有關 SOAP 格式的完美討論,參閱由 Russell Butek 撰寫的 developerWorks 文章“Which style of WSDL should I use?”。

(7) soapAction="" if "Include operation name in SOAP action" 保留不選中。如果選中該選項,則 soapAction 指定操作的名稱,例如:

<wsdlsoap:operation soapAction="getNthSubject"/>

安全性


Web
服務安全性類似於從 Web 中調用的伺服器代理程式的安全性。下面是 Web Services Property 框中 Security 選項頁的範例。

7. Web Services Property 框中的 Security 選項頁

 

前兩行確定誰在執行 Web 服務,即誰是有效用戶:如果兩行都不使用,則有效用戶是 Web 服務的所有者(編輯或簽名設計元素的最後一個用戶)。

  • 如果選中“Run as Web user”選項,則有效用戶是協商網路存取包含 Web 服務的資料庫的用戶:如果資料庫允許匿名存取則為 Anonymous,否則為提供給認證過程的名稱。
  • 如果填充了“Run on behalf of”欄位,則有效用戶是該用戶。

Web 服務的消費者必須能夠協商存取伺服器。如果 HTTP 埠允許匿名存取,則存取自動進行。否則,用戶必須提供有效的名稱和 Internet 密碼進行認證。資料庫 ACL 必須給予有效用戶至少一個選中 Read 公共文件的 Depositor 存取權。  

 

Compile Java code with debugging information”允許從 Java 測試器(比如支援 JPDA Java Platform Debugger ArchitectureJava 平臺測試器架構)的 Eclipse)連接到執行中的 Web 服務。Java 測試是版本 7 的新特性,且僅工作在 Notes 用戶端上。為了測試,Web 服務必須駐留在 Notes 用戶端上。透過選擇任何位置的 Web Browser 中的 Design - Preview,啟動用戶端上的 HTTP 任務。調用 Web 服務。Web 服務應包含只測試程式碼,以暫停片刻。然後將測試器連接到執行中的 Web 服務。  

 

對於 LotusScript Web 服務,“Allow remote debugging”代替 Java 測試行。Web 服務的遠端測試與代理程式的遠端測試相同。在這種情況下,Web 服務必須駐留在伺服器上。

 

Profile this Web service”允許收集 Domino Objects 用去的時間。要報告所選 Web 服務的結果,選擇 Design - View Profile Results。概要分析是版本 7 的新特性,用於 LotusScript Java 編碼的代理程式,以及 Web 服務。  

 

Top

“Set runtime security level”框允許三個級別的安全性。編號越高的安全性級別允許潛在損壞操作,比如寫入文件系統,操作環境變數,等等。  

 

對於“Default access to this Web service”,可以允許所有讀者及以上用戶,或者可以列舉具有存取權的用戶。  

 

Web 服務上下文


Web 服務使用與代理程式相同的框架。在後端,大多數但非全部代理程式上下文應用於 Web 服務。我們已經看到如何在 Java 中獲得 Session AgentContext 物件,如何在 LotusScript 中獲得 NotesSession 物件。下面是與 Web 服務關聯的其他主要上下文元素。  

 

上下文元素

Java

LotusScript

當前 Web 服務

AgentContext.getCurrentAgent();

NotesSession.CurrentAgent

當前資料庫

AgentContext.getCurrentDatabase();

NotesSession.CurrentDatabase

列印到伺服器控制臺和 log.nsf

System.out

Messagebox

Web 服務名稱和別名

Agent.getName();

NotesAgent.Name

Web 服務所有者(完整名稱)

Agent.getOwner();

NotesAgent.Owner

Web 服務所有者(共用名稱)

Agent.getCommonOwner();

NotesAgent.CommonOwner

Web 服務執行時所有者

Agent.getOnBehalfOf();

NotesAgent.OnBehalfOf

Web 服務備註

Agent.getComment();

NotesAgent.Comment

Web 服務 HTTP URL

Agent.getHttpURL();

NotesAgent.HttpURL

Web 服務 Notes URL

Agent.getNotesURL();

NotesAgent.NotesURL

Web 服務父資料庫

Agent.getParent();

NotesAgent.Parent

Web 服務鎖持有者

Agent.getLockHolders();

NotesAgent.LockHolders

 

Web 服務設計元素與代理程式一樣,可以加鎖和解鎖。

下面是 LotusScript 範例,展示了獲得與 Web 服務上下文關聯的屬性。Web 服務具有三個操作。  

 

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Dim agent As NotesAgent
Class GetAgentContext
  Sub NEW
    Set s = New NotesSession
    Set agent = s.CurrentAgent
  End Sub
  Function getAgentName() As String
    getAgentName = agent.Name
  End Function
  Function getEffectiveUserName() As String
    getEffectiveUserName = s.EffectiveUserName

 End Function
    Function getDatabaseFileName() As String
    Dim db As NotesDatabase
    Set db = s.CurrentDatabase
    getDatabaseFileName = db.FileName
  End Function
End Class

下面是 Java 程式碼。

import lotus.domino.*;
import lotus.domino.types.*;
public class GetAgentContext {
  Session s;
  AgentContext ac;
  public GetAgentContext() {

    s = WebServiceBase.getCurrentSession();

    try {
      ac = s.getAgentContext();
    } catch(Exception e) {

      e.printStackTrace(); }
  }

  public java.lang.String getAgentName() {
    String agentName = null;
    try {
      Agent agent = ac.getCurrentAgent();
      agentName = agent.getName();  }
    catch(Exception e) {
      e.printStackTrace(); }
    return agentName;
  }
  public java.lang.String getEffectiveUserName() {
   String userName = null;
    try {
      userName = ac.getEffectiveUserName();  }
    catch(Exception e) {
      e.printStackTrace(); }

   return userName;

 } java.lang.String getCurrentDatabase() {
    String dbFileName = null;
    try {
      Database db = ac.getCurrentDatabase();
      dbFileName = db.getFileName();  }
    catch(Exception e) {
      e.printStackTrace(); }

   return dbFileName;

 }
}

 

Top

 

複雜資料類型


使用下列模型的操作不需要複雜資料類型:

  • 單個標量輸出值(或無輸出值)
  • 標量輸入值(或無輸入值)

返回多個標量輸出值或接受多個標量輸入值的操作需要複雜資料類型。使用複雜資料類型允許移動大的、各種不同的資料結構。  

 

下面幾節討論複雜資料類型:

  • 陣列
  • Class
  • Inout 和輸出參數

陣列


陣列對應為按資料類型加尾碼的名為 ArrayOf complexType WSDL 元素。WSDL complexType 元素定義為陣列。  

例如,按 Java 方法實現的下列操作返回 String 陣列。

 

public java.lang.String[] getAll() {
  String[] info = new String[3];
  try {
    info[0] = ac.getEffectiveUserName();
    info[1] = s.getPlatform();
    info[2] = s.getNotesVersion(); }
  catch(Exception e) {
    e.printStackTrace(); }
  return info;
}

 

 

Java String 陣列對應為名為 ArrayOf_xsd_string WSDL complexType 元素,該元素被定義為 string 類型的陣列。定義 getAll 操作 (getAllResponse) 返回值的訊息有一個部分,其類型為 ArrayOf_xsd_string  

 

- <wsdl:types>
  - <schema targetNamespace="urn:DefaultNamespace"
     xmlns="http://www.w3.org/2001/XMLSchema">
      <import namespace="http://schemas.xmlsoap.org/soap/encoding/" /> 
    - <complexType name="ArrayOf_xsd_string">
      - <complexContent>
        - <restriction base="soapenc:Array">
            <attribute ref="soapenc:arrayType"
              wsdl:arrayType="xsd:string[]" /> 
          </restriction>
        </complexContent>
      </complexType>
    </schema>
  </wsdl:types>
- <wsdl:message name="getAllResponse">

  <wsdl:part name="getAllReturn" type="impl:ArrayOf_xsd_string" /> 
  </wsdl:message>

 

 

LotusScript 中,不能為 Web 服務消費者返回陣列。語言規則要求資料返回值必須定義為不提供足夠資訊的 Variant,以便在產生 WSDL 時解釋類型。解決方案是將陣列放在Class中,如下所示。  

 

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class infoArray
  Public info() As String
End Class
Class GetSessionInfo
  Sub NEW
    Set s = New NotesSession

 End Sub
  Function getItAll() As infoArray
    Set getItAll = New infoArray
    Redim getItAll.info(1 To 3)
    getItAll.info(1) = s.EffectiveUserName
    getItAll.info(2) = s.Platform
    getItAll.info(3) = s.NotesVersion
  End Function
End Class

 

Class

 

Class對應為按Class命名的 complexType WSDL 元素。下面的 Java 範例提供與 Arrays 範例相同的資料,但不是返回陣列,而是返回物件。

  

Top

public InfoClass getAll2() {
  InfoClass info = new InfoClass();
  try {
    info.effectiveUserName = ac.getEffectiveUserName();
    info.platform = s.getPlatform();
    info.notesVersion = s.getNotesVersion(); }
  catch(Exception e) {
    e.printStackTrace(); }
  return info;
}
public class InfoClass {
  public String effectiveUserName;
  public String platform;
  public String notesVersion;
}

 

Java Class InfoClass 對應為同名的 complexTypecomplexType 有三個元素,每個元素的類型都為 xsd:string,按 Java InfoClass Class中的公共資料元素命名。  

 

- <wsdl:types>
  - <schema targetNamespace="urn:DefaultNamespace"
      xmlns="http://www.w3.org/2001/XMLSchema">
      <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
    - <complexType name="InfoClass">
      - <sequence>
          <element name="notesVersion"
            nillable="true" type="xsd:string" /> 
          <element name="platform"
            nillable="true" type="xsd:string" /> 
          <element name="effectiveUserName"
            nillable="true" type="xsd:string" /> 
        </sequence>
      </complexType>
    </schema>
  </wsdl:types>
- <wsdl:message name="getAll2Response">
    <wsdl:part name="getAll2Return" type="impl:InfoClass" /> 
  </wsdl:message>

 

 

下面是相同的 LotusScript 範例。  

 

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class InfoClass
  Public EffectiveUserName As String
  Public Platform As String
  Public NotesVersion As String
End Class
Class GetSessionInfo
  Sub NEW
    Set s = New NotesSession
  End Sub
  Function getItAll2() As InfoClass
    Set getItAll2 = New InfoClass
    getItAll2.EffectiveUserName = s.EffectiveUserName
    getItAll2.Platform = s.Platform
    getItAll2.NotesVersion = s.NotesVersion
  End Function
End Class

 

Inout 和輸出參數


當輸出訊息有一個部分時,不管它是簡單類型還是複雜類型,輸出都對應為函數或方法的返回值。如果輸出訊息有多個部分,則輸出對應為參數,而非返回值。完整的對應取決於輸入部分以及輸入部分與輸出部分的組合。如果第一個輸出部分與任何輸入都不匹配,且其餘輸出部分與輸入部分相匹配,則第一個輸出部分對應為函數或方法的返回值,而其餘部分對應為 inout 參數。  

 

Top

否則,匹配的輸入和輸出部分對應為 inout 參數,不匹配的輸入部分對應為輸入參數,不匹配的輸出部分對應為輸出參數。在這種情況下,沒有返回值,而且對於 LotusScript,使用副程式而非函數。  

 

下列 WSDL 程式碼段是第一個範例的延伸,它返回輸入值作為回應:  

 

- <wsdl:message name="getNthSubjectResponse">
    <wsdl:part name="getNthSubjectReturn" type="xsd:string" /> (1)
    <wsdl:part name="dbname" type="xsd:string" /> (2)
    <wsdl:part name="viewname" type="xsd:string" /> (3)
    <wsdl:part name="n" type="xsd:int" /> (4)
  </wsdl:message>
- <wsdl:message name="getNthSubjectRequest">
    <wsdl:part name="dbname" type="xsd:string" /> (2)
    <wsdl:part name="viewname" type="xsd:string" /> (3)
    <wsdl:part name="n" type="xsd:int" /> (4)
  </wsdl:message>

 

(1) 一個輸出部分與輸入部分不匹配 —— getNthSubjectReturn。該部分對應為函數或方法返回值。(2)(3)(4) 其餘三個輸出部分 —— dbnameviewname n —— 與三個輸入部分相同。這幾個部分對應為 inout 參數。

Inout 和輸出參數不能是基本資料類型。標準 Java 提供包 javax.xml.rpc.holders,其中具有儲存各種類型的 inout 和輸出參數的方法。Lotus Domino inout 和輸出參數對應為下列Class,如下所示:  

 

BigDecimalHolder

CalendarHolder

LongHolder

BigIntegerHolder

DoubleHolder

LongWrapperHolder

BooleanHolder

DoubleWrapperHolder

ObjectHolder

BooleanWrapperHolder

FloatHolder

QNameHolder

ByteArrayHolder

FloatWrapperHolder

ShortHolder

ByteHolder

IntegerWrapperHolder

ShortWrapperHolder

ByteWrapperHolder

IntHolder

StringHolder

 

 

這些Class有一個應用程式可以獲得和設定的公共變數“value”。下例是 getNthSubject 範例的延伸,它像以前一樣返回一個 String,但透過使用 StringHolder IntHolder Class產生三個 inout 參數。這些參數的值作為 SOAP 回應傳回給消費者。  

 

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {
  Session s;
  public GetSubject() {
    s = WebServiceBase.getCurrentSession();
  }
  public String getNthSubject(javax.xml.rpc.holders.StringHolder dbname,
      javax.xml.rpc.holders.StringHolder viewname,
      javax.xml.rpc.holders.IntHolder n) {
    String subject = null;
    try {
      Database db = s.getDatabase(null, dbname.value);
      if (!db.isOpen()) subject = "Cannot open database " + dbname.value;
      else {
       View view = db.getView(viewname.value);
        if (view == null) subject = "Cannot open view " + viewname.value;
        else {
          Document doc = view.getNthDocument(n.value);
          if (doc == null) subject = "Cannot get document " + n.value;
          else {
            if (doc.hasItem("Subject"))
              subject = doc.getItemValueString("Subject");
            else subject = "Document does not have Subject";
          }
        }
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
   return subject;
  }
}

 

 

對於 LotusScriptinclude 文件 lsxsd.lss inout 和輸出參數定義了下列持有者Class  

Top

 

BOOLEAN_HOLDER

LONG_HOLDER

BOOLEANARRAY_HOLDER

LONGARRAY_HOLDER

BYTE_HOLDER

SINGLE_HOLDER

BYTEARRAY_HOLDER

SINGLEARRAY_HOLDER

DOUBLE_HOLDER

STRING_HOLDER

DOUBLEARRAY_HOLDER

STRINGARRAY_HOLDER

INTEGER_HOLDER

VARIANT_HOLDER

INTEGERARRAY_HOLDER

VARIANTARRAY_HOLDER

 

 

這些Class有一個應用程式可以獲得和設定的公共變數“Value”。下一個 LotusScript 範例與前面的 Java 範例相同。持有者Class用於三個 inout 參數。

 

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Class GetSubject
 Sub NEW
   Set s = New NotesSession
 End Sub
  Function getNthSubject(dbname As String_Holder, _
  viewname As String_Holder, _
  n As Long_Holder) As String
    Dim db As NotesDatabase
    Dim view As NotesView
    Dim doc As NotesDocument
    Set db = s.GetDatabase("", dbname.Value)
    If Not(db.IsOpen) Then
      getNthSubject = "Cannot open database " & _
          dbname.Value
      Exit Function
    End If
    Set view = db.GetView(viewname.Value)
    If view Is Nothing Then
      getNthSubject = "Cannot open view " & _
           viewname.Value
      Exit Function
    End If
   Set doc = view.GetNthDocument(n.Value)
    If doc Is Nothing Then
      getNthSubject = "Cannot get document " & _
          n.Value
      Exit Function
    End If
    If doc.HasItem("Subject") Then
      getNthSubject = doc.GetItemValue("Subject")(0)
    Else
      getNthSubject = "Document does not have Subject"
    End If
  End Function
End Class

 

 

資料類型對應


基本資料類型及其 XSD 對應物一般來回對應。例外情況是導入的 SOAPENC 資料類型對應為物件。但是,物件在輸出到產生的 WSDL 時,對應為 XSD 資料類型。  

Top

 

導入的 WSDL

Java 資料類型
LotusScript
資料類型

產生的 WSDL

xsd:boolean

boolean
Boolean

xsd:boolean

soapenc:boolean

java.lang.Boolean
XSD_BOOLEAN (1)

xsd:boolean

xsd:byte

byte
XSD_BYTE (2)

xsd:byte

soapenc:byte

java.lang.Byte
XSD_BYTE

xsd:byte

xsd:double

double
Double

xsd:double

soapenc:double

java.lang.Double
XSD_DOUBLE

xsd:double

xsd:float

float
Single

xsd:float

soapenc:float

java.lang.Float
XSD_FLOAT

xsd:float

xsd:int

int
Long

xsd:int

soapenc:int

java.lang.Integer
XSD_INT

xsd:int

xsd:long

long
XSD_LONG (3)

xsd:long

soapenc:long

java.lang.Long
XSD_LONG

xsd:long

xsd:short

short
Integer

xsd:short

soapenc:short

java.lang.Short
XSD_SHORT

xsd:short

xsd:string

java.lang.String (4)
String

xsd:string

soapenc:string

java.lang.String
XSD_STRING

xsd:string

 

(1) Java 使用 java.lang 中定義的包裝器Classjava.lang.Booleanjava.lang.Byte,等等。LotusScript 使用 lsxsd.lss 中定義的 XSD_ ClassXSD_BOOLEANXSD_BYTE,等等。LotusScript Class繼承下列方法:

Function GetValueAsString() As String
Sub SetValueAsString(value As String)

注意: 在未來的 Beta 版本中,名稱 SetValueAsString 將更改為 SetValueFromString

下面是返回 java.lang.Boolean 類型的操作的 Java 範例:  

 

import lotus.domino.*;
import lotus.domino.types.*;
public class GetDatabaseInfo {
  Session s;
 AgentContext ac;
 Database db;
  public GetDatabaseInfo() {
    s = WebServiceBase.getCurrentSession();
    try {
      ac = s.getAgentContext();
      db = ac.getCurrentDatabase();
    } catch(Exception e) {
      e.printStackTrace(); }
  }
 public Boolean doesViewExist(String viewName) {
    Boolean b = null;
    try {
      if (db.getView(viewName) == null)
        b = new Boolean(false);
      else
        b = new Boolean(true);
    } catch(Exception e) {
      e.printStackTrace(); }
    return b;
  }
}

 

LotusScript 中的對應操作返回 XSD_BOOLEAN 類型:  

Top

 

Option Public
%INCLUDE "lsxsd.lss"
Dim s As NotesSession
Dim db As NotesDatabase
Class GetDatabaseInfo
  Sub NEW
    Set s = New NotesSession
    Set db = s.CurrentDatabase
  End Sub
  Function DoesViewExist(viewName As String) As XSD_BOOLEAN
    Set b = New XSD_BOOLEAN
    If db.GetView(viewName) Is Nothing Then
      Call b.SetValueAsString("False")
    Else
      Call b.SetValueAsString("True")
    End If
    Set DoesViewExist = b
  End Function
End Class

 

(2) LotusScript 不為 xsd:byte 使用基本資料類型。它通常對應為 XSD_BYTELotusScript 基本資料類型對應為 xsd:unsignedByte)。 (3) LotusScript 不為 xsd:long 使用基本資料類型。它通常對應為 XSD_LONGLotusScript 基本資料類型對應為 xsd:int)。 (4) Java 沒有 xsd:string 的基本資料類型。它通常對應為 java.lang.String

其他 XSD 資料類型在 Java 中對應為 java.langjava.mathjava.util lotus.domino.typesLotus Notes/Domino 7 的新特性)物件,在 LotusScript 中對應為 XSD_ objects  

 

WSDL

Java 資料類型
LotusScript
資料類型

xsd:anyType

java.lang.Object
XSD_ANYTYPE
Variant (1)

xsd:anyURI

lotus.domino.types.URI
XSD_ANYURI

xsd:base64Binary
soapenc:base64 (2)

byte[]

xsd:date

java.util.Date
XSD_DATE

xsd:dateTime

java.util.Calendar
XSD_DATETIME

xsd:decimal
soapenc:decimal (3)

java.math.BigDecimal
XSD_DECIMAL

xsd:duration

lotus.domino.types.Duration
XSD_DURATION

xsd:ENTITY

lotus.domino.types.Entity
XSD_ENTITY

xsd:ENTITES

lotus.domino.types.Entities
XSD_ENTITIES

xsd:gDay

lotus.domino.types.GDay
XSD_GDAY

xsd:gMonth

lotus.domino.types.GMonth
XSD_GMONTH

xsd:gMonthDay

lotus.domino.types.GMonthDay
XSD_GMONTHDAY

xsd:gYear

lotus.domino.types.GYear
XSD_GYEAR

xsd:gYearMonth

lotus.domino.types.GYearMonth
XSD_GYEARMONTH

xsd:hexBinary

lotus.domino.types.HexBinary
XSD_HEXBINARY

xsd:ID

lotus.domino.types.Id
XSD_ID

xsd:IDREF

lotus.domino.types.IDRef
XSD_IDREF

xsd:IDREFS

lotus.domino.types.IDRefs
XSD_IDREFS

xsd:integer
soapenc:integer (3)

java.math.BigInteger
XSD_INTEGER

xsd:language

lotus.domino.types.Language
XSD_LANGUAGE

xsd:Name

lotus.domino.types.Name
XSD_NAME

xsd:NCName

lotus.domino.types.NCName
XSD_NCNAME

xsd:negativeInteger

lotus.domino.types.NegativeInteger
XSD_NEGATIVEINTEGER

xsd:NMTOKEN

lotus.domino.types.NMToken
XSD_NMTOKEN

xsd:NMTOKENS

lotus.domino.types.NMTokens
XSD_NMTOKENS

xsd:nonNegativeInteger

lotus.domino.types.NonNegativeInteger
XSD_NONNEGATIVEINTEGER

xsd:nonPositiveInteger

lotus.domino.types.NonPositiveInteger
XSD_NONPOSITIVEINTEGER

xsd:NOTATION

lotus.domino.types.Notation
XSD_NOTATION

xsd:normalizedString

lotus.domino.types.NormalizedString
XSD_NORMALIZEDSTRING

xsd:positiveInteger

lotus.domino.types.PositiveInteger
XSD_NONPOSITIVEINTEGER

xsd:QName

javax.xml.namespace.QName
XSD_QNAME

xsd:time

lotus.domino.types.Time
XSD_TIME

xsd:token

lotus.domino.types.Token
XSD_TOKEN

xsd:unsignedByte

lotus.domino.types.UnsignedByte
Byte
XSD_UNSIGNEDBYTE (4)

xsd:unsignedInt

lotus.domino.types.UnsignedInt
XSD_UNSIGNEDINT

xsd:unsignedLong

lotus.domino.types.UnsignedLong
XSD_UNSIGNEDLONG

xsd:unsignedShort

lotus.domino.types.UnsignedShort
XSD_UNSIGNEDSHORT

 

(1) Variant 在輸出到產生的 WSDL 時對應為 xsd:anyType (2) soapenc:base64 在從 WSDL 導入時對應為 byte[] Byte。產生的 WSDL 通常對應為 xsd:base64Binary (3) soapenc:decimal soapenc:integer 在從 WSDL 導入時對應為 XSD:DECIMAL XSD:INTEGER。產生的 WSDL 通常對應為 xsd:decimal xsd:integer (4) xsd:unsignedByte 在從 WSDL 導入時對應為 ByteByte XSD_UNSIGNEDBYTE 在產生的 WSDL 中都對應為 xsd:unsignedByte  

Top

 

私有過程


Domino Web 服務在實現Class中暴露公共函數、副程式和方法。私有過程被隱藏了。下面是 GetSubject 範例的延伸,它使用公共過程來暴露操作 getFirstSubjectgetLastSubject getNthSubject。公用程式碼透過私有過程 openDatabaseopenView getSubject 提供。  

 

Dim s As NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc As NotesDocument
Dim msg As String
Class GetSubject
  Sub NEW
    Set s = New NotesSession
  End Sub
  Function getFirstSubject(dbname As String, viewname As String) As String
   If openDatabase(dbname) Then
      If openView(viewname) Then
        Set doc = view.GetFirstDocument
        If doc Is Nothing Then
          msg = "Cannot get first document "
        Else
          Call getSubject
        End If
      End If
    End If
    getFirstSubject = msg
  End Function
 Function getLastSubject(dbname As String, viewname As String) As String
    If openDatabase(dbname) Then
      If openView(viewname) Then
        Set doc = view.GetLastDocument
        If doc Is Nothing Then
          msg = "Cannot get last document "
        Else
          Call getSubject
        End If
      End If
    End If
    getLastSubject = msg
  End Function
  Function getNthSubject(dbname As String, viewname As String, n As Integer) As String
    If openDatabase(dbname) Then
      If openView(viewname) Then
        Set doc = view.GetNthDocument(n)
        If doc Is Nothing Then
          msg = "Cannot get document " & n
        Else
          Call getSubject
       End If
      End If
    End If
    getNthSubject = msg
  End Function
 Private  Function openDatabase(dbname As String) As Boolean
    Set db = s.GetDatabase("", dbname)
    If db.IsOpen Then
      openDatabase = True
    Else
      openDatabase = False
      msg = "Cannot open database " & dbname
    End If
  End Function
 Private Function openView(viewname As String) As Boolean
    Set view = db.GetView(viewname)
    If view Is Nothing Then
      openView = False
      msg = "Cannot open view " & viewname
    Else
      openView = True
    End If
  End Function
  Private Sub getSubject
    If doc.HasItem("Subject") Then
      msg = doc.GetItemValue("Subject")(0)
    Else
      msg = "Document does not have Subject"
    End If
  End Sub
End Class

 

 

下面是 Java 範例。  

Top

import lotus.domino.*;
import lotus.domino.types.*;
public class GetSubject {
  Session s;
  Database db;
  View view;
  Document doc;
  String msg;
 public GetSubject() {
    s = WebServiceBase.getCurrentSession();
  }
 public String getFirstSubject(String dbname, String viewname) {
    try {
      if (openDatabase(dbname)) {
        if (openView(viewname)) {
          doc = view.getFirstDocument();
          if (doc == null)
           msg = "Cannot get first document ";
          else
            getSubject();
        }
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    return msg;
  }
  public String getLastSubject(String dbname, String viewname) {
    try {
      if (openDatabase(dbname)) {
        if (openView(viewname)) {
          doc = view.getLastDocument();
          if (doc == null)
            msg = "Cannot get last document ";
          else
            getSubject();
        }
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    return msg;
  }
public String getNthSubject(String dbname, String viewname, int n) {
    try {
      if (openDatabase(dbname)) {
        if (openView(viewname)) {
          doc = view.getNthDocument(n);
          if (doc == null)
            msg = "Cannot get document " + n;
          else
            getSubject();
        }
      }
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    return msg;
  }
  private boolean openDatabase(String dbname) {
    boolean b = false;
    try {
      db = s.getDatabase(null, dbname);
      if (db.isOpen())
        b = true;
      else
        msg = "Cannot open database " + dbname;
    }
    catch(Exception e) {
     e.printStackTrace();
    }
    return b;
  }
 private boolean openView(String viewname) {
    boolean b = false;
    try {
      view = db.getView(viewname);
      if (view != null)
        b = true;
      else
        msg = "Cannot open view " + viewname;
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    return b;
  }
  private void getSubject() {
    try {
      if (doc.hasItem("Subject"))
        msg = doc.getItemValueString("Subject");
      else
        msg = "Document does not have Subject";
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }
}

 

Top

結束語


Lotus Notes/Domino 7 透過用 Java LotusScript 編碼的類似代理程式的設計元素來支援 Web 服務的供應商端。Web 服務必須駐留在啟用 HTTP Domino 7 伺服器上,此外,Web 服務可以透過 Notes 用戶端上的 Web 預覽來測試和測試。消費者透過 SOAP 編碼的 HTTP POST 請求來存取 Domino Web 服務。  

Web 服務操作對應為公共 Java 方法和公共 LotusScript 函數和副程式。Web 服務資料部分對應為參數和返回值。可能的話,XSD 資料類型對應為 Java LotusScript 基本類型。否則,complexType 元素對應為物件。  

本文基於 Lotus Notes/Domino 7 Beta 2 版本。在開發過程中可能進行增強。例如,未來版本預期支援將 Web 服務程式碼放置在Script程式庫中。  

 

參考資料  

 

您可以參閱本文在 developerWorks 全球站點上的 英文原文

Lotus Domino 支援 SOAP 1.1 WSDL 1.1。有關規範和背景資訊,請參閱下列 W3C 文件:

有關 SOAP 格式的詳細資訊,請閱讀 Russell Butek 撰寫的 developerWorks 文章“Which style of WSDL should I use?”。

透過參與 developerWorks blogs 加入 developerWorks 社區。

Developer Bookstore Lotus 專區購買 打折出售的 Lotus 書籍  

 

 

關於作者


Robert Perron 是位於麻塞諸塞州 Westford Lotus 的文件架構師。自從 20 世紀 90 年代初開始,他就一直為 Lotus Notes Domino 開發文件,主要致力於可程式開發能力的開發。他曾為 LotusScript Java Notes Class開發文件,並與別人合著了 60 Minute Guide to LotusScript 3 - Programming for Notes 4 一書。他為 LDD Today 撰寫了多篇文章。去年,他為 The View 撰寫了“A Comprehensive Tour of Programming Enhancements in Notes/Domino 6”一文。

Top

Lotus Notes 技術分享

如何在Web上編輯Notes Profile?

1.      先設計一個設定ProFile用的套表,套表屬性勾選[公式沿用選取文件的數值]的選項.

:套表中的每一個欄位的預設值公式都不能為空白,如沒有公式,那就直接以自己的欄位名稱當作公式.

2. 在該套表的WebQuerySave事件中執行儲存Profile的代理程式.

3. 上述代理程式的程式內容如下:

Sub Initialize

        Dim Session As New NotesSession

        Dim PDoc As NotesDocument

        Dim Doc As NotesDocument

        Dim Db As NotesDatabase

        Dim ProFileName As String

        ProFileName="($SystemSetup)"

        Set Db=Session.CurrentDatabase

        Set Doc=Session.Documentcontext

       

        Set PDoc=Db.Getprofiledocument(ProFileName)

        If PDoc Is Nothing Then

                Print "No System Setup Document! Use Notes Client Setup !"

        Else

                Call Doc.Copyallitems(PDoc,True)

                Call PDoc.Save(True,False)

                Doc.SaveOptions="1"

                Print "文件儲存ok!!"

        End If      

End Sub

4. 最後再撰寫一個開啟Profile的代理程式,代理程式名稱WebOpenSystemSetup,程式內容如下:

Sub Initialize

        Dim Session As New NotesSession

        Dim PDoc As NotesDocument

        Dim Db As NotesDatabase

        Dim ProfileName As String

        ProfileName="($SystemSetup)"

        Set Db=Session.CurrentDatabase

        Set PDoc=Db.Getprofiledocument(ProfileName)

        Cmd1=|@ReplaceSubstring(@ReplaceSubstring(@Subset(@DbName; -1); " "; "+" ); "\\"; "/" )|

        Dbname=Evaluate(Cmd1)

        If PDoc Is Nothing Then           

                Print "No System Setup Document! Use Notes Client Setup !"

        Else

                url= "/"+DbName(0) +"/"+ProfileName+|?OpenForm&ParentUNID=|+ PDoc.Universalid            

                Print "["+url+"]"

        End If      

End Sub 

5.最後只要在Web上開啟該代理程式就可以編輯該Profile.

6. 注意因為Web上之代理程式有Cache的情況會發生,所以有時已經將該Profile Save,但是重新開啟Profile時卻是仍看到舊值,這時只要先將IE全部關閉,然後重新開啟即可.

:如有需要可至智頡科技網站(http://www.wmmate.com)下載範例資料庫。  

Top

近期電子報內容預告

後續陸續會發行相關技術的電子報

內容預告如下:

Lotus Notes系統整合&應用介紹

  內容相當豐富敬請期待...

Top


註:如不想繼續收到本公司之電子報或是要介紹朋友訂閱電子報請至本公司網站線上設定/訂閱


智頡科技股份有限公司

Copyright 1999-2005     版權所有 轉載必究

TEL:03-5326262       FAX:03-5344873        Email:support@wmmate.com