Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] - نسخه متنی

Larne Pekowsky

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







17.9. Global Resources


To a large extent, Web applications are self-contained. All the configuration information, classes, jars, and other resources needed by an application can be held in a war file or in a directory, unknown to Tomcat as a whole. When developing an application for use only by a single individual or within a single company, it is perfectly satisfactory to draw a sharp distinction between Tomcat and the applications hosted within it. However, when a Web application is meant to be distributed and used by several people, some breaking of these boundaries is necessary.

The canonical example of a resource that breaks this boundary is a database. It is to be expected that a Web application that is meant to be run in many different places will also be run in conjunction with many different databases. One installation may use Microsoft SQL server, another MySQL, and a third Oracle. In addition, each installation will have its own usernames and passwords for database access.

Database connection information may be stored in a configuration file within the Web application, but this is inelegant because it requires the person installing the application to open the .war archive and poke around in the internals of the application. There is also no convention for how this information should be stored; it could be in the web.xml, a property file, a class, or jsp files.

The specification for Web applications provides a better solution that is fully supported by Tomcat. Web applications may refer to resources by name using the JNDI conventions. These resources may then be defined at the Tomcat level in the global server.xml. This provides for a consistent interface, eliminates the need to access the internals of a Web application, and makes it easier to share resources between several Web applications that may be running at the same time.

There are two categories of object that may be defined and used in this way: simple environment values such as strings and integers, and compound objects that are built from factories. There are three steps needed to use both, and these steps are basically the same for both types of resource. Environment variables are somewhat simpler, so they will be considered first.

An application that will use an environment variable must declare its intention to do so in its web.xml, tHRough an env-entry node. For example, to use a string called theMessage, the following declaration would be needed:


<env-entry>
<description>A simple text message</description>
<env-entry-name>theMessage</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

The second step is to define the variable in server.xml. To do this, a Context node must be defined for the application, and the variables can be declared within that node. Assuming that theMessage is to be used within the example Web application that has been used throughout this chapter, the declaration would consist of


<Context path="/example">
<Environment
name="theMessage"
type="java.lang.String"
value="This is the value of theMessage!"/>
</Context>

Alternately, if a variable is to be used by many applications, it may be defined globally and used by each application. First, the definition is made in the global resources section of server.xml:


<GlobalNamingResources>
<Environment
name="theMessage"
type="java.lang.String"
value="This is the value of theMessage!"/>
</GlobalNamingResources>

Then a reference to the global definition can be placed in the Context:


<Context path="/example">
<ResourceLink
name="theMessage"
global="theMessage"
type="java.lang.String"/>
</Context>

With these definitions any JSP page, servlet, or other code within the example application can access this value using the standard JNDI calls. Here is a JSP page that prints the value:


<%@page language="java "
import="javax.naming.*" %>
&l202>
<body>
The value of theMessage is
<%
try {
Context initCtx = new InitialContext();
Context envCtx =
(Context) initCtx.lookup("java:comp/env");
String message =
(String) envCtx.lookup("theMessage");
out.println(message);
} catch (Exception e) {
out.println("Unable to access theMessage!");
e.printStackTrace(System.out);
}
%>
</body>
</html>

The preceding example is enough for most usage within a Web application, noting that the base context as defined by Tomcat is java:comp/env.

Compound values are only slightly more complex than environment variables, and to illustrate this, a bean will be made available though JNDI. Listing 17.3 shows the bean.


Listing 17.3. A simple bean


package com.awl.toolbook.chapter17;
public class SampleBean {
public SampleBean() {}
private String message;
public String getMessage() {return message;}
public void setMessage(String message) {
this.message = message;
}
private int intValue;
public int getIntValue() {return intValue;}
public void setIntValue(int intValue) {
this.intValue = intValue;
}
public String toString() {
return "[SampleBean: " +
message + "," +
intValue + "]";
}
}

The definition in server.xml has two parts; the first defines the name and type of the resource:


<Resource
name="beans/SampleBeanFactory"
auth="Container"
type="com.awl.toolbook.chapter17.SampleBean"/>

The second portion defines parameters for the resource. Bean values must be handled by a factory class, and Tomcat provides a bean factory that should be more than sufficient for most uses. The resource declarations name this class and provide values for the bean properties.


<ResourceParams name="beans/SampleBeanFactory">
<parameter>
<name>factory</name>
<value>org.apache.naming.factory.BeanFactory</value>
</parameter>
<parameter>
<name>message</name>


<value>Hello, this is a message in a bean</value>
</parameter>
<parameter>
<name>intValue</name>
<value>288</value>
</parameter>
</ResourceParams>

The declaration of the resource and its parameters may be placed inside the Context definition to make the bean available only to the example application, or they may be defined in the global section and used in the Context with a ResourceLink.


<ResourceLink
name="beans/SampleBeanFactory"
global="beans/SampleBeanFactory"
type="com.awl.toolbook.chapter17.SampleBean"/>

Regardless of how the resource is declared, it is imported into the application with another entry in web.xml.


<resource-env-ref>
<description>Object factory beans</description>
<resource-env-ref-name>
beans/SampleBeanFactory
</resource-env-ref-name>
<resource-env-ref-type>
com.awl.toolbook.chapter17.SampleBean
</resource-env-ref-type>
</resource-env-ref>

The bean is now available to JSP pages and servlets through the same mechanism used to obtain theMessage, under the name beans/SampleBeanFactory.

JDBC data sources may be defined in exactly the same way. The type in this case would be a javax.sql.DataSource, and the resource parameters would use the BasicDataSourceFactory, from the dbcp package, which was discussed in Chapter 10. These are some other resource parameters:

  • username: the username with which to connect

  • password: the password with which to connect

  • driverClassName: the name of the JDBC driver class

  • url: the URL with which to connect


Chapter 10 for more information on these options.


/ 207