Java EE 6 Cookbook for Securing, Tuning, and Extending Enterprise Applications

By Mick Knutson
  • Instant online access to over 8,000+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Out with the Old, In with the New

About this book

Java Platform, Enterprise Edition is a widely used platform for enterprise server programming in the Java programming language.

This book covers exciting recipes on securing, tuning and extending enterprise applications using a Java EE 6 implementation.

The book starts with the essential changes in Java EE 6. Then we will dive into the implementation of some of the new features of the JPA 2.0 specification, and look at implementing auditing for relational data stores. There are several additional sections that describe some of the subtle issues encountered, tips, and extension points for stating your own JPA application, or extending an existing application.

We will then look into how we can enable security for our software system using Java EE built-in features as well as using the well-known Spring Security framework. We will then look at recipes on testing various JavaEE technologies including JPA, EJB, JSF, and Web services.

Next we will explore various ways to extend a Java EE environment with the use of additional dynamic languages as well as frameworks.

The book then covers recipes that touch on the issues, considerations and options related to extending enterprise development efforts into mobile application development.

At the end of the book, we will cover managing enterprise application deployment and configuration, and recipes that will help you debug problems and enhance the performance of your applications.

Publication date:
June 2012
Publisher
Packt
Pages
356
ISBN
9781849683166

 

Chapter 1. Out with the Old, In with the New

In this chapter, we will cover:

  • Pruning old APIs

  • In with the new

  • Implementing Java Context and Dependency Injection (CDI)

  • Understanding the EJB 3.1 specification

  • Understanding the JPA 2.0 specification

  • Understanding the JAX-RS 1.1 specification

  • Understanding the Servlet 3.0 specification

  • Understanding the WebBeans 1.0 specification

  • Understanding the JSF 2.0 specification

  • Understanding Bean Validation

  • Understanding profiles

Introduction

The goal of this book is to describe recipes for securing, tuning, and extending enterprise applications using a Java EE 6 implementation. First, I want to cover some essential changes in Java EE 6, then later employ some of these changes in recipes that are sure to help you make a more secured and robust application.

This chapter is not a tutorial or primer on the various specifications, but rather aimed at giving a high level summary of the key changes in the Java EE 6 release. The focus will be directed on how these new features will simplify your development, as well as how to improve your application performance. However, if you wish to dive straight in, then feel free to skip this chapter with the ability to return to it for reference.

 

Introduction


The goal of this book is to describe recipes for securing, tuning, and extending enterprise applications using a Java EE 6 implementation. First, I want to cover some essential changes in Java EE 6, then later employ some of these changes in recipes that are sure to help you make a more secured and robust application.

This chapter is not a tutorial or primer on the various specifications, but rather aimed at giving a high level summary of the key changes in the Java EE 6 release. The focus will be directed on how these new features will simplify your development, as well as how to improve your application performance. However, if you wish to dive straight in, then feel free to skip this chapter with the ability to return to it for reference.

 

Pruning old APIs


Before diving into new APIs, we need to understand what has been marked for removal in Java EE 6.

Java EE was first released in 1999 and has had new specifications added to each release. Until Java EE 6, no specifications were removed or marked for removal. Over the years, there have been some features that were not well supported or widely adopted, because they were technologically outdated or other alternatives were made available. Java EE 6 has adopted a pruning process (also known as marked for deletion). This process has already been adopted by the Java SE group. None of the proposed items marked will actually be removed from Java EE 6, but could be removed from Java EE 7.

  1. 1. To begin with, let's look at the relationships among the Java EE containers:

  2. 2. Next, we examine the availability of the Java EE 6 APIs in the web container:

    • The green boxes denote the new APIs added to Java EE 6.

  3. 3. Next, we examine the availability of the Java EE 6 APIs in the EJB container:

    • The green boxes denote the new APIs added to Java EE 6.

  4. 4. Next, we examine the availability of the Java EE 6 APIs in the application client:

    • The green box denotes the new API added to Java EE 6.

We will now cover each of the items marked for deletion, why it was marked for deletion, and what will be replacing the pruned specification.

Pruning JAX-RPC

JAX-RPC is an early implementation for web services' interoperability across heterogeneous platforms and languages. JAX-RPC was a great initial implementation, and the JAX-RPC team has done an amazing job of creating this reference implementation. However, when the project started, there were few reference implementations to partner with, such as JAXB. Since the 1.x life span of JAX-RPC, there have been many specifications that have gained momentum, and the JAX-RPC team has used the knowledge learned from 1.x, as well as the widely available and adopted standards, to transform JAX-RPC 1.x into JAX-RPC 2.0.

