<taglib:tutorial lesson="7"/>

In this lesson, we will look at how we can use custom Tags to access resource managers set for our application.

1 Lesson 7, Accessing resource references

    In this lesson, we will look at how we can use custom Tags to access resource managers set for our application. To exemplify this, we will build Tags that will give us the ability to send outgoing mail messages with the use of a mail manager set up as a resource reference for our application.


    Figure 1: The InitialContext class

    We will start with creating the Tags. After that we will update the Taglib descriptor. With this done, we will update our web-application descriptor to define a resource reference. We will also take a look at how to set up the resource for our application. After all this is done, we will create a JSP that will utilise our new Tags.

    Throughout this lesson, We will continue to use the setup previously defined for this tutorial. You should feel comfortable about the BodyTag interface and the BodyTagSupport class before starting on this lesson. If you want to learn more about resource managers, you should read the J2EE 1.2 specification. As we are going to use JavaMail in this lesson, it could be a good thing to take a look at the JavaMail 1.1.2 specification too.

2 Creating the mail sending Tag

    We will start with creating the Tag that we will use to send messages through the mail resource manager. The SendMail Tag will extend the BodyTagSupport class like shown in the image below.


    Figure 2: The SendMailTag class

    Our BodyTag will use the InitialContext to get hold of a Java Mail Session object. We will then use this Session object to create a new MimeMessage. We will set the content of this MimeMessage to be a MultiPart object, to which we will add the body of the Tag as a MimeBodyPart. As a MultiPart object can hold numerous MimeBodyParts, additional parts can be added before the mail is sent.

    1. In the '/WEB-INF/classes/com/acme/tag/' directory, create a new class called 'SendMailTag.java' with the following content:


      package com.acme.tag;

      import javax.servlet.jsp.*;
      import javax.servlet.jsp.tagext.*;
      import javax.naming.*;
      import javax.mail.*;
      import javax.mail.internet.*;
      import java.util.*;
      Listing 1: The import statements.

      In the code above, we import javax.naming.* to get the naming and directory functionality (JNDI) needed. We also import the mail handling functionality we will need.

    2. Continue with the following:


      public class SendMailTag extends BodyTagSupport
      {
      private String mimeType="text/plain";
      private Session session=null;
      private Message message=null;
      private String to=null;
      private String cc=null;
      private String bcc=null;
      private String from=null;
      private String subject=null;
      private String sessionLocation=null;
      private Multipart multipart = new MimeMultipart();
      private InitialContext context = null;
      Listing 2: Declaration of class and private variables.

      As you can see above, we set the default mime-type to be "text/plain". As most mail messages are of this type, this will save time for users of the Tag.

    3. Continue with the following:


      public SendMailTag()
      {
      super();
      }

      public void setTo(String to)
      {
      this.to=to;
      }
      Listing 3: The constructor

      The Container will use the method above to set the to variable, which we will use later to specify the receiver(s) of our message.

    4. Continue with the following:


      public void setCc(String cc)
      {
      this.cc=cc;
      }
      Listing 4: CC set-method.

      The Container will use the method above to set the cc variable, which we will use later to specify the carbon copy receiver(s) of our message.

    5. Continue with the following:


      public void setBcc(String bcc)
      {
      this.bcc=bcc;
      }
      Listing 5: BCC set-method

      The Container will use the method above to set the bcc variable, which we will use later to specify the blind carbon copy receiver(s) of our message.

    6. Continue with the following:


      public void setFrom(String from)
      {
      this.from=from;
      }
      Listing 6: Setter for From field

      The Container will use the method above to set the from variable, which we will use later to specify the sender of our message.

    7. Continue with the following:


      public void setSubject(String subject)
      {
      this.subject=subject;
      }
      Listing 7: Setter for Subject field

      The Container will use the method above to set the subject variable, which we will use later to specify the subject for our message.

    8. Continue with the following:


      public void setMimeType(String mimeType)
      {
      this.mimeType=mimeType;
      }
      Listing 8: Setter for MimeType field

      The Container will use the method above to set the mimeType variable, which we will use to specify the mime-type for our message.

    9. Continue with the following:


      public void setSession(String sessionLocation)
      {
      this.sessionLocation=sessionLocation;
      }
      Listing 9: Setter for Session field.

      The Container will use the method above to set the sessionLocation variable, which we will use to later with JNDI to find the mail Session.

    10. Continue with the following:


      public Multipart getMultipart()
      {
      return multipart;
      }
      Listing 10: Getter for MultiPart field.

      The method above can be used by any Tag that wants to get hold of the current MultiPart object for adding new MimeBodyParts.

    11. Continue with the following:


      public int doStartTag() throws JspTagException
      {
      try
      {
      context=new InitialContext();
      if(sessionLocation!=null)
      {
      session=(Session)context.lookup("java:comp/env/mail/"+sessionLocation);
      }
      else
      {
      session = Session.getDefaultInstance(new Properties(), null);
      }
      }
      catch(NamingException ne)
      {
      throw new JspTagException(ne.getMessage());
      }
      message =new MimeMessage(session);
      return EVAL_BODY_TAG;
      }
      Listing 11: Overriding the doStartTag method.

      The Container will call the method above at the start of the Tag. If a name of a session is passed in, we use that name to find the resource. If no session name is passed in, we will use the default Session.

    12. Continue with the following:


      public int doAfterBody() throws JspTagException
      {
      try
      {
      MimeBodyPart mbp=new MimeBodyPart();
      mbp.setContent(bodyContent.getString(),mimeType);
      multipart.addBodyPart(mbp,0);
      message.setContent(multipart);
      }
      catch(MessagingException me)
      {
      throw new JspTagException(me.getMessage());
      }
      bodyContent.clearBody();
      return SKIP_BODY;
      }
      Listing 12: Overriding the doAfterBody() method

      The method above will get called by the Container at the end of the body of the Tag. In the method, we create a new MimeBodyPart and set this to hold the content of our Tags body. We then add this to the MultiPart as the first part. As any additional parts added before the end of the body of the SendMailTag should be considered attachments, we need to make sure that the body of the SendMailTag is added as the first part, and thus considered to be the default part of the message.

      After that, we clear any body content and tell the Container not to re-evaluate the Tag.

    13. Continue with the following:


      public int doEndTag() throws JspException
      {
      try
      {
      if(from!=null)
      {
      message.setFrom(new InternetAddress(from));
      }
      if(subject!=null)
      {
      message.setSubject(subject);
      }
      addRecipients(to,Message.RecipientType.TO);
      addRecipients(cc,Message.RecipientType.CC);
      addRecipients(bcc,Message.RecipientType.BCC);
      Transport.send(message);
      }
      catch(AddressException ae)
      {
      throw new JspException(ae.getMessage());
      }
      catch(MessagingException me)
      {
      throw new JspException(me.getMessage());
      }
      return EVAL_PAGE;
      }
      Listing 13: Overriding the DoEndTag method.

      In the method above, we try to set the from address of the message as well as any subject specified. After that we use our own method to add one or more recipients to the message (see below). Finally, we use the Transport object to send our message.

    14. Finish the Tag with the following:


      public void addRecipients(String addresses, Message.RecipientType type) throws AddressException, MessagingException
      {
      if (addresses != null)
      {
      StringTokenizer st = new java.util.StringTokenizer(addresses, ",");
      while (st.hasMoreTokens())
      {
      InternetAddress inetAddress=new InternetAddress(st.nextToken());
      message.addRecipient(type,inetAddress);
      }
      }
      }
      }
      Listing 14: Method to add recipients.

      The method above will be called with a Message RecipentType (such as CC, BCC or TO) together with a String holding one or more email addresses. The method will add the given addresses to the message.

      By now, your SendMailTag.java should look like this. Store the sourcecode in the /WEB-INF/classes/com/acme/tag/ directory as SendMailTag.java

    15. Compile the Body Tag.

