The target audience for this guide is the Web component provider, i.e. the person in charge of developing the Web components on the server side. It describes how the Web component provider should build the deployment descriptors of its Web components and how the web components should be packaged.
The content of this guide is the following:
A Web Component is a generic term which denotes both JSP pages and
Servlets. Web components are packaged in a .war
file and can be
deployed in a JOnAS server via the web container service. Web
components can be integrated in a J2EE application by packing the
.war
file in an .ear
file (refer to the J2EE Application Programmer's
Guide).
The JOnAS distribution includes a Web application example: The EarSample example.
The directory structure of this application is the following:
etc/xml | contains the web.xml file describing the web application |
etc/resources/web | contains html pages and images; JSP pages can also be placed here. |
src/org/objectweb/earsample/servlets | servlet sources |
src/org/objectweb/earsample/beans | beans sources |
The bean directory is not needed if beans coming from another application will be used.
Java Server Pages (JSP) is a technology that allows regular, static HTML, to be mixed with dynamically-generated HTML written in Java programming language for encapsulating the logic that generates the content for the page. Refer to the Java Server PagesTM and the Quickstart guide for more details.
The following example shows a sample JSP page that lists the content of a cart.
<!-- Get the session --> <%@ page session="true" %> <!-- The import to use --> <%@ page import="java.util.Enumeration" %> <%@ page import="java.util.Vector" %> <html> <body bgcolor="white"> <h1>Content of your cart</h1><br> <table> <!-- The header of the table --> <tr bgcolor="black"> <td><font color="lightgreen">Product Reference</font></td> <td><font color="lightgreen">Product Name</font></td> <td><font color="lightgreen">Product Price</font></td> </tr> <!-- Each iteration of the loop display a line of the table --> <% Cart cart = (Cart) session.getAttribute("cart"); Vector products = cart.getProducts(); Enumeration enum = products.elements(); // loop through the enumeration while (enum.hasMoreElements()) { Product prod = (Product) enum.nextElement(); %> <tr> <td><%=prod.getReference()%></td> <td><%=prod.getName()%></td> <td><%=prod.getPrice()%></td> </tr> <% } // end loop %> </table> </body> </html>
It is a good idea to hide all the mechanisms for accessing EJBs from JSP
pages by using a proxy java bean, referenced in the JSP page by the
usebean
special tag. This technique is shown in the alarm example, where the .jsp files
communicate with the EJB via a proxy java bean ViewProxy.java.
Servlets are modules of Java code that run in an application server for answering client requests. Servlets are not tied to a specific client-server protocol. However, they are most commonly used with HTTP, and the word "Servlet" is often used as referring to an "HTTP Servlet."
Servlets make use of the Java standard extension classes in the packages
javax.servlet
(the basic Servlet framework) and
javax.servlet.http
(extensions of the Servlet framework for
Servlets that answer HTTP requests).
Typical uses for HTTP Servlets include:
For more details refer to the JavaTM Servlet Technology and the Servlets tutorial.
The following example is a sample of a Servlet that lists the content of a
cart.
This example is the servlet version of the previous JSP page example.
import java.util.Enumeration; import java.util.Vector; import java.io.PrintWriter; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class GetCartServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html><head><title>Your cart</title></head>"); out.println("<body>"); out.println("<h1>Content of your cart</h1><br>"); out.println("<table>"); // The header of the table out.println("<tr>"); out.println("<td><font color="lightgreen">Product Reference</font></td>"); out.println("<td><font color="lightgreen">Product Name</font></td>"); out.println("<td><font color="lightgreen">Product Price</font></td>"); out.println("</tr>"); // Each iteration of the loop display a line of the table HttpSession session = req.getSession(true); Cart cart = (Cart) session.getAttribute("cart"); Vector products = cart.getProducts(); Enumeration enum = products.elements(); while (enum.hasMoreElements()) { Product prod = (Product) enum.nextElement(); int prodId = prod.getReference(); String prodName = prod.getName(); float prodPrice = prod.getPrice(); out.println("<tr>"); out.println("<td>" + prodId + </td>); out.println("<td>" + prodName + </td>); out.println("<td>" + prodPrice + </td>); out.println("</tr>"); } out.println("</table>"); out.println("</body>"); out.println("</html>"); out.close(); } }
The following sections describe:
import javax.naming.Context; import javax.naming.InitialContext; //remote interface import org.objectweb.earsample.beans.secusb.Op; import org.objectweb.earsample.beans.secusb.OpHome; Context initialContext = null; try { initialContext = new InitialContext(); } catch (Exception e) { out.print("<li>Cannot get initial context for JNDI: "); out.println(e + "</li>"); return; } // Connecting to OpHome thru JNDI OpHome opHome = null; try { opHome = (OpHome) PortableRemoteObject.narrow(initialContext.lookup ("java:comp/env/ejb/Op"),OpHome.class); } catch (Exception e) { out.println("<li>Cannot lookup java:comp/env/ejb/Op: " + e + "</li>"); return; } // OpBean creation Op op = null; try { op = opHome.create("User1"); } catch (Exception e) { out.println("<li>Cannot create OpBean: " + e + "</li>"); return; }Note that the following elements must be set in the
web.xml
file
tied to this web application:
<ejb-ref> <ejb-ref-name>ejb/Op</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>org.objectweb.earsample.beans.secusb.OpHome</home> <remote>org.objectweb.earsample.beans.secusb.Op</remote> <ejb-link>secusb.jar#Op</ejb-link> </ejb-ref>
//local interfaces import org.objectweb.earsample.beans.secusb.OpLocal; import org.objectweb.earsample.beans.secusb.OpLocalHome; // Connecting to OpLocalHome thru JNDI OpLocalHome opLocalHome = null; try { opLocalHome = (OpLocalHome) initialContext.lookup("java:comp/env/ejb/OpLocal"); } catch (Exception e) { out.println("<li>Cannot lookup java:comp/env/ejb/OpLocal: " + e + "</li>"); return; }This is found in the
web.xml
file:
<ejb-local-ref> <ejb-ref-name>ejb/OpLocal</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home>org.objectweb.earsample.beans.secusb.OpLocalHome</local-home> <local>org.objectweb.earsample.beans.secusb.OpLocal</local> <ejb-link>secusb.jar#Op</ejb-link> </ejb-local-ref>
String envEntry = null; try { envEntry = (String) initialContext.lookup("java:comp/env/envEntryString"); } catch (Exception e) { out.println("<li>Cannot get env-entry on JNDI " + e + "</li>"); return; }This is the corresponding part of the
web.xml
file:
<env-entry> <env-entry-name>envEntryString</env-entry-name> <env-entry-value>This is a string from the env-entry</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry>
import javax.transaction.UserTransaction; // We want to start transactions from client: get UserTransaction UserTransaction utx = null; try { utx = (UserTransaction) initialContext.lookup("java:comp/UserTransaction"); } catch (Exception e) { out.println("<li>Cannot lookup java:comp/UserTransaction: " + e + "</li>"); return; } try { utx.begin(); opLocal.buy(10); opLocal.buy(20); utx.commit(); } catch (Exception e) { out.println("<li>exception during 1st Tx: " + e + "</li>"); return; }
The Web component programmer is responsible for providing the deployment
descriptor associated with the developed web components. The Web component
provider's responsibilities and the application assembler's responsibilities
are to provide an XML deployment descriptor that conforms to the deployment
descriptor's XML DTD as defined in the Java TM Servlet
Specification Version 2.3. (Refer to
$JONAS_ROOT/xml/web-app_2_3.dtd
).
To customize the Web components, information not defined in the standard
XML deployment descriptor may be needed. For example, the information may
include the mapping of the name of referenced resources to its JNDI name.
This information can be specified during the deployment phase, within another
XML deployment descriptor that is specific to JOnAS. The JOnAS-specific
deployment descriptor's XML DTD is located in
$JONAS_ROOT/xml/jonas-web-app_X_Y.dtd
. The file name of the
JOnAS-specific XML deployment descriptor must be the file name of the
standard XML deployment descriptor prefixed by 'jonas-'.
JOnAS interprets the <!DOCTYPE> tag at the parsing of the deployment
descriptor XML files.
The parser first tries to get the specified DTD via the classpath, then it
uses the specified URL (or path).
In the two following examples, the parser gets the
jonas-web-app_3_1.dtd
DTD file via the URL or in the
/usr/local/jonas/xml/ directory.
<!DOCTYPE jonas-web-app PUBLIC "-//ObjectWeb//DTD JOnAS Web App 3.1//EN" "http://www.objectweb.org/jonas/dtds/jonas-web-app_3_1.dtd"> <!DOCTYPE jonas-web-app SYSTEM "/usr/local/jonas/xml/jonas-web-app_3_1.dtd">
The standard deployment descriptor (web.xml) should contain structural information that includes the following:
The JOnAS-specific deployment descriptor (jonas-web.xml) may contain information that includes:
<host> element: If the configuration file of the web container contains virtual hosts, the host on which the WAR file is deployed can be set.
<context-root> element: The name of the context on which the application will be deployed should be specified. If it is not specified, the context-root used can be one of the following:
<java2-delegation-model> element: Set the compliance to the java 2 delegation model.
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>Op</servlet-name> <servlet-class>org.objectweb.earsample.servlets.ServletOp</servlet-class> </servlet> <servlet-mapping> <servlet-name>Op</servlet-name> <url-pattern>/secured/Op</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>Protected Area</web-resource-name> <!-- Define the context-relative URL(s) to be protected --> <url-pattern>/secured/*</url-pattern> <!-- If you list http methods, only those methods are protected --> <http-method>DELETE</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint> <!-- Anyone with one of the listed roles may access this area --> <role-name>tomcat</role-name> <role-name>role1</role-name> </auth-constraint> </security-constraint> <!-- Default login configuration uses BASIC authentication --> <login-config> <auth-method>BASIC</auth-method> <realm-name>Example Basic Authentication Area</realm-name> </login-config> <env-entry> <env-entry-name>envEntryString</env-entry-name> <env-entry-value>This is a string from the env-entry</env-entry-value> <env-entry-type>java.lang.String</env-entry-type> </env-entry> <!-- reference on a remote bean without ejb-link--> <ejb-ref> <ejb-ref-name>ejb/Op</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>org.objectweb.earsample.beans.secusb.OpHome</home> <remote>org.objectweb.earsample.beans.secusb.Op</remote> </ejb-ref> <!-- reference on a remote bean using ejb-link--> <ejb-ref> <ejb-ref-name>ejb/EjbLinkOp</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>org.objectweb.earsample.beans.secusb.OpHome</home> <remote>org.objectweb.earsample.beans.secusb.Op</remote> <ejb-link>secusb.jar#Op</ejb-link> </ejb-ref> <!-- reference on a local bean --> <ejb-local-ref> <ejb-ref-name>ejb/OpLocal</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <local-home>org.objectweb.earsample.beans.secusb.OpLocalHome</local-home> <local>org.objectweb.earsample.beans.secusb.OpLocal</local> <ejb-link>secusb.jar#Op</ejb-link> </ejb-local-ref> </web-app>
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE jonas-web-app PUBLIC "-//ObjectWeb//DTD JOnAS Web App 3.1//EN" "http://www.objectweb.org/jonas/dtds/jonas-web-app_3_1.dtd"> <jonas-web-app> <!-- Mapping between the referenced bean and its JNDI name, override the ejb-link if there is one in the associated ejb-ref in the standard Web Deployment Descriptor --> <jonas-ejb-ref> <ejb-ref-name>ejb/Op</ejb-ref-name> <jndi-name>OpHome</jndi-name> </jonas-ejb-ref> <!-- the virtual host on which deploy the web application --> <host>localhost</host> <!-- the context root on which deploy the web application --> <context-root>/web-application</context-root> </jonas-web-app>
Although some characters, such as ">", are legal, it is good practice to replace them with XML entity references. The following is a list of the predefined entity references for XML:
< | < | less than |
> | > | greater than |
& | & | ampersand |
' | ' | apostrophe |
" | " | quotation mark |
Web components are packaged for deployment in a standard Java programming language Archive file called a war file (Web ARchive), which is a jar similar to the package used for Java class libraries. A war has a specific hierarchical directory structure. The top-level directory of a war is the document root of the application.
The document root is where JSP pages, client-side classes and archives, and static web resources are stored. The document root contains a subdirectory called WEB-INF, which contains the following files and directories:
Before building a war file, the java source files must be compiled to obtain the class files (located in the WEB-INF/classes directory) and the two XML deployment descriptors must be written.
Then, the war file (<web-application>.war) is built using the jar command:
cd <your_webapp_directory> jar cvf <web-application>.war *
During the development process, an 'unpacked version' of the war file can be used. Refer to Configuring Web Container Service for information about how to use directories for the web application.