While this might sound like a major release, it is much more than that. With the advent of JAX-RPC, the team, for many reasons, has decided to rename JAX-RPC 2.0 to JAX-WS 1.0. But the really exciting part of the team's efforts is the adoption of JAX-WS by Java EE 6. We will be exploring the JAX-WS specification in more detail later in this chapter, and in later recipes.

Why was it marked for deletion?

JAX-RPC version 1.1 was marked for deletion in Java EE 6. However, JAX-RPC version 2.0 was actually renamed to JAX-WS version 2.0. There are a few reasons for this renaming:

  • One reason is that the JAX-RPC name is misleading. Developers assume that all JAX-RPC code is Remote Procedure Calls (RPC), not Web Services.

  • Another important reason is, JAX-RPC 1.x does not use JAXB. The first version of JAX-RPC was completed before JAXB was released. The JAX-RPC writers developed a custom mapping solution instead.

  • By maintaining binary compatibility with the JAX-RPC 1.1, APIs would hinder the goal of ease-of-development.

What has replaced this specification?

JAX-RPC 2.0 was renamed JAX-WS 2.0 (Java API for XML Web Services). This is a much more robust, feature-rich, and popular API, effectively superseding the JAX-RPC 1.1 specification.

See also

Pruning JAXR

The Java API for XML Registries (JAXR) gives you a uniform way to use business registries that are based on open standards (such as ebXML) or industry consortium-led specifications (such as UDDI). While UDDI and ebXML still have valid use cases in the enterprise, they are not widely supported or used. Thus, the Java EE expert group has chosen not to continue the addition of JAXR in the Java EE 6 specification, and allow this specification to continue to evolve on its own.

Why was it marked for deletion?

Unfortunately, since UDDI is not widely used, JAXR has very limited adoption, deployment, and vendor support.

What has replaced this specification?

There is no replacement for this specification. It will potentially evolve as a separate JSR.

Pruning EJB Entity (CMP)

Previous versions of the EJB specification used a type of bean known as Entity Bean. These were distributed objects enabling an object-relational, persistent state. Beans in which their container managed the persistent state were said to be using Container-Managed Persistence (CMP), whereas beans that managed their own state were said to be using Bean-Managed Persistence (BMP).

Why was it marked for deletion?

The complex, heavyweight, and overkill model of EJB 2.x Entity Beans has been replaced by the popular, lightweight, POJO-based JPA persistence model introduced as a part of EJB 3.0 in Java EE 5. As of EJB 3.1, JPA has been completely separated to its own spec, and EJB will focus only on the core session bean and message-driven bean component models, and their client API.

What has replaced this specification?

JPA 2.0 is the recommended standard for persistence in Java EE 6.

See also

Pruning Java EE application deployment

The JSR 88 defines standard application programming interfaces (APIs) to enable deployment of J2EE applications and standalone modules to J2EE product platforms.

Why was it marked for deletion?

JSR 88 was an attempt at developing deployment tools that work across application servers. Unfortunately, this API has never gained much vendor support.

What has replaced this specification?

There is no replacement for this specification. It will potentially evolve as a separate JSR.

See also

Pruning EE Management

The J2EE Management specification (JSR 77) includes standard mappings of the model to Common Information Model (CIM), SNMP Management Information Base (MIB), and to the Java object model through a server resident Enterprise JavaBeans (EJB) component, known as the J2EE Management EJB Component (MEJB). The MEJB provides interoperable remote access to the model from any standard J2EE application.

Why was it marked for deletion?

Similar to JSR 88, JSR 77 was an attempt at creating application server management tools that work in a cross-vendor manner. This API has not been well supported.

What has replaced this specification?

There is no replacement for this specification. It will potentially evolve as a separate JSR.

See also

 

In with the new


Now that you've seen what is being marked for removal from the earlier versions of Java EE, you might be wondering what the novelties are in Java EE 6. This section will cover, at a high level, the key new features of Java EE 6. These new features will be employed in the upcoming recipes so you can get a better grasp on these new specifications, and understand how you can use them in your day-to-day problems and solutions.

The main goal of this release is to continue the improved ease of development introduced with Java EE 5. In Java EE 5, EJBs, persistent entities, and web services were remodeled to follow a more object-oriented approach (Java classes implementing Java interfaces), and to use annotations as a new way of defining metadata (XML deployment descriptors becoming optional). Java EE 6 follows this path and applies the same paradigms to the web tier.

