MyEclipse XDoclet Web Development Tutorial

Eric Glass, Independent Consultant
karicg@worldnet.att.net

 

Overview

This tutorial provides a detailed example for using the XDoclet support within MyEclipse to speed web development through the use of attribute-oriented programming. Using XDoclet greatly reduces development time since it automates the generation of deployment descriptors and other support code. This tutorial is based on the concepts that are explained more fully in the IBM developerWorks article Enhance J2EE component reuse with XDoclets by Rick Hightower. If you're new to XDoclet, reading the developerWorks tutorial is highly recommended to provide you the background information needed to fully understand what is described here. Additionally, once you've read how to do it the "hard way" you'll really appreciate the integrated facilities provided by MyEclipse as we develop a sample web application composed of an HTML page, a servlet, a JSP, and a custom taglib.

     
     

Steps to Easy Web Development

This section will take you through the step-by-step process of web project creation, XDoclet configuration, deployment descriptor generation, and Tomcat 5 deployment.

1) Create a New Web Project

  1. Change to or open the MyEclipse Perspective (Window > Open Perspecitve > Other... > MyEclipse) .
  2. Select File > New... > Project > J2EE > Web Module Project, then press the Next button.
  3. For the project name use MyXDocletWeb and for the context root specify /MyXDocletWeb, as shown in Figure 1 below, and press the Finish button.  The resulting project structure will be the same as that shown in Figure 2.

    Creating the Web Project
    Figure 1. Creating the Web Project

    Web Project Layout
    Figure 2. Web Project Layout

2) Create a Servlet

  1. Select the project MyXDocletWeb in the Package Explorer
  2. Select File > New... > Servlet,
  3. Populate it with the package name com.myeclipse.tutorial.servlet and class name BasicServlet as shown in Figure 3, then press the Next button.

    Creating the Servlet
    Figure 3. Creating the Servlet

  4. When the second page of the servlet wizard is displayed, deselect the checkbox labeled Generate/Map web.xml File and select the finish button as shown in Figure 4.  We don't need to have the wizard map the web.xml file since we'll be generating it based on our XDoclet settings later.

    Creating the Servlet - Page 2
    Figure 4. Creating the Servlet - Page 2

  5. After the servlet is generated, it will be opened in the Java editor. Replace the generated source code completely with the following contents and save the file.

/*
 * BasicServlet.java
 * Created on Aug 7, 2003
 */
package com.myeclipse.tutorial.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Basic Servlet Using XDoclet.
 *
 * @author Administrator
 * @version 1.0, Aug 7, 2003
 *
 * @web.servlet name = "BasicServlet"
 *              display-name = "Basic Servlet"
 *              load-on-startup = "1"
 * @web.servlet-init-param name = "hi"
 *                         value = "${basic.servlet.hi}"
 * @web.servlet-init-param name = "bye"
 *                         value = "${basic.servlet.bye}"
 * @web.servlet-mapping url-pattern = "/Basic/*"
 * @web.servlet-mapping url-pattern = "*.Basic"
 * @web.servlet-mapping url-pattern = "/BasicServlet"
 * @web.resource-ref description = "JDBC resource"
 *                   name = "jdbc/mydb"
 *                   type = "javax.sql.DataSource"
 *                   auth = "Container"
 */
public class BasicServlet extends HttpServlet {
    /**
     * Constructor of the object.
     */
    public BasicServlet() {
        super();
    }

    /**
     * Destruction of the servlet.
     */
    public void destroy() {
        super.destroy(); // Just puts "destroy" string in log
    }

    /**
     * The doGet method of the servlet.
     *
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     *
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * The doPost method of the servlet.
     *
     * @param request the request send by the client to the server
     * @param response the response send by the server to the client
     *
     * @throws ServletException if an error occurred
     * @throws IOException if an error occurred
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns information about the servlet.
     *
     * @return String information about this servlet
     */
    public String getServletInfo() {
        return "Basic Servlet Using XDoclet";
    }

    /**
     * Initialization of the servlet.
     *
     * @throws ServletException if an error occurred
     */
    public void init() throws ServletException {
        // Put your code here
    }