3 Creating the attachment Tag

    We will now write a BodyTag that can be used to add attachments to the mail message set up in the Tag above.


    Figure 3: The AttachmentTag class

    The BodyTag will first try to locate a SendTag encapsulating it. It will then ask this Tag for its MultiPart object. After that, it will add its body as an additional MimeBodyPart to the existing ones. The user of the Tag will be able to specify a file name and set the mime type for it.

    1. In the '/WEB-INF/classes/com/acme/tag/' directory, create a new class called 'AttachmentTag.java' with the following content:


      package com.acme.tag;

      import javax.servlet.jsp.*;
      import javax.servlet.jsp.tagext.*;
      import javax.mail.internet.*;
      import javax.mail.MessagingException;
      Listing 15: Import statements

    2. There is really nothing to say about the above, so lets continue a bit:


      public class AttachmentTag extends BodyTagSupport
      {
      private String mimeType="text/plain";
      private String filename;
      private SendMailTag sendMailTag;
      Listing 16: Class declaration

      The attributes defined above will hold the selected mime type and file name for the attachment, as well as a reference (yet unset) to a encapsuling SendMailTag.

    3. Continue with the following:


      public AttachmentTag()
      {
      super();
      }

      public void setFilename(String filename)
      {
      this.filename=filename;
      }
      Listing 17: Constructor

      The method above will be called by the Container to set the file name for the attachment.

    4. Continue with the following method:


      public void setMimeType(String mimeType)
      {
      this.mimeType=mimeType;
      }
      Listing 18: Setter for MimeType

      The method above will be called by the Container to set the mime type of the attachment.

    5. Continue with the following method:


      public int doStartTag() throws JspTagException
      {
      sendMailTag=(SendMailTag)findAncestorWithClass(this,SendMailTag.class);
      if(sendMailTag==null)
      {
      throw new JspTagException("Attachment outside Mail");
      }
      return EVAL_BODY_TAG;
      }
      Listing 19: Overriding the doStartTag method.

      The method above will give us a reference to an encapulating SendMailTag. If no such Tag exists, a JspTagException will be thrown.

    6. Finish the BodyTag with the following:


      public int doAfterBody() throws JspTagException
      {
      try
      {
      MimeBodyPart mbp=new MimeBodyPart();
      mbp.setContent(bodyContent.getString(),mimeType);
      mbp.setFileName(filename);
      sendMailTag.getMultipart().addBodyPart(mbp);
      }
      catch(MessagingException me)
      {
      throw new JspTagException(me.getMessage());
      }
      bodyContent.clearBody();
      return SKIP_BODY;
      }
      }
      Listing 20: Overriding the doAfterBody() method.

      The method above will create a new MimeBodyPart and set the content to be the body of this Tag with the specified mime type. It will then set the file name of the MimeBodyPart to the specified file name and finally add it to the encapsuling SendMailTags MultiPart object.

      After that, we make sure that the body of the Tag is cleared and that the body is not re-evaluated.

      By now, your AttachmentTag.java should look like this. Store the sourcecode in the /WEB-INF/classes/com/acme/tag/ directory as AttachmentTag.java

    7. Compile the Body Tag.

