Network Deployment (Distributed operating systems), v8.0 > End-to-end paths > Web services - RESTful services > Use Java contexts and dependency injection with JAX-RS > 4. Implementing JAX-RS resources with JCDI functionality.
Implement JAX-RS resources with dependency injection
Java Contexts and Dependency Injection (JCDI) supports dependency injection in managed beans. By configuring your web application to be JCDI-enabled, you can add @javax.inject.Inject annotated fields and properties. If the annotated fields and properties are valid injection points with valid JCDI managed beans, then their dependencies will be resolved during run time. Dependency injection separates the creation of new instances of Java types from the use of those Java types in the code. Dependency injection can allow for more easily testable code while also improving the ability to manage applications.
In this task, you configure the application to use JCDI by adding a beans.xml deployment descriptor. Then, you create a standard Java API for RESTful Web Services (JAX-RS) resource type with a @javax.inject.Inject field, which will be resolved during run time.
The following instructions describe how you can create a simple JCDI-enabled web application with JAX-RS:
Procedure
- Add a beans.xml deployment descriptor to your web application (WAR) in the WEB-INF directory. This indicates that the web application should be a JCDI-enabled application. The existence of the WEB-INF/beans.xml file indicates that the archive is a JCDI-enabled archive. You are not required to add any additional information to the deployment descriptor for this task. The following example illustrates a basic WEB-INF/beans.xml file:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xsi:schemeLocation="http://java.sun.com/xml/ns/javaee http:// java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <!-- This is empty on purpose. --> </beans>
- Create a JAX-RS root resource class. The following example illustrates a simple JAX-RS root resource class:
package com.example.jaxrs; @javax.ws.rs.Path("exampleWithInjection") public class StringResource { public StringResource() { /* use a no-argument constructor */ } @javax.ws.rs.core.Context private javax.ws.rs.core.HttpHeaders //publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ Headers; @javax.annotation.PostConstruct private void myPostConstruct() { /* read from the //publib.boulder.ibm.com/infocenter/wasinfo/v8r0/index.jsp?topic=/ Headers if required */ } @javax.ws.rs.GET @javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN) public String get() { return "Hello world!"; } }In the code above, a no-argument constructor was used. A no-argument constructor is a valid JCDI constructor, which makes the class a valid JCDI bean. To inject JAX-RS context objects or parameters during object instantiation, you can use bean properties or fields. Then use an @javax.annotation.PostConstruct annotated method, which is called after the object is constructed.
- Add a JCDI lifecycle scope to your JAX-RS classes. The following example illustrates a JAX-RS root resource class with an @javax.enterprise.context.RequestScopedscope annotation:
Add the @javax.enterprise.context.RequestScoped annotation to your root resource classes to ensure that your JAX-RS root resource class has a unique instance per request. This is the default behavior in non-JCDI-enabled applications.
package com.example.jaxrs; @javax.ws.rs.Path("exampleWithInjection") @javax.enterprise.context.RequestScoped public class StringResource { @javax.ws.rs.GET @javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN) public String get() { return "Hello world!"; } }
- Create a class that is injected into the JAX-RS root resource. The following example illustrates a standard Java class:
package com.example.jaxrs; public class Data { public String getData() { return "Hello world!"; } }- Modify your JAX-RS root resource to add an @javax.inject.Inject annotated field for the com.example.jaxrs.Data type. The following example illustrates a modified JAX-RS root resource class with an @javax.inject.Inject injection point:
package com.example.jaxrs; @javax.ws.rs.Path("exampleWithInjection") @javax.enterprise.context.RequestScoped public class StringResource { @javax.ws.rs.GET @javax.ws.rs.Produces(javax.ws.rs.core.MediaType.TEXT_PLAIN) public String get() { return myData.getData(); } @javax.inject.Inject private Data myData; }During run time, when the JAX-RS root resource is constructed, an instance of the Data type is injected into the myData field. While this is a simple form of injection, JCDI allows for more complex use cases. Read the JCDI specification for additional details.
- Add a Servlet 3.0 web.xml file to your WAR file. In the following example, a default JAX-RS application servlet definition is added, which makes all JAX-RS root resources available in the /rest/* URL pattern:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/ j2ee/web-app_3_0.xsd" version="3.0"> <servlet> <servlet-name>javax.ws.rs.core.Application </servlet-name> <load-on-startup>1 </load-on-startup> </servlet> <servlet-mapping> <servlet-name>javax.ws.rs.core.Application </servlet-name> <url-pattern>/rest/* </url-pattern> </servlet-mapping> </web-app>
Results
You have configured a web application to use JCDI, created a JCDI lifecycle scoped JAX-RS resource, and created a standard injection point.
Implement a JAX-RS resource with decorators and method interceptors
Implement JAX-RS resources with different lifecycle scopes
Use Java contexts and dependency injection with JAX-RS
Related
Web services specifications and APIs