    /**
     * Initialization of the servlet with the servlet's configuration.
     *
     * @param config the servlet's configuration
     *
     * @throws ServletException if an error occurred
     */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    /**
     * Processes requests for both HTTP GET and POST methods.
     *
     * @param request servlet request
     * @param response servlet response
     *
     * @throws ServletException if an error occurred
     * @throws java.io.IOException if an I/O error occurred
     */
    protected void processRequest(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        ServletConfig config = this.getServletConfig();
        String hi = config.getInitParameter("hi");
        String bye = config.getInitParameter("bye");

        try {
            response.setContentType("text/html");

            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Basic Servlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>hi:  " + hi + "</h1>");
            out.println("<h1>bye:  " + bye + "</h1>");
            out.println("</body>");
            out.println("</html>");
            out.close();
        } catch (Exception e) {
            throw new ServletException(e);
        }
    }
}

Explanation of XDoclet Tags Used in the Servlet
The example tag illustrates the use of several helpful XDoclet tags. The tags and what they generate are displayed in the table below.
XDoclet Tag Generated Code
@web.servlet name = "BasicServlet"     display-name = "Basic Servlet"     load-on-startup = "1" Generated into the web.xml:

<servlet>
   <servlet-name>BasicServlet</servlet-name>
   <display-name>Basic Servlet</display-name>
   <servlet-class>com.myeclipse.tutorial.servlet.BasicServlet</servlet-class>
   ...
   <load-on-startup>1</load-on-startup>
</servlet>
@web.servlet-init-param name = "hi"
    value = "${basic.servlet.hi}"
@web.servlet-init-param name = "bye"
    value = "${basic.servlet.bye}"
Generated into the web.xml when Ant properties are set to: (basic.servlet.hi = Ant is cool!) and (basic.servlet.bye = XDoclet Rocks!):

<servlet>
   ...
   <init-param>
      <param-name>hi</param-name>
      <param-value>Ant is cool!</param-value>
   </init-param>
   <init-param>
      <param-name>bye</param-name>
      <param-value>XDoclet Rocks!</param-value>
   </init-param>
   ...
</servlet>
@web.servlet-mapping url-pattern = "/Basic/*"
@web.servlet-mapping url-pattern = "*.Basic"
@web.servlet-mapping url-pattern = "/BasicServlet"
Generated into web.xml:

<servlet-mapping>
   <servlet-name>BasicServlet</servlet-name>
   <url-pattern>/Basic/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>BasicServlet</servlet-name>
   <url-pattern>*.Basic</url-pattern>
</servlet-mapping>
<servlet-mapping>
   <servlet-name>BasicServlet</servlet-name>
   <url-pattern>/BasicServlet</url-pattern>
</servlet-mapping>
@web.resource-ref
    description = "JDBC resource"
    name = "jdbc/mydb"
    type = "javax.sql.DataSource"
    auth = "Container"
Generated into web.xml:

<resource-ref>
   <description>JDBC resource</description>
   <res-ref-name>jdbc/mydb</res-ref-name>
   <res-type>javax.sql.DataSource</res-type>
   <res-auth>Container</res-auth>
</resource-ref>

3) Create a Custom Tag Class

  1. Select the project MyXDocletWeb in the Package Explorer
  2. Select File > New... > Class,
  3. Populate it with the package name com.myeclipse.tutorial.customtag, class name BasicTag, and subclass javax.servlet.jsp.tagext.TagSupport as shown in Figure 5, then press the Finish button.

    Creating a Custom Tag
    Figure 5. Creating a Custom Tag

  4. After the tag is generated, it will be opened in the Java editor. Replace the generated source code completely with the following contents and save the file.

/*
 * BasicTag.java
 */
package com.myeclipse.tutorial.customtag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

/**
 * Basic Custom Tag Using XDoclet.
 *
 * @jsp.tag name="BasicTag"
 * @jsp.variable name-given="currentIter"
 *               class="java.lang.Integer"
 *               scope="NESTED"
 *               declare="true"
 * @jsp.variable name-given="atBegin"
 *               class="java.lang.Integer"
 *               scope="AT_BEGIN"
 *               declare="true"
 * @jsp.variable name-given="atEnd"
 *               class="java.lang.Integer"
 *               scope="AT_END"
 *               declare="true"
 *
 */
public class BasicTag extends TagSupport {
    /** Holds value of property includePage. */
    private boolean includePage = false;

    /** Holds value of property includeBody. */
    private boolean includeBody = false;

    /** Holds value of property iterate. */
    private int iterate = 0;

    /**
     * Creates a new BasicTag object.
     */
    public BasicTag() {
        super();
    }

