One of the big features in Java EE 6 is dependency injection(yeah, 330 & 299 stuff!!). It pretty much integrated with the every EE component. That means you can nicely use all the CDI features with JAX-WS web services. Let us see a simple shopping cart web service that uses CDI.

 @WebService public class ShoppingCart { @Inject private CartData cart; public List<String> addCart(String item) { return cart.addCart(item); } } @SessionScoped public class CartData implements Serializable { private List<String> items = new ArrayList<String>(); public List<String> addCart(String item) { items.add(item); return items; } } 

First, you may have noticed the two unfamiliar annotations: @Inject, @SessionScoped. As you may have guessed from @Inject annotation, a CartData instance would be injected into ShoppingCart instance. Right, but what is the lifecycle of a CartData instance ? A CartData instance is tied to a client's HTTP session scope since it uses @SessionScoped annotation. If a client uses the web service after its session expires, the container creates a new CartData instance behind the scenes. One needs to write a lot of code to do this in Java EE 5, now it is that simple in Java EE 6 ! To try the service, let us specify in web.xml that a HTTP session timeout is a minute.

 <web-app ...> <session-config> <session-timeout>1</session-timeout> </session-config> </web-app> 

Also, to enable CDI, one needs to package an empty beans.xml. So our war file would like the following:

 WEB-INF/beans.xml WEB-INF/classes/pkg/CartData.class WEB-INF/classes/pkg/ShoppingCart.class WEB-INF/web.xml 

Note that the above war is portable across all Java EE 6 implementations. Also, the war doesn't contain any wrapper bean classes(usually generated by wsgen). No need to run wsgen and package those classes in a bundle anymore in Java EE 6.Let us a write a sample client to access the ShoppingCartService and see what happens.

 public class Main { public static void main(String[] args) throws Exception { ShoppingCart cart = new ShoppingCartService().getShoppingCartPort(); Map requestContext = ((BindingProvider) cart).getRequestContext(); requestContext.put( BindingProvider.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE); List<String> items = cart.addCart("mango"); items = cart.addCart("apple"); System.out.println("Sleeping 5 secs"); Thread.sleep(5*1000); items = cart.addCart("pear"); System.out.println("cart ..."+items); System.out.println("Sleeping 60 secs. Should create a new cart ..."); Thread.sleep(60*1000); items = cart.addCart("beef"); items = cart.addCart("chicken"); System.out.println("Sleeping 5 secs"); Thread.sleep(5*1000); items = cart.addCart("pork"); System.out.println("cart ..."+items); } } Client execution output: cart ...[mango, apple] Sleeping 5 secs cart ...[mango, apple, pear] Sleeping 60 secs. Should create a new cart ... cart ...[beef, chicken] Sleeping 5 secs cart ...[beef, chicken, pork] 

As you see the client execution output, new cart is automatically created after a minute. That's it for now, keep exploring the other features of CDI in Java EE 6. Try this in GlassFish v3

Technorati: jaxws metro webservices glassfish v3 cdi jsr299 weld