PROGRAMMING DOMINO FOR WEB APPLICATIONS

Providing a Web service
A Domino application can have a Web service interface that allows it to be accessed as a Web Service by remote users or by Web server clients. Here's what you need to include in your application to make this possible:
Creating the Web service Web agent

Create an agent with the settings specified in "Setting up a Web agent."

This is the LotusScript code for the "WebService" Web agent in the Domino App.nsf database:

Sub Initialize

'Http://servername.com/Database+Name.nsf/agentName?OpenAgent

Dim s As New notessession
Dim doc As NotesDocument
Set doc = s.DocumentContext

'...Get SOAPin...

This line of code sets the SOAPin variable equal to the content of the "Request_content" field, which is where the SOAP message resides as a result of a "Post," in the DocumentContext object.

For more details, see "LotusScript and Java in Web agents."

SOAPin= doc.GetItemValue("Request_content")(0)

This piece of code manually parses the SOAP message to extract the following:
ItemVariable stored inDefinition
namespaceNameSpaceScript Library to load.
methodMethodNameFunction to execute in the script library.
argumentargValueParameter to pass to function as the aString variable.
Note Use DomParser methods to parse the SOAP content more efficiently.

On Error Resume Next
bodyPos= Instr(1,SOAPin,|<SOAP-ENV:Body>|)+15
methodPos= Instr(bodyPos,SOAPin,|:|)+1
methodEnd=Instr(methodPos,SOAPin,| |)
MethodName = Mid(SOAPin,methodPos,(methodEnd-methodPos))
nameSpacePos= Instr(methodEnd,SOAPin,|uri:|)+4

nameSpaceEnd=Instr(nameSpacePos,SOAPin,|"|)
NameSpace=Mid(SOAPin,nameSpacePos,(nameSpaceEnd-nameSpacePos))
argPos=Instr(nameSpaceEnd,SOAPin,|>|)+1
argPos2=Instr(argPos, SoapIn, |>|)+1
argEnd=Instr(argPos2,SOAPin,|</|)
argValue =Mid(SOAPin,argPos2,(argEnd-ArgPos2))

This code maps the namespace, method, and argument from the SOAP request to the script library, function, and parameter (respectively) called by the Web agent.

LSlib = NameSpace
Parameter = argValue
MyFunction = MethodName
Library= |"| & LSlib & |"|
Arg= |("| & Parameter & |")|

This code sets CallString equal to a call to the script library and captures the return value in the response variable.

CallString = |Use | & Library & |
response =  | & MyFunction & Arg

Executes CallString, which executes the specified script library.

Execute CallString

The result is: argValue="1. this is the first quote"

This code builds a SOAP response that incorporates the response and MethodName variables and saves it to the strTmp variable.

strTmp = |<?xml version="1.0" encoding="UTF-8" standalone="no"?>| &_
|<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">| & _
|<SOAP-ENV:Body>| & _
|<m:| & MethodName & "Response"  & | xmlns:m="| & NameSpace & |"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">| & _
|<Answer xsi:type="xsd:string">| & response & |</Answer>| & _
|</m:| & MethodName & |Response>| & _
|</SOAP-ENV:Body>| & _
|</SOAP-ENV:Envelope>|

The first Print statement in the agent must specify that the content-type of the agent is XML. By default, Domino translates Web agent content to HTML.

Print "Content-Type: text/xml"

This statement sends the SOAP response stored in strTmp back to the requester. It does not print it to the console.

Print strTmp

'Print |<?xml version="1.0" encoding="UTF-8" standalone="no"?><SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAPSDK1:GetQuoteResponse xmlns:SOAPSDK1="uri:Domino"><Answer>4. I don&apos;t understand the Question. Try again.</Answer></SOAPSDK1:GetQuoteResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>|

End Sub

Creating the Script library called by the Web agent

Wrap the LotusScript code that is called by the SOAP request in a LotusScript script library.

1. Create a LotusScript script library with the same name as the namespace specified in the SOAP request.


2. Create a new function with the same name as the method specified in the SOAP request.

The following is a standard LotusScript function. It is the "GetQuote" function of the "Domino" script library. This code accesses a quotation from a list of quotations stored in the "Answer" field of a form. Several documents with different quotations are stored in the "Domino App" database. This function retrieves a quotation at random, while preventing the most recent quotation retrieved from being retrieved a second time.

Function GetQuote(aString As String) As String

'Return incoming string & "From LotusScript Lib function"
'GetQuote= aString$ & ". From LotusScript Lib function         " & Time
Dim s As New NotesSession
Dim db As NotesDatabase
Dim docCollection As NotesDocumentCollection
Dim doc As NotesDocument
Dim count As Integer
Dim index As Integer
Dim QuoteIndex As Integer
Set db = s.CurrentDatabase
Set docCollection = db.AllDocuments
count = docCollection.count
Randomize
index = Int((count * Rnd) + 1)
While aString = index
index = Int((count * Rnd) + 1)
Wend
Set doc = docCollection.GetNthDocument(index)
GetQuote = index & ". " & doc.GetItemValue("Answer")(0) '& |  | & Time
End Function

Using this Web agent and script library, a remote requester is able to send in a request formatted as SOAP, run a task on the Domino server, and receive an answer formatted as SOAP. It successfully provides a Web service.

Creating a WSDL file

The WSDL file describes a Web service to potential service consumers, specifying where the Web service resides (its URL), the namespace of the service, the names of methods a user can call from it, and details about what parameters, if any, are required. A WSDL file is required if you are offering the Web service to users who will consume the service using .NET tools from Microsoft.

Optionally, you can create a profile form to store the HTTP name of the hosting server. You can later use this profile form to extract the server name when specifying the URL for the service in the WSDL file.

For example, if you create a profile form called "WebServiceProfile," you can store the Server's HTTP name in an editable field called HttpName with this input translation formula:

_Name := @LowerCase(HttpName);

@If(@Begins(_Name;"http://");_Name;"http://"+_Name)

This ensures that if the user enters "web2.mysite.net" as the HTTP name for the server, the required "http://" is prepended to it.

The computed value in the GetQuoteWSDL page below retrieves this value.

To create a WSDL file:

1. Open the database containing the LotusScript function you want to offer as a Web service.

2. From the Designer menu, select Create - Design - Page.


3. From the Designer menu, select Design - Page Properties.
4. Enter a name for the page, such as "GetQuoteWSDL." Select Other in the Web Access - Content type section of the Page Info tab.
5. Enter "text/xml" in the text box and close the Properties box. This sets the page content to XML.

6. Add the following xml content to the page:


The first computed value contains the following code, which retrieves the HTTP name for the server stored in a profile document (See "Creating a WSDL file" above):

@GetProfileField("WebServicesProfile";"HttpName")

The second computed value contains this code, which replaces spaces encountered in the database name with plus signs (in Domino 6, you can use @WebDbName instead):

@ReplaceSubstring(@Subset(@DbName;-1);" ";"+")

The alternative to including two computed values in the source would be to hard-code the URL ("http://servername.com/Domino+App.nsf/WebService?OpenAgent") for the service into the WSDL file.


See Also