    /**
     * @see javax.servlet.jsp.tagext.TagSupport#doStartTag()
     */
    public int doStartTag() throws JspException {
        pageContext.setAttribute("currentIter", new Integer(iterate));
        pageContext.setAttribute("atBegin", new Integer(0));

        return includeBody ? EVAL_BODY_INCLUDE : SKIP_BODY;
    }

    /**
     * @see javax.servlet.jsp.tagext.TagSupport#doEndTag()
     */
    public int doEndTag() throws JspException {
        pageContext.setAttribute("atEnd", new Integer(iterate));

        return includePage ? EVAL_PAGE : SKIP_PAGE;
    }

    /**
     * @see javax.servlet.jsp.tagext.TagSupport#doAfterBody()
     */
    public int doAfterBody() throws JspException {
        iterate -= 1;
        pageContext.setAttribute("currentIter", new Integer(iterate));

        if (iterate <= 0) {
            return SKIP_BODY;
        } else {
            return EVAL_BODY_AGAIN;
        }
    }

    /**
     * Getter for property includePage.
     *
     * @return Value of property includePage.
     *
     * @jsp.attribute required="true"
     *                rtexprvalue="true"
     *                description="The includePage attribute"
     */
    public boolean isIncludePage() {
        return includePage;
    }

    /**
     * Setter for property includePage.
     *
     * @param includePage New value of property includePage.
     */
    public void setIncludePage(boolean includePage) {
        this.includePage = includePage;
    }

    /**
     * Getter for property includeBody.
     *
     * @return Value of property includeBody.
     *
     * @jsp.attribute required="true"
     *                rtexprvalue="true"
     *                description="The includeBody attribute"
     */
    public boolean isIncludeBody() {
        return includeBody;
    }

    /**
     * Setter for property includeBody.
     *
     * @param includeBody New value of property includeBody.
     */
    public void setIncludeBody(boolean includeBody) {
        this.includeBody = includeBody;
    }

    /**
     * Getter for property iterate.
     *
     * @return Value of property iterate.
     *
     * @jsp.attribute required="true"
     *                rtexprvalue="true"
     *                description="The iterate attribute"
     */
    public int getIterate() {
        return iterate;
    }

    /**
     * Setter for property iterate.
     *
     * @param iterate New value of property iterate.
     */
    public void setIterate(int iterate) {
        this.iterate = iterate;
    }
}

Explanation of XDoclet Tags Used in the Custom Tag
The example tag  illustrates the use of several helpful XDoclet tags. The tags and what they generate are displayed in the table below.
XDoclet Tag Generated Code
@jsp.tag name="BasicTag" Generated into the taglib's .tld file:

<tag>
   <name>BasicTag</name>
   <tag-class>
       com.myeclipse.tutorial.customtag.BasicTag
   </tag-class>
   ...
</tag>
@jsp.variable 
    name-given="currentIter"
    class="java.lang.Integer"
    scope="NESTED"
    declare="true"
@jsp.variable 
    name-given="atBegin"
    class="java.lang.Integer"
    scope="AT_BEGIN"
    declare="true"
@jsp.variable 
    name-given="atEnd"
    class="java.lang.Integer"
    scope="AT_END"
    declare="true"
Generated into the taglib's .tld file:

<tag>
   ...
   <variable>
      <name-given>currentIter</name-given>
      <variable-class>java.lang.Integer</variable-class>
  <declare>true</declare>
      <scope>NESTED</scope>
   </variable>
   <variable>
      <name-given>atBegin</name-given>
      <variable-class>java.lang.Integer</variable-class>
  <declare>true</declare>
      <scope>AT_BEGIN</scope>
   </variable>
   <variable>
      <name-given>atEnd</name-given>
      <variable-class>java.lang.Integer</variable-class>
  <declare>true</declare>
      <scope>AT_END</scope>
   </variable>
   ...
</tag>
@jsp.attribute required="true"
    rtexprvalue="true"
    description="The includePage attribute"
@jsp.attribute required="true"
    rtexprvalue="true"
    description="The includeBody attribute"
@jsp.attribute required="true"
    rtexprvalue="true"
    description="The iterate attribute"
Generated into the taglib's .tld file:

<tag>
   ...
   <attribute>
      <name>includePage</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The includePage attribute]]></description>
   </attribute>
   <attribute>
      <name>includeBody</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The includeBody attribute]]></description>
   </attribute>
   <attribute>
      <name>iterate</name>
      <required>true</required>
      <rtexprvalue>true</rtexprvalue>
      <description><![CDATA[The iterate attribute]]></description>
   </attribute>
</tag>

4) Add a Folder Called 'merge' to the Project

  1. Select the project MyXDocletWeb in the Package Explorer
  2. Select File > New... > Folder,
  3. Populate it with the name merge, as shown in Figure 6, then press the Finish button.

    Creating the Merge Folder
    Figure 6. Creating the Merge Folder

5) Create the taglibs.xml file

  1. Select the folder MyXDocletWeb/merge in the Package Explorer
  2. Select File > New... > XML,
  3. Populate it with the name taglibs.xml, as shown in Figure 7, then press the Finish button.

    Creating the taglibs.xml file
    Figure 7. Creating the taglibs.xml file

Once taglibs.xml has been created and opened in the XML editor, completely replace the contents with the following:

<taglib>
   <taglib-uri>/mytaglib</taglib-uri>
   <taglib-location>/WEB-INF/mytaglib.tld</taglib-location>
</taglib>

6) Create the welcomefiles.xml file

  1. Select the folder MyXDocletWeb/merge in the Package Explorer
  2. Select File > New... > XML,
  3. Populate it with the name welcomefiles.xml then press the Finish button as you did for taglibs.xml.
Once welcomefiles.xml has been created and opened in the XML editor, completely replace the contents with the following:

<welcome-file-list>
   <welcome-file>index.jsp</welcome-file>
   <welcome-file>index.html</welcome-file>
</welcome-file-list>

7) Create the xdoclet-build.properties file

  1. Select the folder MyXDocletWeb in the Package Explorer
  2. Select File > New... > File,
  3. Populate it with the name xdoclet-build.properties, as shown in Figure 8, then press the Finish button.

    Creating the xdoclet-build.properties file
    Figure 8. Creating the xdoclet-build.properties file

    Once xdoclet-build.properties has been created and opened in the Text editor, completely replace the contents with the following:

basic.servlet.hi = MyEclipse Rocks!
basic.servlet.bye = Feel the power of XDoclet!

8) Configure the Project for XDoclet Usage

  1. Right-click on the folder MyXDocletWeb in the Package Explorer
  2. Select Properties > XDoclet Configurations
  3. Right-click and select Add Standard as shown in Figure 9.
  4. Select Standard Web from the resulting dialog box. The resulting configuration is shown in Figure 10.

    Adding a Standard XDoclet Configuration
    Figure 9. Adding a Standard XDoclet Configuration

    Adding Standard Web Configuration
    Figure 10. Adding Standard Web Configuration

  5. Select deploymentdescriptor under the webdoclet entry and select and set the following values as shown in the table below and in Figure 11.
    Property Value
    Servletspec 2.3
    destDir WebRoot/WEB-INF
    displayName XDoclet Web Tutorial
    mergeDir merge

    Deployment Descriptor Settings
    Figure 11. Deployment Descriptor Settings

  6. Select jsptaglib under the webdoclet entry and select and set the following values as shown in the table below and in Figure 12.
    Property Value
    Jspversion 1.2
    destDir WebRoot/WEB-INF
    destinationFile mytaglib.tld
    shortname basic

    JSP Taglib Settings
    Figure 12. JSP Taglib Settings

  7. Select the OK button at the bottom of the Properties dialog to save the XDoclet Configurations. This will generate the file xdoclet-build.xml into the project folder.

9) Setting XDoclet Ant Properties

  1. Right-click on the generated xdoclet-build.xml file in the Package Explorer and select Run Ant....
  2. On the dialg, titled MyXDocletWeb xdoclet-build.xml, select the Properties tab.
  3. Select the Add... button next to the Property files: list
  4. Browse to the project folder select xdoclet-build.properties.
  5. The resultant configuration will look like that in Figure 13.

    Adding Xdoclet Properties File
    Figure 13. Adding the Properties File

  6. Select the Refresh tab on the dialog and ensure that Refresh references after running tool is checked.

    Checking the Refresh Settings
    Figure 14. Checking the Refresh Settings

  7. Select the Apply button to save the changes.
  8. Select the Run button to process the XDoclet JavaDoc statements in the Java source with the Ant webdoclet task.
  9. After XDoclet runs, the files web.xml and mytaglib.tld will have been added to the WEB-INF directory as shown in Figure 15 below.

    Generated Files
    Figure 14. Generated Files