Java EE 6 focuses on bringing simplicity to the enterprise by pruning outdated specifications, and introducing new specifications such as Contexts and Dependency Injection (CDI) and profiles. It adds more features to the existing specification (for example, standardizing singleton session beans), while adding new ones such as JAX-RS and JAX-WS.

Lighter

The Java EE 6 expert group had to face an interesting challenge—how to make the platform lighter, while adding more specifications. An application server has to implement 33 specifications in order to be compliant with Java EE 6. To make the platform more lightweight, the group introduced profiles, pruning, and EJB Lite (a subset of the full EJB features focusing on local interfaces, interceptors, transactions, and security only).

The metadata and common annotations

In addition to the various annotations that have been added or modified in Java EE 6, we also have various metadata and common annotations defined in the Java specification, including:

  • Annotations related to security, such as @DeclareRoles and @RolesAllowed

  • Annotations to use EJB, such as @EJB and @EJBs

  • Annotations for resource injection, such as @Resource and @Resources

  • Annotations to use JPA, such as @PersistenceContext, @PersistenceContexts, @PersistenceUnit, and @PersistenceUnits

  • Lifecycle annotations, such as @PostConstruct and @PreDestroy

  • Annotations to provide references to web services, such as @WebServiceRef and @WebServiceRefs

See also

 

Implementing Java Contexts and Dependency Injection (CDI)


Dependency injection is a popular technique in developing enterprise Java applications. In dependency injection, also called Inversion of Control (IoC), a component specifies the resources that it depends on.

An injector, typically a container, provides the resources to the component. Though dependency injection can be implemented in various ways, many developers implement it with annotations.

The concept of CDI originated in 2002 with Rod Johnson, who released the framework with the publication of his book Expert One-on-One J2EE Design and Development. Since then, Springframework has become one of the most widely used frameworks in the Java world. Dependency injection is used heavily in Java development frameworks such as Spring and Guice. Unfortunately, there is no standard approach for annotation-based dependency injection. In particular, a framework such as Spring takes a different approach to annotation-based dependency injection, than that of a framework such as Guice.

These services allow Java EE components, including EJB session beans and JavaServer Faces (JSF) managed beans, to be bound to lifecycle contexts, to be injected, and to interact in a loosely coupled way by firing and observing events. CDI unifies and simplifies the EJB and JSF programming models and allows enterprise beans to replace JSF managed beans in a JSF application.

JSR 299 can be broken down to these main packages:

  • Scopes and contexts: javax.context

  • Dependency injection service: javax.inject

  • Framework integration SPI: javax.inject.manager

  • Event notification service: javax.event

JSR 299 relies heavily on Java annotations for the Context and Dependency Injection specification, JSR 330. JSR 330 contains a set of annotations for use on injectable classes. The annotations are as follows:

  • @Qualifier: Identifies qualifier annotations. Qualifiers are strongly-typed keys that help distinguish different uses of objects of the same type.

  • @Inject: Identifies injectable constructors, methods, and fields.

  • @Named: Is a String-based qualifier.

  • @Scope: Identifies scope annotations.

  • @Singleton: Identifies a type that the injector only instantiates for a single instance.

@Qualifier

The JSR 330 @Qualifier annotation identifies a specific implementation of a Java class or interface to be injected:

@Target({ TYPE, METHOD, PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
@Qualifier
public @interface InjectableType {...}

@Inject

The JSR 330 @Inject annotation identifies a point in which a dependency on Java class or interface can be injected into a target class. This injection not only creates a new instance, or prototype object by default, but can also inject a singleton object as well:

@Stateful
@SessionScoped
@Model
public class ServiceWithInjectedType { @Inject InjectableType injectable;
...

The container will find the injectable type specified by @Qualifier and automatically inject the reference.

@Named

The JSR 330 @Named annotation allows for the String-based versus type-based qualification of injectable assets. An example would be:

http://download.oracle.com/javaee/6/api/javax/inject/Named.html.

@Named
public class NamedBusinessType implements InjectableType {...}

@Scope

Within a web application, a bean needs to be able to hold the state of duration of the client's interaction with the application. The following table details the available bean scopes:

Scope

Annotation

Duration

Request

@RequestScoped

Clients' interaction for a single HTTP Request.

Session

@SessionScoped

Clients' interaction across multiple HTTP Requests.

Application

@ApplicationScoped

Shared state across all clients' interactions.

Dependent

@Dependent

Default scope if none is specified. Means an Object exists to serve exactly one client (bean), and has the same lifecycle as that client (bean).

Conversation

@ConversationScoped

Clients' interaction with JSF application within developer-controlled boundaries that extend across multiple invocations of the JSF lifecycle.

The Scoped class-based annotation would look like:

@Stateful
@SessionScoped
@Model
public class ServiceWithInjectedType { @Inject InjectableType injectableType;

You can also create your own custom scope handling by using the @Scope annotation:

@java.lang.annotation.Documented
@java.lang.annotation.Retention(RUNTIME)
@javax.inject.Scope
public @interface CustomScoped {}

See also

 

Understanding the EJB 3.1 specification


Enterprise JavaBeans (EJB) is a managed, server-side component architecture for modular construction of enterprise applications. EJB was originally introduced in 1998, which included Session Beans and Entity Beans; Java EE 6 now focuses only on Session Beans. Entity Beans (CMP) have been replaced with the newly adopted JPA specification.

The EJB 3.1 specification simplifies the development and deployment by leveraging new annotations, and making XML descriptors optional.

@Stateless

The EJB 3.0 local client view is based on a Plain Old Java Interface (POJI) called a local business interface. A local interface defines the business methods that are exposed to the client and that are implemented on the bean class. Having a separate interface from the implementation is sometimes unnecessary and cumbersome. In these situations, to further ease the use of EJBs locally, you can simply annotate a class (POJO). There is no interface required to create a simple stateless EJB. EJBs can also be deployed directly in a WAR file without being previously packaged in a JAR file:

@Stateless
public class CustomerEJB {
@PersistenceContext(unitName = "businessData")
private EntityManager em;
public Customer findCustomerById(Long id) {
return em.find(Customer.class, id);
}
public Customer createCustomer(Customer customer) {
em.persist(customer);
return customer;
}
}

@EJB

The ease of use for the new EJB annotations extends to the client side as well. Invoking a method on EJB requires only annotating a reference using dependency injection.

Dependency injection allows a container (client, web, or EJB container) to automatically inject a reference on EJB with the help of the @EJB annotation:

@EJB
private CustomerEJB customerEJB;
...
Customer customer = customerEJB.findCustomerById(123L);

Even though there is no interface, the client cannot instantiate the bean class using the new() operator explicitly. That's because all bean invocations are made through a special EJB reference or proxy provided by the container, which allows the container to provide all the additional bean services, such as pooling, container-managed transactions, and concurrency management.

@Remote

If EJB needs to be invoked remotely, then it needs to implement a remote interface. The only difference between a normal Java interface and a remote interface is the presence of the @Remote annotation, as shown in the following code example:

@Remote
public interface CustomerEJBRemote {
public List<Customer> findCustomers();
public Customer findCustomerById(Long id);
public Customer createBook(Customer customer);
public void deleteCustomer(Customer customer);
public Customer updateCustomer(Customer customer);
}

@Singleton

A singleton bean, also known as a singleton, is a new kind of session bean that is guaranteed to instantiate a single instance for an application JVM.

You define a singleton with the @Singleton annotation, as shown in the following code example:

@Singleton
public class ServiceBean {
...
}

@Asynchronous

By default, session bean invocations through remote, local, and no-interface views are synchronous:

A client invokes a method, and it gets blocked for the duration of the invocation until the processing has completed; the result is returned, and the client can carry on with their work.

But asynchronous processing is a common requirement in many applications handling long-running tasks, or for tasks that are fire-and-forget, where you might be able to increase response time:

Since EJB 3.1, you can call methods asynchronously simply by annotating a session bean method with @Asynchronous.

Asynchronous methods can return a java.util.concurrent.Future<V> object or void. A Future<V> object holds the result of an asynchronous operation. You can access the Future<V> object to retrieve a result value, check for exceptions, or cancel an in-progress invocation. The Future<V> interface provides a get() method to retrieve the value:

public class AppointmentBeanImpl implements AppointmentService{
public Future<XMLGregorianCalendar> getAppointment (String accountNumber){
...
XMLGregorianCalendar result = ...;
return new AsyncResult <XMLGregorianCalendar>(result);
}
}

The call to the getAppointment method will return a pointer to FUTURE and the call will not block until you make the request for the represented type in the Future<V> by calling get() in the Future<V>:

public Object getFromFuture(Future future)
throws Exception {
Object t;
try {
t = future.get (EXECUTION_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS);
}
...
return t;
}

See also

 

Understanding the JPA 2.0 specification


The Java Persistence API is the standard for persisting Java objects to a relational database. This specification includes metadata definition mappings and configuration. It also includes a standard Service Provider Interface (SPI) that allows applications to easily plug-in different JPA providers, such as Hibernate, or iBatis, just to name a few.

@ElementCollection

Another useful new mapping type in JPA 2.0 is the element collection, which allows an entity to reference a collection of objects that are of a basic type (such as String or Integer). The @ElementCollection annotation is used to indicate the mapping. The objects are stored in a separate table called a collection table, which is by default named as <entityName>_<attributeName>:

@Entity
public class Customer {
...
@ElementCollection
@Column(name="SNAME")
Collection<String> screennames;
...
}

@CollectionTable

If you want to override the default mapping name convention of the @ElementCollection annotation, it can be overridden with the @CollectionTable annotation:

@Entity
public class Customer {
...
@ElementCollection
@CollectionTable(name="SCREENNAMES")
@Column(name="SNAME")
Collection<String> screennames;
...
}

Pessimistic locking

In the JPA 2.0 specification, pessimistic locking has been a needed improvement, especially in high data concurrency systems.

In order to enable this functionality, the entity manager, find() and refresh() methods take a lock mode at the operational level.

Criteria API

An exciting new feature is the Criteria API. This allows you to leverage the Criteria API to add nodes programmatically to the criteria tree, and then pass to a criteria wrapper for evaluation. The two types are String-based and Strongly-typed criteria.

String-based criteria

With string-based criteria, you specify attribute names as strings similar to many of the existing criteria APIs, as well as expression frameworks such as Hibernate:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery c = cb.createQuery(Customer.class);
Root cust = c.from(Customer.class);
c.select(cust). where(cb.equal(cust.get("name"), "BASE Logic"));
List result = em.createQuery(c).getResultList();

Strongly-typed criteria

A string-based criterion seems familiar, but can lead to difficulties in finding defects if attributes are mistyped or a wrong attribute is used. The compiler will not catch these errors, and the exception manifests itself only at runtime such as searching for a Customer's name with cust.get("name"). Using strongly-typed criteria will bind the criteria to the attribute of the Customer Object as seen in the following listing:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Customer> c = cb.createQuery(Customer.class);
Root<Customer> cust = c.from(Customer.class);
c.select(cust) where (cb.equal (cust.get(Customer_.name), "BASE Logic"));
List<Customer> result = em.createQuery(c).getResultList();

Additional JPQL

There are several additional JPQL features worth noting. The following listing details the key addition, a description, and a given example on how this might be used:

Feature

Description

Example

CASE statement

CASE {
WHEN conditional
THEN [expr]+
ELSE [expr]
END
UPDATE Customer c SET c.creditLimit = CASE WHEN c. creditScore = 600
THEN c. creditLimit * 2.0
ELSE c. creditLimit * 1.5
END

Collection input parameters

Allow parameter arguments to be collections

SELECT c FROM Customer c WHERE c.lastName IN :names

Date, time, and timestamp literals

JDBC syntax was adopted:

{d 'yyyy-mm-dd'}
{t 'hh-mm-ss'}
{ts 'yyyy-mm-dd hh-mm-ss'}
SELECT c FROM Customer c WHERE c.lastupdate < {d '2011-01-08'}

INDEX in a List

Refer to an item's position index in a list

SELECT c FROM Appointment a JOIN a.waitingList c WHERE a.num = 454 AND INDEX(c) = 0

Map support KEY, VALUE, ENTRY

Allow comparison and selection of keys and values and selection of entries

SELECT c.name, KEY(p), VALUE(p) FROM Customer c JOIN c.phones p WHERE KEY(p) IN ('Work', 'Cell')

Non-polymorphic queries TYPE

Can query across specific subclasses of a superclass

SELECT p FROM Division d WHERE TYPE(p) = SouthernDivision OR TYPE(p) = NorthernDivision

NULLIF, COALESCE

Additional CASE variants: COALESCE([expr], [expr]+)

SELECT COALESCE (d.name, d.id) FROM Department d

Scalar expressions in the SELECT clause

Return the result of performing a scalar operation on a selected term

SELECT LENGTH(c.name) FROM Customer c

Variables in SELECT constructors

Constructors in SELECT clause can contain identification variables

SELECT new CustInfo (c.name, a) FROM Customer c
JOIN c.address a

See also

 

Understanding the JAX-RS 1.1 specification


A long-awaited feature for Java EE 6 is the advent of RESTful Web Services. Representational State Transfer (REST) attempts to describe architectures that use HTTP or similar protocols by constraining the interface to a set of well-known, standard operations (such as GET, POST, PUT, DELETE for HTTP). Here, the focus is on interacting with stateful resources, rather than messages or operations.

The term Representational State Transfer was introduced and defined in 2000 by Roy Fielding in his doctoral dissertation.

JAX-RS enables you to rapidly build lightweight web services that conform to the REST style of software architecture. An important concept in REST is the existence of resources, each of which can be referred to with a global identifier, that is, a URI. In particular, data and functionality are considered resources that can be identified and accessed through URIs.

JAX-RS furnishes a standardized API for building RESTful web services in Java. The API contributes a set of annotations and associated classes and interfaces. Applying the annotations to POJOs enables you to expose web resources. This approach makes it simple to create RESTful web services in Java.

@Path

The @Path annotation sets the relative URI path. While this feature is quite powerful, this annotation becomes even more important with the concept of URI Templates. A URI Template allows you to embed variables within your URI syntax. These variables are substituted at runtime in order for a resource to respond to a request based on the substituted URI. Variables are denoted by curly braces:

@Path("/customers/{name}")
public class CustomerController {
@GET
@Produces("text/xml")
public String getCustomer (@PathParam("name") String name) {
...
}
}

HTTP Methods

Several HTTP Method resource designator annotations, such as @Get, @Put, @Post, @Delete, and @Head are supported; they correspond to the similarly named HTTP methods.

@Produces

The @Produces annotation is used to specify the MIME types, which a resource can produce and return to a client. Common MIME types include PLAIN_TEXT, TEXT_XML, APPLICATION_XML, and APPLICATION_JSON:

@Path("/order")
public class OrderController {
// Return JSON
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Order getJSONOrXML() {
...
}
// Return Text/Xml
@GET
@Produces({ MediaType.TEXT_XML })
public Order getHTML() {
...
}
// Return plain text
@GET
@Produces({ MediaType.TEXT_PLAIN })
public Order getText() {
...
}
}

@Consumes

The @Consumes annotation is used to specify the MIME types that a resource can consume, which were sent from a client. Common MIME types include PLAIN_TEXT, TEXT_XML, APPLICATION_XML, and APPLICATION_JSON.

See also

 

Understanding the Servlet 3.0 specification


Unlike some previous releases of the Servlet specification, the Servlet 3.0 specification is packed with lots of exciting features, facilitating annotation-based configuration. Some of the key additions include:

  • Ease of development with annotations

  • Optional deployment descriptors

  • Asynchronous support

  • Security enhancements

  • Other miscellaneous changes

@WebServlet

To define a Servlet component in a web application, you use @WebServlet. The @WebServlet annotation has many attributes, such as name, urlPatterns, and initParams, which you use to define the Servlet's behavior. At least, name and urlPatterns are required:

@WebServlet(name="HealthMonitorServlet", urlPatterns="/health")
public class ServletHealthMonitor extends HttpServlet {
...
}

@WebFilter

You use the @WebFilter annotation to define a filter. You can use @WebFilter on any class that implements the javax.servlet.Filter interface. Just like the @WebServlet annotation, you must specify the urlPatterns on this annotation as well:

@WebFilter(filterName = "AuthenticateFilter", urlPatterns = {"/customer", "/getOrders"})
public class AuthenticateFilter implements Filter {
...
}

@WebInitParam

You use the @WebInitParam annotation to specify the init parameters to a Servlet or Filter. This annotation is especially helpful for configuration, and as we will see in later recipes, it can allow us greater control over application configuration:

@WebServlet (name="HealthMonitorServlet", urlPatterns="/health")
@WebInitParam (name = "serverId", value = "XYZ:8080")
public class
ServletHealthMonitor extends HttpServlet {
...
}

@WebListener

You use the @WebListener annotation on a class that acts as a listener to events in a given web application context. You can use @WebListener to annotate a class that implements ServletContextListener, ServletContextAttributeListener, ServletRequestListener, ServletRequestAttributeListener, HttpSessionListener, and HttpSessionAttributeListener.

Here is an example with ServletContextListener:

@WebListener
public class AuditServletContextListener implements ServletContextListener {
...
}

Web fragments

One of Servlet 3.0's most significant concepts is the idea of web fragments or modular web.xml. The idea is to be able to create modular and reusable web components. These components would typically be packed inside of a JAR and contain a descriptor such as this web-fragement.xml packaged into the JAR's META-INF directory:

<web-fragment>
<servlet>
<servlet-name>
myReusableServlet
</servlet-name>
<servlet-class>
ch01.myReusableServlet
</servlet-class>
</servlet>
<listener>
<listener-class>
ch01.myReusableListener
</listener-class>
</listener>
</web-fragment>

This reusable JAR is placed into the WEB-INF/lib directory of the web applications in which you want to use this reusable component. During the application startup, it is the responsibility of the Container to scan the information that is found in the /META-INF/web-fragment.xml file available in the application's classpath.

Asynchronous servlet processing

Along the same lines as the @Asynchronous annotation we have seen earlier, the Servlet 3.0 specification now has support for asynchronous servlet processing:

public void doGet (HttpServletRequest request, HttpServletResponse response) {
AsyncContext context = request.startAsync(request, response);
ServletContext scope = request.getServletContext();
((Queue<AsyncContext>) scope.getAttribute("jobQueue")).add(context);
..

This new feature is especially useful for AJAX-based interaction with Web 2.0 designs. We will investigate several asynchronous recipes to demonstrate how this can be a great performance enhancement to the user experience.

See also

 

Understanding the WebBeans 1.0 specification


The name of the JSR was changed from WebBeans to Contexts and Dependency Injection for Java.

See also

 

Understanding the JSF 2.0 specification


Java Server Faces (JSF) was initially released in 2004, and has been met with both criticism and embrace, as with many specifications. But time has tested and revealed that JSF is a solid framework, and Java EE embraces the new JSF 2.0 specification. With the advent of the new JSF 2.0 model, several new annotations are now available to simplify development and configuration.

@ManagedBean

The @ManagedBean annotation is used for defining a POJO as a JSF Managed Bean. This will be especially helpful for applications not using @EJBs.

@ResourceDependency

The @ResourceDependency annotation allows you to define resources to be used in your pages. This is a more elegant way to include resources such as styles and scripts:

@ResourceDependency(library="corp_en", name="css_english.css")

@ListenerFor

The @ListenerFor annotation allows a component to subscribe to a particular event as a listener:

@ListenerFor(systemEventClass= AfterAddToParentEvent.class, sourceClass=UIOutput.class)
public class CustomRenderer extends Renderer implements ComponentSystemEventListener {
...
public void processEvent (ComponentSystemEvent event) throws AbortProcessingException {
...

@FacesConverter

The @FacesConverter annotation allows you to register a class as a runtime Converter:

@FacesConverter(value = "callConverter")
public class CallConverter implements Converter {
@Override
public Object getAsObject (FacesContext ctx, UIComponent component, String value) {
return value;
}
@Override
public String getAsString (FacesContext ctx, UIComponent component, Object value) {
}
}

@FacesValidator

The @FacesValidator annotation allows you to register a class as a runtime Validator:

@FacesValidator(value = "accountValidator")
public class AccountValidator implements Validator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
...

See also

 

Understanding Bean Validation


The Java API for JavaBeans Validation (Bean Validation) provides a mechanism for validating application data. Bean Validation is integrated into the Java EE containers, allowing the same validation logic to be used in any of the tiers of an enterprise application. This allows for a simplified and more readable application when utilizing Bean Validation in JSF, JAX-RS, or your JPA services.

Getting ready

The Bean Validation is built into the Java EE 6 compliant containers, so there is no preparation that you need to employ for these techniques.

How to do it...

Bean Validation can be as simple as null and size checks on your domain objects such as:

public class Customer {
@NotNull
@Size(min=2, max=16)
private String firstname;

In addition to standard validation annotations, the new @Pattern annotation allows complex, property-type validation based on regular expressions. The following depicts the validation of a phone number:

@Pattern(regexp="^\\(?(\\d{3})\\)?[- ]?(\\d{3})[- ]?(\\d{4})$",
message="{invalid.phonenumber}")
protected String officePhone;

The @Pattern annotation has an optional message property associated with the validation failure.

There's more...

The built-in Bean Validation constraints are shown in the following table:

Feature

Description

Example

@AssertFalse

Match the field or property against Boolean false.

@AssertFalse

boolean isComplete;

@AssertTrue

Match the field or property against Boolean true.

@AssertTrue

boolean isEnabled;

@DecimalMax

Match the field or property against a decimal value lower than or equal to the element value.

@DecimalMax("8.75")

BigDecimal taxRate;

@DecimalMin

Match the field or property against a decimal value higher than or equal to the element value.

@DecimalMax("4.20")

BigDecimal taxRate;

@Digits

Match the field or property against a number in a specific range.

@Digits(integer=6, fraction=2)

BigDecimal cost;

@Future

Match the field or property against a future date.

@Future

Date endDate;

@Max

Match the field or property against an integer value less than or equal to the element value.

@Max(3)

int attempts;

@Min

Match the field or property against an integer value greater than or equal to the element value.

@Min(1)

int quantity;

@NotNull

Match the field or property to be not null value.

@NotNull

String username;

@Null

Match the field or property to be a null value.

@Null

String errors;

@Past

Match the field or property against a past date.

@Past

Date startDate;

@Pattern

Match the field or property against the given regular expression.

 

@Size

Match the field or property against specific size boundaries.

If the field or property is a String, the size of the string is evaluated. If the field or property is a Collection, the size of the Collection is evaluated. If the field or property is a Map, the size of the Map is evaluated. If the field or property is an array, the size of the array is evaluated.

@Size(min=2,max=240)

String briefMessage;

Note

Do not confuse @Future with Future<V> in the concurrency package.

Timezone and locale

An important note about @Future and @Past is that each validator uses the current time-zone and current locale for the constraint. If you are validating in varying timezones, then you will need to create a custom constraint to accomplish the task. We will create custom constraints in later chapters, to demonstrate how to solve these frequent occurrences.

See also

 

Understanding profiles


Profiles are a major new feature in the Java EE 6 environment. Their main goal is to allow developers to pick-and-choose the specifications from the Java EE stack they need, and allow for smaller footprints for projects that do not need certain specifications from the 33 different ones included in Java EE 6. Many people have complained that Java EE was too large. Servlet containers such as Tomcat have allowed many developers to use a small subset Java EE, such as Servlets, JSF, and JSPs, but have forced developers to add other frameworks, such as Spring or Guice to accomplish even medium complex solutions to everyday problems.

We will utilize various aspects of these profiles as we work through the proceeding chapters.

See also

About the Author

  • Mick Knutson

    Mick Knutson has over 25 years of experience in the IT industry. As a passionate and experienced enterprise technology consultant, Java architect, and software developer, he looks forward to using his unique professional experience to help students learn about software development in an effective, practical, and convenient manner.

    Mick's real-world expertise comes from providing individuals and mid-to-large-size businesses with advanced software consulting and training. He has collaborated with many notable clients and partners including VMware, Spring Source, FuseSource, Global Knowledge, and Knowledge United. His technical expertise includes OOA/OOD/OOP, Java, Java EE, Spring Security, Oracle, Enterprise Integration, and Message-Oriented Middleware (MOM).

    As a veteran of the IT industry, Mick is determined to help as many people as possible and show that anyone can become a software developer. He has spoken around the world at training seminars, luncheons, book publishing engagements, and white paper engagements. He has authored several technical books and articles on Spring Security, Java EE 6, HTTP, and VisualVM. He is also a featured blogger at DZone, where he is part of the curated Most Valuable Blogger (MVB) group.

    Having lived and breathed software development for over two decades, Mick enjoys translating complex technical concepts into plain English for different audiences. Whether he is helping an experienced software professional or someone who is new to the field, he can simplify even the most intricate IT concepts.

    Mick's mission is to use his seasoned professional experience to help anyone who wants to learn about software development. As an expert and professional, Mick designs his training courses to make the learning experience as enriching, seamless, and convenient as possible so that you can master software development in the shortest amount of time.

    Learn from an expert. Mick warmly looks forward to helping you learn software development in the right way so that you can maximize both your money and your time.

    You can also refer to his following books:

    • Spring Security Third Edition
    • Distributed Configuration with Spring Cloud Config
    • Java EE6 Cookbook
    • HTTP Reference Card (DZone)
    • VisualVM Reference Card (DZone)
    • You can also refer to his video on BASELogic available on YouTube.

    You can also connect with him on the following social media sites:

    • LinkedIn (mickknutson)
    • Twitter (mickknutson)
    • GitHub (mickknutson)
    • Bitbucket (mickknutson)
    • Udemy video series (MickKnutson)
    • Facebook (BASELogic)
    • Google+ (BASElogic)

    Browse publications by this author
Book Title
Access this book, plus 8,000 other titles for FREE
Access now