|
Primer : Forms Using Servlets |
|
|
On the web, forms allow the user to enter information. When the "SUBMIT" button is pressed,
that information can get sent to either another (scriplet) page or to a servlet. In either
case, some code must be executed in order to collect that form information.
|
||
|
This lesson describes how to collect form information using a servlets. A servlet is
binary code, whether it be Java or Smalltalk, that processes HTTP requests.
|
||
|
1.
If the Web Toolkit is not already running and your sandbox site not configured, please do
so now.
2. Our web architect has outlined the following pages for us:
Figure 2. The servlet collects data from a form and stores it in a custom object. We are going to create a custom class called Answer, of which an instance will contain the data from our form. There's nothing special about our class, just 3 instance variables and your typical getter and setter methods. However, to pull data from the form, we will create a class that is subclassed from the SingleThreadModelServlet class. This class, Wss, will inherit functionality from its parent class that enables it to extract data from a submitted form. Since the method used on the form tag is "post", we must create a method called doPost in order to extract the named-pairs from the form. Like the ASP model, we use methods from the Request class to do this. 4. In your favorite text editor, enter the following and save this file as formJ2EE.htm in the sandbox directory (just copy from here and paste it into your editor).
<html>
This is straight-forward HTML.
<head> <title>My J2EE Model Form</title> </head> <body bgcolor="white"> <center> <h1>Welcome to My J2EE Model Form</h1> This page allows a user to enter a name and click one of 2 buttons. The form is then "sent" to a Smalltalk servlet (Wss - World's Smallest Servlet) which will determine the user's input. <form name="formJ2" method="post" action="servlet/Wss"> <p>Username: <input type="text" name="username"></p> <p> <input type="submit" name="Submit" value="Button One"></p> <p> <input type="submit" name="Submit" value="Button Two"></p> </form> </center> </body> </html> What makes the form "work" is the action attribute on the form tag. The value of servlet/Wss means that when the form is submitted, the Wss class (Smalltalk code found in the runtime image) will be used to process the form.
<form name="formJ2" method="post" action="servlet/Wss">
The method attribute of "post" is preferred over "get" (and older method that was deprecated in HTML 4.0) which sends data to the server as an actual data stream. The action attribute is used to specify the name of the Smalltalk class that will receive the data stream when the form is submitted. The term servlet suggests that the Wss class contains some type of code/logic processing to extract (and potentially do something with) the data that was sent from the form. 5. In your favorite text editor, enter the following and save this file as formJ2EE.ssp in the sandbox directory (just copy from here and paste it into your editor).
<jsp:usebean id="Jmodel" class="Wss" scope="session"/>
<html> <head> <title>Servlet Page to Handle a Form</title> </head> <body bgcolor="white"> <center> <h1>Servlet Page to Handle a Form</h1> <p> </p> <p>You Identified Yourself on the previous (form) page as</p> <font color=blue><b> <jsp:getproperty name="Jmodel" property="loginName"/> </b></font> <p>You clicked the </p> <font color=blue><b> <jsp:getproperty name="Jmodel" property="button"/> </b></font> <p>button</p> <p> </p> <jsp:getproperty name="Jmodel" property="message"/> </center> </body> </html> To someone who has never programmed Java Server Pages before, this code will no doubt look a little strange. So let's explain some of the lines of code that need a bit more clarification.
<jsp:usebean id="Jmodel" class="Wss" scope="session"/>
The shortest explaination of this line would be that it is equivalent to the following line of Smalltalk code: session at: 'Jmodel' put: Wss new. What this does is give use "persistence" using a session variable. The variable Jmodel refers to a session variable which in turn is an instance variable of the Wss class. Since we want to access all input fields on our form, we will initialize Wss's instance variable model to an instance of another class (Answer) that contains instance variables for all input fields. This may sound confusing but it will become clear very soon.
<jsp:getproperty name="Jmodel" property="loginName"/>
The shortest explaination of this line would be that it is equivalent to the following line of Smalltalk code: Jmodel loginName. Now that we have identified the "persistence" session variable of Jmodel (from the jsp:usebean tag at the beginning), we can fetch properties from it using the jsp:getproperty tag. The property loginName will map to the username input field on our form. You will see that when we actually starting writing code for the Wss class. We will use the same methodology for extracting the value of the submit button. This takes care of the input fields on the form, so what does the following line do:
<jsp:getproperty name="Jmodel" property="message"/>
The message property will contain feedback to the user. If the user specifies a certain word for their user name, the servlet will respond with one type of message whereas it will respond with another type of message if they specify anything else. The bottom line is this: when the user clicks either button 1 or button 2, the form will be processed by a Smalltalk servlet, code within the VisualWorks image. All of the feedback information will be stored in an instance variable of the Wss class called model and the formJ2EE.ssp page will extract that data from this variable using the jsp:usebean and jsp:getproperty tags. The diagram below shows how everything hooks together.
Figure 3. How the tags and classes are intertwined. So let's get coding !! 6. From the main VisualWorks Launcher window, click the fourth button on the Toolbar or select the menu option Browse >> System. 7. Click on any category and enter the following in the bottom pane:
Smalltalk defineClass: #Wss
superclass: #{VisualWave.SingleThreadModelServlet}
indexedType: #none
private: false
instanceVariableNames: 'model '
classInstanceVariableNames: ''
imports: ''
category: 'WebToolkit'
8. <Operate-Click> and select Accept. 9. Now enter the following in the bottom pane:
Smalltalk defineClass: #Answer
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'loginName button message '
classInstanceVariableNames: ''
imports: ''
category: 'WebToolkit'
10. <Operate-Click> and select Accept. 11. With the Answer class still selected, select the class radio button. 12. <Operate-Click> in the protocol pane and select Add... 13. In the next dialog box, enter instance creation and click OK. 14. Enter the following method under the instance creation protocol.
new
^super new initialize. 15. With the Answer class still selected, click the instance radio button. 16. <Operate-Click> in the protocol pane and select Add... 17. In the next dialog box, enter initialize and click OK. 18. Enter the following method under the initialize protocol.
initialize
loginName := 'default name'. button := 'default button'. 19. <Operate-Click> in the protocol pane and select Add... 20. In the next dialog box, enter accessing and click OK. 21. Enter the following 6 methods under the accessing protocol.
button
^button
button: aString
button := aString
message
^message
message: aString
message := aString
loginName
^loginName
loginName: aString
loginName := aString. aString = 'Smalltalk' ifTrue: [message := '<h2><font color=red>You win a prize!</font></h2>'] ifFalse: [message := '<h3><a href=formJ2EE.htm>Sorry, try again</a></h3>']. 22. Select the Wss class and click the instance radio button. 23. <Operate-Click> in the protocol pane and select Add... 24. In the next dialog box, enter executing and click OK. 25. Enter the following doPost method under the executing protocol.
doPost
model := session at: 'Jmodel' ifAbsentPut: [Answer new]. model loginName: (request anyParameterValueAt: 'username'). model button: (request parameters at: 'Submit') first. self redirectTo: ('../', 'formJ2EE.ssp'). |
||
|
There is a lot going on in this doPost method so we will break this down line by line.
model := session at: 'Jmodel' ifAbsentPut: [Answer new].
The instance variable of model will contain an instance of the Answer class. The session name for our Answer instance is Jmodel. If the object does not exist, we will create a new instance.
model loginName: (request anyParameterValueAt: 'username').
Now that model contains an instance of the Answer class, we can use methods of the Answer class. One such method is the setter method loginName: which will contain the value of whatever the user entered on our form for the element named username.
model button: (request parameters at: 'Submit') first.
This is similar to line above it except that it's a little different for an obvious reason. Our form contains two buttons and they both have the same name of Submit. The code snippet (request parameters at: 'Submit') will return an ordered collection. Whichever button the user clicked will be the first entry in the collection, therefore, using the first method will return the value of submit button. This then is assigned to the button instance variable.
self redirectTo: ('../', 'formJ2EE.ssp').
Because the Wss class is a subclass to the SingleThreadModelServlet class, the redirectTo: method is inherited, therefore we can use self to refer to our instance of this request. And because our servlet has no knowledge of what directory structure is being used (or from what Web Toolkit site this form was submitted from), it assumes the default web root directory which is why we need the '../' to preceed the name of the SSP page we wish to go to. |
||
|
26.
In your browser, navigate to http://localhost:8008/sandbox/formJ2EE.htm
Figure 4. The simple form with Carlson as the username and button2 about to be clicked 27. Fill out the form and click either Button 1 or Button 2. You should see something like the screen shot below (obviously your answers will be much different):
Figure 5. Data collected from formJ2EE.htm As you can see, the servlet successfully extracted the data from the form, stored it in an instance variable where the scriplet page (formJ2EE.ssp) was able to extract this data from the instance variable. Since the username did not match the "secret word", the servlet responded with a "try again" message.
Figure 6. Data collected from formJ2EE.htm In this case, the username did match the "secret word" and the servlet responded accordingly. |
||
|
SummaryWhen an HTML form sends data to a servlet, the values can be extracted by the Request object methods using the anyParameterValueAt: and parameters at: methods. However, these methods must reside in a method called doPost that belong to an instance of a SingleThreadModelServlet class. |