This chapter presents an example that uses the framework and the mail monitor. Unlike all other examples that need Servlets 2.1+ and JSP 1.0+, the Mail example needs only Servlets 2.0.
This example uses a data bean that is almost identical with the one used by the Simple example. There is only one difference: the subBean property was transformed from a contained bean to a bean array and renamed subBeanArray.
ExampleBean.java:
package com.devsphere.examples.mapping.mail;
/**
* Example bean
*/
public class ExampleBean implements java.io.Serializable {
private String string;
private float number;
private int integer;
private boolean flag;
private String colors[];
private int list[];
private String optional;
private ExampleSubBean subBeanArray[];
/**
* No-arg constructor
*/
public ExampleBean() {
}
/**
* Gets the string property
*/
public String getString() {
return this.string;
}
/**
* Sets the string property
*/
public void setString(String value) {
this.string = value;
}
/**
* Gets the number property
*/
public float getNumber() {
return this.number;
}
/**
* Sets the number property
*/
public void setNumber(float value) {
this.number = value;
}
/**
* Gets the integer property
*/
public int getInteger() {
return this.integer;
}
/**
* Sets the integer property
*/
public void setInteger(int value) {
this.integer = value;
}
/**
* Gets the flag property
*/
public boolean getFlag() {
return this.flag;
}
/**
* Sets the flag property
*/
public void setFlag(boolean value) {
this.flag = value;
}
/**
* Gets the colors property
*/
public String[] getColors() {
return this.colors;
}
/**
* Sets the colors property
*/
public void setColors(String values[]) {
this.colors = values;
}
/**
* Gets an element of the colors property
*/
public String getColors(int index) {
return this.colors[index];
}
/**
* Sets an element of the colors property
*/
public void setColors(int index, String value) {
this.colors[index] = value;
}
/**
* Gets the list property
*/
public int[] getList() {
return this.list;
}
/**
* Sets the list property
*/
public void setList(int values[]) {
this.list = values;
}
/**
* Gets an element of the list property
*/
public int getList(int index) {
return this.list[index];
}
/**
* Sets an element of the list property
*/
public void setList(int index, int value) {
this.list[index] = value;
}
/**
* Gets the optional property
*/
public String getOptional() {
return this.optional;
}
/**
* Sets the optional property
*/
public void setOptional(String value) {
this.optional = value;
}
/**
* Gets the subBeanArray property
*/
public ExampleSubBean[] getSubBeanArray() {
return this.subBeanArray;
}
/**
* Sets the subBeanArray property
*/
public void setSubBeanArray(ExampleSubBean values[]) {
this.subBeanArray = values;
}
/**
* Gets an element of the subBeanArray property
*/
public ExampleSubBean getSubBeanArray(int index) {
return this.subBeanArray[index];
}
/**
* Sets an element of the subBeanArray property
*/
public void setSubBeanArray(int index, ExampleSubBean value) {
this.subBeanArray[index] = value;
}
}
ExampleSubBean.java:
package com.devsphere.examples.mapping.mail;
/**
* Example sub-bean
*/
public class ExampleSubBean implements java.io.Serializable {
private String string;
private float number;
/**
* No-arg constructor
*/
public ExampleSubBean() {
}
/**
* Gets the string property
*/
public String getString() {
return this.string;
}
/**
* Sets the string property
*/
public void setString(String value) {
this.string = value;
}
/**
* Gets the number property
*/
public float getNumber() {
return this.number;
}
/**
* Sets the number property
*/
public void setNumber(float value) {
this.number = value;
}
}
The properties of ExampleBean are mapped to the form elements of ExampleForm.html:
Name |
Property type |
Element type |
|
|
|
string |
String |
text |
number |
float |
text |
integer |
int |
radio[] |
flag |
boolean |
checkbox |
colors |
String[] |
checkbox[] |
list |
int[] |
select |
optional |
String |
text |
subBeanArray.0.string |
String |
text |
subBeanArray.0.number |
float |
text |
subBeanArray.1.string |
String |
text |
subBeanArray.1.number |
float |
text |
subBeanArray.2.string |
String |
text |
subBeanArray.2.number |
float |
text |
The HTML form of the Simple example was modified so that the user can fill the properties of three ExampleSubBean objects instead of one.
ExampleForm.html:
<HTML>
<HEAD><TITLE>Example form</TITLE></HEAD>
<BODY>
<H3>Mail Example</H3>
<FORM METHOD="POST">
<P> String <BR>
<INPUT TYPE="TEXT" NAME="string" SIZE="20">
<P> Number <BR>
<INPUT TYPE="TEXT" NAME="number" SIZE="20">
<P> Integer <BR>
<INPUT TYPE="RADIO" NAME="integer" VALUE="1">Option 1
<INPUT TYPE="RADIO" NAME="integer" VALUE="2">Option 2
<INPUT TYPE="RADIO" NAME="integer" VALUE="3">Option 3
<P> Flag <BR>
<INPUT TYPE="CHECKBOX" NAME="flag">Flag
<P> Colors <BR>
<INPUT TYPE="CHECKBOX" NAME="colors" VALUE="red">Red
<INPUT TYPE="CHECKBOX" NAME="colors" VALUE="green">Green
<INPUT TYPE="CHECKBOX" NAME="colors" VALUE="blue">Blue
<P> List <BR>
<SELECT NAME="list" SIZE="3" MULTIPLE>
<OPTION VALUE="1">Item 1</OPTION>
<OPTION VALUE="2">Item 2</OPTION>
<OPTION VALUE="3">Item 3</OPTION>
</SELECT>
<P> Optional <BR>
<INPUT TYPE="TEXT" NAME="optional" SIZE="20">
<P> String (subBeanArray[0]) <BR>
<INPUT TYPE="TEXT" NAME="subBeanArray.0.string" SIZE="20">
<P> Number (subBeanArray[0]) <BR>
<INPUT TYPE="TEXT" NAME="subBeanArray.0.number" SIZE="20">
<P> String (subBeanArray[1]) <BR>
<INPUT TYPE="TEXT" NAME="subBeanArray.1.string" SIZE="20">
<P> Number (subBeanArray[1]) <BR>
<INPUT TYPE="TEXT" NAME="subBeanArray.1.number" SIZE="20">
<P> String (subBeanArray[2]) <BR>
<INPUT TYPE="TEXT" NAME="subBeanArray.2.string" SIZE="20">
<P> Number (subBeanArray[2]) <BR>
<INPUT TYPE="TEXT" NAME="subBeanArray.2.number" SIZE="20">
<P>
<INPUT TYPE="SUBMIT" VALUE="Submit">
<INPUT TYPE="RESET" VALUE="Reset">
</FORM>
</BODY>
</HTML>
While the Simple example uses a ListResourceBundle, the Mail examples gets the bean resources from a .properties file. In addition to default values, error messages, optional properties and processing order, this file contains the fixed length of the bean array, the HTML separators of the error messages (that replace the default ones) and the configuration parameters used by FormMailer.
This developer's guide contains two examples that use contained bean arrays: Dynamic and Mail. Dynamic uses a bean array whose length is variable and is stored in a hidden element of the HTML form. The bean array used by the Mail example has a fixed length that is stored in the bean resources.
ExampleBeanResources.properties:
# Default values
[DEFAULT_VALUE.string]=abc
[DEFAULT_VALUE.number]=0.123
[DEFAULT_VALUE.flag]=true
[DEFAULT_VALUE.list.length]=2
[DEFAULT_VALUE.list.0]=2
[DEFAULT_VALUE.list.1]=3
# Error messages
[ERROR_MESSAGE.integer]=An option must be selected
[ERROR_MESSAGE.colors]=One or more colors must be selected
[ERROR_MESSAGE.list]=One or more items must be selected
# List of optional properties
[OPTIONAL_PROPERTIES]=optional
# List of properties that participate to the mapping process
[PROCESSING_ORDER]=string number integer flag colors list optional subBeanArray
# The fixed length of the contained bean array
[FIXED_LENGTH.subBeanArray]=3
# File name of the HTML form
[FORM_NAME]=ExampleForm.html
# The HTML wrappers of the error messages
[HTML_MESSAGE_START]=<FONT COLOR\="\#0000FF"><I>
[HTML_MESSAGE_SEPARATOR]=<BR>\r\n
[HTML_MESSAGE_END]=</I></FONT><BR>\r\n
# Parameters of the FormMailer servlet
[FormMailer.RESPONSE_PAGE]=ExampleResponse.html
[FormMailer.ERROR_PAGE]=ExampleError.html
[FormMailer.EMAIL_SUBJECT]=Mail Example
[FormMailer.EMAIL_FROM_PERSON]=Tester
[FormMailer.EMAIL_FROM]=tester@smtphost
[FormMailer.EMAIL_REPLAY_TO]=
[FormMailer.EMAIL_TO]=x@smtphost
[FormMailer.EMAIL_CC]=y@smtphost z@smtphost
[FormMailer.EMAIL_BCC]=
[FormMailer.EMAIL_CHARSET]=
Unlike the Simple example, the Mail example defines default values for the properties of ExampleSubBean.
ExampleSubBeanResources.properties:
# Default values
[DEFAULT_VALUE.string]=def
[DEFAULT_VALUE.number]=0.456
The processor instance is created by com.devsphere.apps.mapping.monitor.MonitorStarter. The constructor opens an AWT window that contains a text area.
All valid beans are processed by the processExampleBean() method of the processor instance. This processing method is called by com.devsphere.apps.mapping.monitor.StoreConnector using the Reflection API and it prints the values of the bean properties to the window's text area.
ExampleProc.java:
package com.devsphere.examples.mapping.mail;
import java.awt.*;
import java.awt.event.*;
/**
* Example processor
*/
public class ExampleProc {
private Frame frame;
private TextArea textArea;
/**
* Creates the processor and opens its window
*/
public ExampleProc() {
// Create the frame
frame = new Frame("Example Processor");
frame.setLayout(new BorderLayout());
// Add the textArea
textArea = new TextArea(20, 80);
textArea.setEditable(false);
frame.add(textArea, BorderLayout.CENTER);
// Register the listener
frame.addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e) { frame.dispose(); } });
// Show the frame
frame.pack();
frame.setLocation(0, 100);
frame.setVisible(true);
}
/**
* Processing method. Outputs the values of the bean properties
*/
public void processExampleBean(ExampleBean exampleBean) {
println("ExampleBean properties:");
println(" string = " + exampleBean.getString());
println(" number = " + exampleBean.getNumber());
println(" integer = " + exampleBean.getInteger());
println(" flag = " + exampleBean.getFlag());
println(" colors = " + toString(exampleBean.getColors()));
println(" list = " + toString(exampleBean.getList()));
println(" optional = " + exampleBean.getOptional());
for (int i = 0; i < exampleBean.getSubBeanArray().length; i++) {
println(" subBeanArray[" + i + "].string = "
+ exampleBean.getSubBeanArray(i).getString());
println(" subBeanArray[" + i + "].number = "
+ exampleBean.getSubBeanArray(i).getNumber());
}
println("");
}
/**
* Appends a string to the text area component
*/
protected void println(String s) {
textArea.append(s);
textArea.append("\r\n");
}
/**
* Concatenates the elements of a list and retuens a string
*/
public static String toString(String list[]) {
if (list == null || list.length == 0)
return "";
if (list.length == 1 && list[0] != null)
return list[0];
StringBuffer strbuf = new StringBuffer();
strbuf.append("{ ");
for (int i = 0; i < list.length; i++)
if (list[i] != null) {
strbuf.append(list[i]);
strbuf.append(" ");
}
strbuf.append("}");
return strbuf.toString();
}
/**
* Concatenates the elements of a list and retuens a string
*/
public static String toString(int list[]) {
if (list == null || list.length == 0)
return "";
if (list.length == 1)
return Integer.toString(list[0]);
StringBuffer strbuf = new StringBuffer();
strbuf.append("{ ");
for (int i = 0; i < list.length; i++) {
strbuf.append(list[i]);
strbuf.append(" ");
}
strbuf.append("}");
return strbuf.toString();
}
}
The FormMailer needs two static pages: a normal response page and an error page.
ExampleResponse.html:
<HTML>
<HEAD><TITLE>Thanks</TITLE></HEAD>
<BODY>
<CENTER>
<H3>Mail Example</H3>
<H3>Thanks for submiting the data.</H3>
</CENTER>
</BODY>
</HTML>
ExampleError.html:
<HTML>
<HEAD><TITLE>Error</TITLE></HEAD>
<BODY>
<CENTER>
<H3>Mail Example</H3>
<H3>Data was received but the servlet was not able to email it.</H3>
<P>The SMTP server might not be available
<BR>or the e-mail parameters defined as bean resources might not be valid.
</CENTER>
</BODY>
</HTML>
Before running the example you must ensure that all used classes are in CLASSPATH and the servlet was declared in the servlets.properties or web.xml file (you may have to modify the HOST parameter):
ExampleMailer.code=com.devsphere.apps.mapping.mailer.FormMailer
ExampleMailer.initparams=\
BEAN_NAME=com.devsphere.examples.mapping.mail.ExampleBean,\
BASE_PATH=/mail,\
HOST=smtphost,\
PROTOCOL=smtp,\
DEBUG_MAIL_SESSION=true,\
BUFFER_SIZE=2048
or
<servlet>
<servlet-name>ExampleMailer</servlet-name>
<servlet-class>com.devsphere.apps.mapping.mailer.FormMailer</servlet-class>
<init-param>
<param-name>BEAN_NAME</param-name>
<param-value>com.devsphere.examples.mapping.mail.ExampleBean</param-value>
</init-param>
<init-param>
<param-name>BASE_PATH</param-name>
<param-value>/mail</param-value>
</init-param>
<init-param>
<param-name>HOST</param-name>
<param-value>smtphost</param-value>
</init-param>
<init-param>
<param-name>PROTOCOL</param-name>
<param-value>smtp</param-value>
</init-param>
<init-param>
<param-name>DEBUG_MAIL_SESSION</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>BUFFER_SIZE</param-name>
<param-value>2048</param-value>
</init-param>
</servlet>
Also you must edit the ExampleBeanResources.properties file of the Mail example and set the email addresses since the original values of the [FormMailer.EMAIL_*] bean resources may not be adequate.
[FormMailer.EMAIL_FROM_PERSON]=Tester
[FormMailer.EMAIL_FROM]=tester@smtphost
[FormMailer.EMAIL_REPLAY_TO]=
[FormMailer.EMAIL_TO]=x@smtphost
[FormMailer.EMAIL_CC]=y@smtphost z@smtphost
[FormMailer.EMAIL_BCC]=
After configuration, you should be able to invoke the servlet with something like this:
http://localhost:8080/dsmf/servlet/ExampleMailer
Run the mail monitor using a command line that matches this pattern:
java com.devsphere.apps.mapping.monitor.MonitorStarter
com.devsphere.examples.mapping.mail.ExampleBean
com.devsphere.examples.mapping.mail.ExampleProc processExampleBean
<protocol> <host> <user> <password> <folder>
10 true log.txt
The <protocol> parameter may be pop3, imap or dir. Two windows should show up ("Mail Monitor" and "Example Processor"). At every 10 seconds, the new messages should be listed in the second window. If the protocol is dir the <host>, <user> and <password> parameters may have any non-empty values and <folder> must be a directory where you drop files containing email messages that were sent by FormMailer. If <protocol> is pop3, <folder> must be INBOX and <host> must be a pop3 server. If <protocol> is imap, <folder> must be a valid folder of the <user> account and <host> must be an imap server. The <user> and <password> parameters are used for authentication, when MailMonitor connects to the pop3/imap server.
Compare this example with the Simple example.
A previous chapter describes the application model used by this example.
|