10) Adding a JSP Page

  1. Select the project MyXDocletWeb in the Package Explorer
  2. Right-click and select New... > JSP,
  3. Populate the wizard page with the file name TestJSP.jsp, as shown in Figure 15, then press the Finish button.

    Creating a JSP
    Figure 15. Creating a JSP

  4. After the JSP is generated, it will be opened in the JSP editor. Replace the generated source code completely with the following contents and save the file.

<%@&nbsp;page language="java" %>
<%@&nbsp;taglib uri="/mytaglib" prefix="mytag" %>

<html>
  <head>
    <title>I am a happy JSP page. Yeah!</title>
  </head>
  <body>
    <mytag:BasicTag includePage="true" includeBody="true" iterate="3">
      Current iteration is <%=currentIter%> <br/>
    </mytag:BasicTag>
  </body>
</html>

10) Adding an HTML Page

  1. Select the project MyXDocletWeb in the Package Explorer
  2. Right-click and select New... > HTML,
  3. Populate the wizard page with the file name index.html, as shown in Figure 16, then press the Finish button.

    Creating an HTML Page
    Figure 16. Creating an HTML Page

  4. After the HTML page is generated, it will be opened in the HTML editor. Replace the generated source code completely with the following contents and save the file.

<html>
  <head>
    <title>XDoclet Web Tutorial</title>
  </head>
  <body>
    <br />
    <blockquote>
      <h3>XDoclet Web Tutorial</h3>
      <ul>
        <li><a href="TestJSP.jsp">Test Basic JSP Custom Tag</a></li>
        <li><a href="BasicServlet">Test Basic Servlet</a></li>
      </ul>
    </blockquote>
  </body>
</html>

11) Verify Project

The project is now complete. To verify that the structure is complete, please compare your project to the one shown in Figure 17.

Final Project Structure
Figure 17. Final Project Structure

12) Deploy the Project and Test

  1. Right-click on the MyXDocletWeb project and select MyEclipse > Add and Remove Project Deployments as shown in Figure 18.

    Opening the Deployment Dialog
    Figure 18. Opening the Deployment Dialog

  2. Select the Add button as shown in Figure 19.

    Adding a Deployment
    Figure 19. Adding a Deployment

  3. Select whatever server you've got configured as an exploded archive as shown in Figure 20.

    Picking the Application Server
    Figure 20. Picking a Server

  4. Select the OK button as shown in Figure 21.

    Completing Deployment
    Figure 21. Completing Deployment

  5. Start the server as shown in Figure 22.

    Starting the Application Server
    Figure 22. Starting the Server

  6. Open a browser and test the application. The results are shown in Figure 23.

    Testing the Application 1 Testing the Application 2 Testing the Application 3
    Figure 23. Testing the Application

    Conclusion

    This has been an introduction to XDoclet use for web applications within MyEclipse. Although the example application was a simple one, it was a complete application that included an HTML page, a JSP page, an XDoclet-based Servlet, and and XDoclet-based Tag library. Now that you know how the basics work, get out there and start simplifying your web development with MyEclipse and XDoclet!
 
Genuitec offers a broad range of consulting services including an Eclipse practice for plugin development, training and customization. Genuitec Eclipse services cover all aspects of the Eclipse framwork and include:
Genuitec Solutions and Services
  • Custom Plugin Development for Eclipse-Based Applications
  • Eclipse Development Courses and Workshops
  • Custom Widget Development and SWT/JFaces Extensions
  • Business Desktop Application or Suite Development
  • Productivity Tools Development and Branding
  • J2EE Consulting and Out-sourcing

 
MyEclipse mission is to deliveran affordable and a true end-to-end seamless development environment for Web, J2EE, XML, JSP, Struts, and application server integration.
MyEclipse Features
  • Web Development Tools
    • Smart editors - JSP, HTML, Struts, XML, CSS, and J2EE deployment descriptors
    • XML editing
    • Struts Support
    • XDoclet Support
  • Productivity Wizards
    • Creation of Web, EAR and EJB projects.
    • Java Project to Web Project enablements.
    • EJB Wizards
    • Automated deployment.
  • Application Server Integration
    • 20 application server connectors
    • Integrated controls
    • Full hot swap debugging