4 Update the Tag Library Descriptor

    We now need to tell our JSP Container about our new Body Tags.

    1. Open your 'taglib.tld' from your '/WEB-INF/' directory with your favourite editor.

    2. Add the following description for your new Tag and its TEI:


      <tag>
      <name>sendMail</name>
      <tagclass>com.acme.tag.SendMailTag</tagclass>
      <bodycontent>jsp</bodycontent>
      <info>Tag for sending mail</info>
      <attribute>
      <name>from</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>to</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>cc</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>bcc</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>subject</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>mimeType</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>session</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      </tag>
      <tag>
      <name>attach</name>
      <tagclass>com.acme.tag.AttachmentTag</tagclass>
      <bodycontent>jsp</bodycontent>
      <info>Adds a attachment to a Mail. Must be used inside a sendMailTag</info>
      <attribute>
      <name>fileName</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>content</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      <attribute>
      <name>mimeType</name>
      <required>false</required>
      <rtexprvalue>true</rtexprvalue>
      </attribute>
      </tag>
      Listing 21: Adding the Tag and TEI entries to the descriptor.

    Your taglib.tld should now look like this. Store the descriptor in the /WEB-INF/ directory as taglib.tld.

5 Adding a resource reference to your Web Application

    In order to use your new Tags, you will need to add a resource reference to your Web Application.

    1. Open the 'web.xml' file found in the '/WEB-INF/' directory of your web-application.

    2. Add the following lines right before the last line of the file:


      <resource-ref>
      <description>Mailing ability</description>
      <res-ref-name>mail/mailSession</res-ref-name>
      <res-type>javax.mail.Session</res-type>
      <res-auth>Container</res-auth>
      </resource-ref>
      Listing 22: Resource reference entry.

      This will tell our container that our web-application will need access to the mail manager, and it will use the name "mailSession" to reference it.

    3. Save your web.xml .

    By now, your web.xml should look something like this.

6 Setting up the mail manager for your application

    In order for your web application to reference the mail manager, we must make sure that it is properly set-up.

    Setting up a Mail Session is not part of the J2EE 1.2 specification, so if you are using any other application server than Orion, this part will not work for you. In that case you should reference your application server documentation for further information.

    1. Find the orion-application.xml file in the '/orion/application-deployment/taglib-tutorial/' directory.

    2. Edit the orion-application.xml file and add the following lines inside of the <orion-application> and </orion-application> tags:


      <mail-session location="mail/MailSession" smtp-host="your.smtp.host">
      <property name="mail.transport.protocol" value="smtp" />
      <property name="mail.smtp.from" value="your@email" />
      <property name="mail.from" value="your@emali" />
      </mail-session>
      Listing 23: MailSession configuration.

      This will enable the mail manager for this application.

    3. Save your orion-application.xml .

    By now, your orion-application.xml should look something like this.

7 Presenting your Tag

    In order to test your Tag, you will need a JSP page that uses it.

    1. Create a file called sendMail.jsp and add the following lines:


      <%@ taglib uri="mytags" prefix="mt" %>
      <HTML>
      <HEAD>
      <TITLE>SendMail</TITLE>
      </HEAD>
      <BODY>
      <mt:sendMail from="foobar@acme.com" to="foobar@acme.com" subject="This is a mail">
      Hello there!
      This is a mail sent using the taglib tutorial SendMail Tag!
      <mt:attach fileName="test.txt" mimeType="text/plain"> This is a small attachment. </mt:attach>
      </mt:sendMail>
      <hr>
      Mail Sent!
      <hr>
      </BODY>
      </HTML>
      Listing 24: A sample JSP page.

    The page above will try to send a mail to the recipients mentioned.

    If you've typed in this correctly, your sendMail.jsp should look like this.

8 Using your new Tag

    We are now ready to use our Tag.

    Open the URL http://localhost/taglib/sendMail.jsp in a normal web browser. Hopefully you will see the "Mail Sent!" message.

    Continue with lesson 8, "Accessing user information".

Copyright © 2005 IronFlare AB