ELResolver, and Configuring, Packaging, and Deploying JAX-WS Handlers|
In This Issue
Welcome to the Enterprise Java Technologies Tech Tips for August 26, 2006. Here you'll get tips on using enterprise Java technologies and APIs, such as those in Java Platform, Enterprise Edition (Java EE).
These tips were developed using the Java EE 5 SDK. You can download the SDK from the Java EE Downloads page.
You can download the sample archive for the tip Extending the Java EE Unified Expression Language with a Custom You can download the sample archive for the tip Configuring, Packaging, and Deploying JAX-WS Handlers. Any use of this code and/or information below is subject to the license terms. See the Subscribe/Unsubscribe note at the end of this newsletter to subscribe to Tech Tips that focus on technologies and products in other Java platforms. Extending the Java EE Unified Expression Language with a Custom
ELResolverby Ed Burns The Unified Expression Language (EL), new in Java EE 5, is a powerful and flexible way to tie together the tiers of a web application without sacrificing architectural integrity. Previous Enterprise Java Technologies Tech Tips, such as Using Enterprise Beans with JSP Pages covered an earlier version of the EL, one that was included in JavaServer Pages (JSP) 2.0 technology. Unfortunately, because of differences between the JSP and JavaServer Faces technology programming model, JavaServer Faces technology users could not take advantage of that version of the EL. A different version of the EL is available with JavaServer Faces technology 1.0 and 1.1. The new unified EL aligns the JSP and JavaServer Faces technology ELs. In other words the same unified EL can now be leveraged by both JSP and JavaServer Faces technology users.
This Tech Tip shows you how to extend the capabilities of the unified EL by providing a custom Portions of this tip are extracted from the book JavaServer Faces: The Complete Reference by Ed Burns and Chris Schalk. A Unified EL Example Here is an example of a Unified EL expression:
#{sessionScope.inventory['1353465'].unitPrice}
This expression says, "look in the current HTTP session for an
entry named
Within the Java EE web tier, there is a small set of implicit
objects that have specific meaning when used as the first part
of an expression. In the example of the unified EL expression,
Let's examine a custom
The JavaServer Faces technology 1.0 and 1.1 runtimes include
default singleton instances of two classes:
The following example illustrates the central role that
#{requestScope.user.firstName}
To resolve this expression and get its value, the EL
implementation in JavaServer Faces technology 1.0 and 1.1 breaks
down the expression into two parts:
With
The last step in the evaluation of the expression happens when
Notice how the expression is continually broken down into parts, with the result of evaluating step n being fed into the evaluation of step n + 1.
Extending
Now let's return to the custom
The first thing to know is that a custom
public class JNDIELResolver extends javax.el.ELResolver {
/**
*
Construct a new {@link JNDIELResolver} instance.
*
*/
public JNDIELResolver() {
}
The no-argument constructor is necessary because the system
instantiates the
The core run-time behavior of an
In Java EE 5,
Looking further at the custom
/**
* Resolve variable names known to this resolver;
* otherwise, delegate to the ELResolver chain.
*
* @param name Variable name to be resolved
*/
public Object getValue(ELContext elContext, Object base,
Object property) {
Object result = null;
// If we have a non-null base object,
// function as a PropertyResolver
if (null != base) {
if (base instanceof Context) {
elContext.setPropertyResolved(true);
Context context = (Context) base;
try {
if (property instanceof Name) {
result = context.lookup((Name) property);
} else {
if (null != property) {
result = context.lookup(
property.toString());
}
}
} catch (NameNotFoundException e) {
// Mimic standard JSF/JSP behavior
// when base is a Map by returning null
return null;
} catch (NamingException e) {
throw new ELException(e);
}
}
}
else {
// function as a VariableResolver
if (null == property) {
throw new PropertyNotFoundException(
"JNDIELResolver: name must " +
"not be null");
}
if (JNDI_VARIABLE_NAME.equals(property)) {
elContext.setPropertyResolved(true);
try {
InitialContext ic = new InitialContext();
result = (Context) ic.lookup(
"java:comp/env");
} catch (NamingException e) {
throw new ELException(e);
}
}
}
return result;
}
Pay special attention to the
Next is the
public Class<?> getType(ELContext elContext, Object base,
Object property) {
if (null != base && base instanceof Context) {
elContext.setPropertyResolved(true);
return Object.class;
}
return null;
The
The next method is
public void setValue(ELContext elContext, Object base,
Object property,
Object value) {
if (null != base && base instanceof Context) {
Context context = (Context) base;
elContext.setPropertyResolved(true);
try {
// Mimic standard JSF/JSP behavior when base is a Map
// by calling rebind() instead of bind()
if (property instanceof Name) {
context.rebind((Name) property, value);
} else {
context.rebind(property.toString(), value);
}
} catch (NamingException e) {
throw new ELException(e);
}
}
}
The
The remaining three methods:
Declaring Your
To make your <el-resolver> com.sun.faces.extensions.jndi.JNDIELResolver </el-resolver> Running the Sample Code The runtime environment for this example is the Java EE 5 SDK, which you can download from the Java EE Downloads page. The example code is packaged as a NetBeans 5.5 Beta 2 Web Application project. You can open the project and run it in NetBeans 5.5 Beta 2. You can also run the example from the command line, as follows:
Here is the JSP source for the table:
<h:panelGrid border="1" columns="2">
JNDI Entry One <h:outputText value="#{jndi.TestEntryOne}" />
JNDI Entry Two <h:outputText value="#{jndi.TestEntryTwo}" />
JNDI Entry Three
<h:outputText value="#{jndi.TestEntryThree}" />
</h:panelGrid>
The following JNDI entries are declared in the
<env-entry>
<description>Look this up from JNDI</description>
<env-entry-name>TestEntryOne</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Test Entry One</env-entry-value>
</env-entry>
<env-entry>
<description>Look this up via JNDI</description>
<env-entry-name>TestEntryTwo</env-entry-name>
<env-entry-type>java.lang.Float</env-entry-type>
<env-entry-value>3.1415</env-entry-value>
</env-entry>
<env-entry>
<description>Look this up via JNDI.</description>
<env-entry-name>TestEntryThree</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>The Third and Final Environment Entry
</env-entry-value>
</env-entry>
Summary This Tech Tip showed how to extend the unified EL with a simple class consisting of six methods, only three of which are really necessary for run-time behavior. For more information on extending the unified EL see the book JavaServer Faces: The Complete Reference by Ed Burns and Chris Schalk. About the Author Ed Burns is a senior staff engineer at Sun Microsystems. He has worked on a wide variety of client and server-side web technologies since 1994, including NCSA Mosaic, Mozilla, the Sun Java Plugin, Jakarta Tomcat and, most recently JavaServer Faces technology. Ed is currently the co-spec lead for JavaServer Faces 1.2 technology. Configuring, Packaging, and Deploying JAX-WS Handlers
by Rama Pulavarthi The June 24, 2006 Tech Tip, Writing a Handler in JAX-WS introduced JAX-WS handlers and how they can be used to pre-process or post-process messages exchanged between a server and client. This Tech Tip covers how to configure, package, and deploy handlers for a web service. This tip will be followed next month by a tip that shows different ways to configure handlers on a web service client. JAX-WS provides a plug-in framework for handlers. It also defines the life cycle of handlers and the way handlers interact with the client and server. JAX-WS does not define a standard deployment model for handlers. Instead, the deployment metadata used to configure handlers on the server is defined by JSR-109: Implementing Enterprise Web Services. Handler Chains Handlers are configured according to an ordered list of handlers known as a handler chain. The syntax of a handler chain is defined by JSR-109. Within the handler chain, handlers that are applicable to a port component (that is, a particular port associated with a service) are selected to form a chain. The selected handlers are then executed in an orderly way. Logical handlers are executed before SOAP handlers, maintaining the original order in the chain. The schema for the handler chain is defined in a Java EE web services deployment descriptor (http://java.sun.com/xml/ns/javaee/javaee_web_services_1_2.xsd). Here's an example of a simple handler chain:
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-name>SOAPLogicalLoggingHandler</handler-name>
<handler-class>handlers.common.SOAPLoggingHandler
</handler-class>
</handler>
<handler>
<handler-name>LogicalLoggingHandler</handler-name>
<handler-class>handlers.common.LogicalLoggingHandler
</handler-class>
</handler>
</handler-chain>
</handler-chains>
A handler chain configuration can be applied to any port or service. For example, you might have multiple services specified in a WSDL file and multiple ports in a service with different protocol bindings. You can apply the handler chain to any or all of the services and ports. However, you can selectively apply a handler configuration to specific ports by placing a constraint on the Let's look at these constraints:
Use this element to apply handlers to specific services. You do this by specifying a Java EE qname-pattern in the element. Handlers identified in the associated
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<service-name-pattern
xmlns:ns1="http://example.com/handlers">
ns1:HelloService
</service-name-pattern>
<handler/>
<handler/>
</handler-chain>
</handler-chains>
As a result of the exact name specification, handlers specified in the
Here's an example of a
<service-name-pattern
xmlns:ns1="http://example.com/handlers">
ns1:HelloService*
<service-name-pattern>
Here, handlers specified in the associated Here's another wild card pattern:
<service-name-pattern>*
Handlers specified in the associated
Use this element to apply handlers to a specific port. For example:
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<port-name-pattern xmlns:ns1="http://example.com/handlers">
ns1:Hello*
</port-name-pattern>
<handler/>
<handler/>
</handler-chain>
</handler-chains>
Here, handlers specified in the associated
Use this element to apply handlers to a specific set of protocol bindings. The handlers specified in the associated
In the following example, the
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<protocol-bindings>##SOAP11_HTTP
http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true
</protocol-bindings>
<handler/>
<handler/>
</handler-chain>
</handler-chains>
Configuring Handlers in a Handler Chain
You can configure handlers in a handler chain either by using the annotation Configuring Handlers Using the HandlerChain Annotation
JSR-181: Web Services Metadata for the Java Platform defines an annotation,
Here's an example that uses the
@javax.jws.HandlerChain(file="Hello1_handler.xml")
@javax.jws.WebService(serviceName="HelloService1",
targetNamespace="http://example.com/handlers")
public class Hello1 {
public String sayHello(String param) {
// implement the web service operation here
return "Hello " + param + "!";
}
}
Configuring Handlers Through JAX-WS Customization
In this approach you specify Here is an example of a customization file that can be used for handler configuration:
<bindings xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation=
"http://example.com/handler_config/Hello1?wsdl">
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
<handler>
<handler-class>
example.handlers.MyHandler</handler-class>
</handler>
</handler-chain>
</handler-chains>
</bindings>
The
Note that if the Specifying Handlers in a Deployment Descriptor
You can also specify handlers in a deployment descriptor using
<webservices xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="1.2" xsi:schemaLocation=
"http://java.sun.com/xml/ns/javaee
http://www.ibm.com/webservices/xsd/javaee_web_services_1_2.xsd">
<webservice-description>
<webservice-description-name>HelloService2
</webservice-description-name>
<wsdl-file>WEB-INF/wsdl/HelloService2.wsdl
</wsdl-file>
<port-component>
<port-component-name>Hello2</port-component-name>
<service-endpoint-interface>service2.HelloIF
</service-endpoint-interface>
<service-impl-bean>
<servlet-link>Hello2</servlet-link>
</service-impl-bean>
<handler-chains>
<handler-chain>
<handler>
<handler-name>SOAPLoggingHandler</handler-name>
<handler-class>handlers.common.SOAPLoggingHandler
</handler-class>
</handler>
</handler-chain>
<handler-chain>
<protocol-bindings>##SOAP12_HTTP
</protocol-bindings>
<handler>
<handler-name>SOAP12Handler</handler-name>
<handler-class>service2.handlers.SOAP12Handler
</handler-class>
</handler>
</handler-chain>
</handler-chains>
</webservice-description>
</webservices>
You might wonder, what if you specify handlers in all three ways: deployment descriptor, Packaging and Deploying Handlers
You need to package, either by containment or reference, the handler class and its dependent classes in one module with the deployment descriptor information that references the handler classes. As discussed earlier, you can specify handlers in a deployment descriptor or through Summary
Defining handlers for Java EE web services is not difficult. It simply involves configuring handlers using a Running the Sample Code You can run the sample code for this tip as follows:
About the Author Rama Pulavarthi is a Member of Technical Staff in the Java Web Services group at Sun Microsystems. He currently works on the development of the JAX-WS Reference Implementation. He previously led the Software Quality Engineering effort for JAX-RPC. | ||||||
|
| ||||||||||||