1. Introduction
Non-persistent CGI are "stateless".
In other words, the browser connects to the server, makes a request
(calls a CGI),
receives the response, then disconnects from the server.
On the next request from the same browser, there is no guarantee that the
same program has maintaned the state (variables and record positioning)
it was left with at the end of the previous request.
In such a stateless situation, the developer has to implement some
"tricks" to restore some variables on the next call to the CGI,
such as
- using hidden input fields in the HTML forms
- writing and retrieving cookies
Sometimes, however, when designing complex transactions, these rather simple tricks
may not be sufficient to fulfill state requirements
and a programmer would be tempted to use "persistent" CGI instead.
However, persistent
CGI have their own problems.
In those cases, better methods for storing and retrieving
state information are required.
2. User spaces
iSeries user spaces objects are ideal for this purpose:
- Each user space can hold up to 16 MB of information
- System APIs are provided to create a user space, change its attributes
(including making it automatically extendible, retrieve a pointer to it, etc.)
- Once addressability to a user space (a pointer) has been established,
one can map, using based variables, many types of data into it,
including data structures
- Saving and restoring user state information can be accomplished as follow:
- at the start of the transaction, create a uniquely named user space,
- use based variable(s) to map the user's data into the space,
- send an HTTP response to the user, including a hidden field containing the user space name,
- when the user makes a request using the form that contains the hidden user space name, use that
name to retrieve a pointer to the user space, thus restoring addressability to the user space's contents
using the same based variables that were used to store them.
3. User space procedures
- Subprocedure "CrtUsrSpc" - Create an User Space
It creates a randomly named, automatically extendible user space
in a user-specified library. The user space's contents are initialized
to all x'00's.
Parameters
- User space library (input)
- If the library not found, CrtUsrSpc sets the user space name
to blanks and MsgId to CPF9810
- If the requestor does not have change authority to the library,
CrtUsrSpc sets the user space name to blanks and MsgId to CPF2144
- Pointer to user space (output)
- Set to null if the user space is not created
- Message ID (output)
- blank if no errors
- else, message id of error
Optional Parameters
- Public authority (input)
- If not passed, it is set to *EXCLUDE
- Text (input)
- If not passed, it is set to 'Created by CGIDEV2' plus timestamp
- Initial size (input)
- If not passed, it is set to 12288
- Extended attribute
- If not passed, it is set to blanks
Returns
Errors in system APIs
- If any of the called system APIs fails, a message is forced into
the CGIDEBUG file.
Example:
* Input variables
D AnEntry s 40 varying
* User space
D UsrSpcName s 10
D UsrSpcLib c 'CGIDEV2USP'
* Message ID for CrtUsrSpc
D MsgId s 7
* State related variables (user space contents)
D State ds based(StateP)
D Count 10i 0
D Entries 1000 varying
C eval UsrSpcName= CrtUsrSpc(
C UsrSpcLib : StateP : MsgID)
|
In this example, a user space is created in library CGIDEV2USP
and its name is loaded into variable "UsrSpcName".
- Subprocedure "RtvUsrSpcPtr" - Retrieve Pointer to User Space
Parameters
- User space name (input)
- User space library (input)
Returns
- If successful
- Pointer to the user space
- Otherwise
Errors in system APIs
- If any of the called system APIs fails, a message is forced into
the CGIDEBUG file.
Example:
C eval StateP = RtvUsrSpcPtr(UsrSpcName:
C UsrSpcLib)
C if StateP = *null
... ...
C endif
|
In this example, the contents of the user space
are made accessible via data structure "State".
To update the contents of the user space,
one should just update the data structure "State":
C eval AnEntry = ZhbGetVar('AnEntry')
C if AnEntry <> ''
C eval Count = Count + 1
C eval Entries = Entries + '<br>' + AnEntry
C endif
|
4. Sample program
CGI program STATE demonstrates
the use of user space to maintain program state information.
In this programs, the user may enter, one at a time,
several inputs. The inputs are saved in a user space.
The user space contents are displayed to the user.
|