Step 3. Create JAX-WS WebLogic Web Services for Spring beans
Time to complete this step: 20 minutes
You can use the Oracle Enterprise Pack for Eclipse (OEPE) to automatically generate WebLogic Web Service to expose Spring service delegates/beans.
During previous tutorial part for Spring, you have developed Spring service delegates/beans for various DAOs of the Trouble Ticket System. In this step, you will use the OEPE for generating JAX-WS WebLogic Web Services for the
TroubleTicketSystemServer Spring delegates/beans. The Web Services will use the JAXB types generated in the previous step for messaging.
You will perform the following tasks in this step:
Import the utility/helper classes
Copy the following Java classes from the extracted
resources folder to the
com.oracle.ticketsystem.util package.
- Utils.java
Overwrite the existing
Utils class. The
Utils class has additional methods for providing a reference of a
TicketSystemException based on the given error message and a
Throwable instance.
- TicketSystemException.java
An exception class to represent error situation while running the web service operation. The
TicketSystemException class is annotated with
@WebFault annotation that maps the WSDL faults to Java exceptions.
- Adapter.java:
An adapter class with static helper methods for converting the given JPA beans to the corresponding JAXB type.
Open each copied class and review the code.
Create the JAX-WS WebLogic Web Services for Spring beans
- In the
Project Explorer view, right-click the
TroubleTicketSystemServer project and select
New > WebLogic Web Service for Spring beans. This will open the
Select Spring Service Bean wizard page.
- On the wizard dialog, provide the following information:
- Select the Spring bean configuration file i.e.
/TroubleTicketSystemServer/WebContent/Web-INF/applicationContext.xml.
- Select the
LoginDelegate Spring bean that we want to expose as WebLogic Web Service. (Note: the wizard does not support Spring ORM service beans implemented in Spring 1.x style based on JPA Templates and TransactionProxyFactoryBeans.)
- The selection of the
LoginDelegate Spring bean highlights the Spring service delegate interface and its operations defined. Make sure that
com.oracle.ticketsystem.delegates.ILoginDelegate is selected as the type and the
login item is selected as the method. (Note: a service bean can implement multiple interfaces but service methods from only one interface can be generated in this wizard.)
- Click
Next.
- This will open the
Web Service Class Name wizard page. Specify the
com.oracle.ticketsystem.webservices as the package and
LoginWebService as class name for the web service.
- Click
Finish. The JAX-WS WebLogic Web Service class (
LoginWebService) is generated in the
com.oracle.ticketsystem.webservices package. The web service class contains methods exposed from the Spring bean.
- Similarly, generate JAX-WS WebLogic Web Services for the Spring delegates/beans
ProductDelegate and
TicketDelegate with the name
ProductWebService and
TicketWebService in the
com.oracle.ticketsystem.webservices package. Make sure that all the methods of the Spring delegates/beans are selected.
- Open the generated JAX-WS WebLogic Web Service class
LoginWebService and review the code.
|
@WebService
public class LoginWebService extends SpringBeanAutowiringSupport
{
public static String BEAN_ID = "LoginDelegate";
@Autowired
@Qualifier("LoginDelegate")
private ILoginDelegate springServ;
@Resource
private WebServiceContext wsContext;
private void getSpringService() throws Exception {
if(springServ ==null ) {
//@Autowired does not work in JAX-WS web services on WebLogic server 10.3
//fall back to get the spring bean from WebApplicationContext
ServletContext servletContext= (ServletContext)wsContext.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
WebApplicationContext webContext = WebApplicationContextUtils.getWebApplicationContext( servletContext );
springServ = (ILoginDelegate)webContext.getBean(BEAN_ID);
if( springServ == null )
throw new Exception("Spring service not available: " + BEAN_ID);
}
}
@WebMethod
public Technician login(String id,String pwd) throws Exception {
getSpringService();
return springServ.login( id,pwd );
}
}
|
- The generated JAX-WS WebLogic Web Service classes extends the
SpringBeanAutowiringSupport class, which is a convenient base class for self-autowiring classes in Spring-based web applications. It resolves
@Autowired annotations in the endpoint class against beans in the current Spring root web application context.
- The
LoginWebService class is annotated with the
@WebService annotation. The
@WebService annotation marks a Java class as implementing a Web service or marks a service endpoint interface (SEI) as implementing a Web service interface.
- The
@Resource annotation marks the
WebServiceContext as a resource needed by the application and is injected by the server container.
- The
login() method of the
LoginWebService class is annotated with the
@WebMethod annotation to denotes it as a web service operation. It first calls the
getSpringService() method to intialize the
LoginDelegate spring delegate/bean from
WebServiceContext.
- Open the other generated JAX-WS WebLogic Web Service classes and review the code.
Edit the generated JAX-WS WebServices to use the JAXB types for messaging
The web service operations of the generated JAX-WS WebLogic Web Service classes uses the JPA beans for messaging; i.e., it accepts JPA beans as input and returns the same as output. That means the web service client has to depend on JPA beans and thus the server side complexities is now released to the outside world. This can be avoided and we can use the JAXB types generated in the previous step for messaging. For that we need to modify the web service operation/method signature.
Since, the web service operation parameters are not annotated with
@WebParam annotations, the message part names of the generated WSDL will have name like args0, args1, .... Thats not very readable, hence you will also annotate each parameter of the web service operation with the
@WebParam annotation. The
name parameter of
@WebParam annotation describes the
name of the
wsdl:part attribute representing the parameter.
Edit the web service operation signature of
LoginWebService
- Open the
LoginWebService class.
- Specify
@WebParam for each input argument of the
login() operation as shown below:
Note: when the Java Editor is active, press Ctrl+Shift+O to organize imports.
|
@WebMethod
public Technician login(
@WebParam(name="id")
String id,
@WebParam(name="pwd")
String pwd)
throws Exception {
getSpringService();
return springServ.login( id,pwd );
}
|
- To report any runtime failure, while executing the web service operation, use the provided
TicketSystemException class. The
TicketSystemException class is annotated with the
@WebFault annotation that maps the WSDL faults to Java exceptions. Change the
login() operation signature and implementation to throw a
TicketSystemException instead of
Exception class.
|
@WebMethod
public Technician login(
@WebParam(name="id")
String id,
@WebParam(name="pwd")
String pwd)
throws TicketSystemException {
try {
getSpringService();
return springServ.login( id,pwd );
} catch(Exception ex) {
throw Utils.getTicketSystemException("Login failed", ex);
}
}
|
Note: when the Java Editor is active, press Ctrl+Shift+O to organize imports. Make sure to choose the
com.oracle.ticketsystem.util.Utils.
- The
login() operation returns the
Technician JPA entity bean. Edit its signature to return the
TechnicianType JAXB type instead of
Technician JPA entity bean. Use the provided
Adapter helper class for converting the
Technician JPA entity bean to the
TechnicianType JAXB type.
|
@WebMethod
public TechnicianType login(
@WebParam(name="id")
String id,
@WebParam(name="pwd")
String pwd) throws TicketSystemException {
try {
getSpringService();
Technician technician = springServ.login( id, pwd );
return Adapter.adapt(technician);
} catch(Exception ex) {
throw Utils.getTicketSystemException("Login failed", ex);
}
}
|
Note: when the Java Editor is active, press Ctrl+Shift+O to organize imports. Make sure to choose the
com.oracle.ticketsystem.util.Adapter.
- Save the
LoginWebService class.
Edit the web service operation signature of
ProductWebService
- Open the
ProductWebService class. You can either copy the
ProductWebService class from the
resources folder (to save time) or follow the instructions here for editing it.
- Specify
@WebParam for each input argument of the
getProduct() operation as shown below: Note: when the Java Editor is active, press Ctrl+Shift+O to organize imports: in cases where multiple options are presented, ensure to import
com.oracle.ticketsystem.util.Utils, com.oracle.ticketsystem.util.TicketSystemException, com.oracle.ticketsystem.util.Adapter.
|
@WebMethod
public Product getProduct(
@WebParam(name="id")
long id) throws Exception {
getSpringService();
return springServ.getProduct( id );
}
|
- Change the signature and implementation of
getAllProducts() and
getProduct() operations to throw
TicketSystemException instead of
Exception class.
|
@WebMethod
public List<Product> getAllProducts()
throws TicketSystemException {
try {
getSpringService();
return springServ.getAllProducts( );
} catch (Exception e) {
throw Utils.getTicketSystemException("getAllProdcts operation failed", e);
}
}
@WebMethod
public Product getProduct(
@WebParam(name="id")
long id)
throws TicketSystemException {
try {
getSpringService();
return springServ.getProduct( id );
} catch (Exception e) {
throw Utils.getTicketSystemException("getProduct operation failed", e);
}
}
|
- The
getAllProducts() operation returns a
java.util.List of
Product JPA entity beans. Edit its signature to return a
ProductResultType JAXB type instead of the list of
Product JPA entity beans. Use the provided
Adapter helper class for converting the
java.util.List of
Product JPA entity bean to the
ProductResultType JAXB type.
|
@WebMethod
public
ProductResultType getAllProducts()
throws TicketSystemException {
try {
getSpringService();
List<Product> products = springServ.getAllProducts();
ProductResultType result = Adapter.adapt(products);
return result;
} catch (Exception e) {
throw Utils.getTicketSystemException("getAllProdcts operation failed", e);
}
}
|
- The
getProduct() operation returns the
Product JPA entity beans. Edit its signature to return a
ProductType JAXB type instead of the
Product JPA entity bean. Use the provided
Adapter helper class for converting the
Product JPA entity bean to the
ProductType JAXB type.
|
@WebMethod
public
ProductType getProduct(
@WebParam(name="id")
long id) throws TicketSystemException {
try {
getSpringService();
Product product = springServ.getProduct( id );
ProductType productType = Adapter.adapt(product);
return productType;
} catch (Exception e) {
throw Utils.getTicketSystemException("getProduct operation failed", e);
}
}
|
- Save the
ProductWebService class.
Edit the web service operation signature of
TicketWebService
- Open the
TicketWebService class.
- For each web service operation of
TicketWebService perform following steps:
Note: To save time either you can copy the provided
TicketWebService class from the
resources folder.
- Specify
@WebParam for each input argument of the web service operation.
- Change the signature and implementation of operations to throw a
TicketSystemException instead of
Exception class.
- Change the signature and implementation of the web service operations to return the JAXB type instead of the JPA entity bean.
- For the
add() ,
update() , and
get() opeations return the
TicketTypeJAXB type instead of
Ticket JPA entity bean
- For the
getTicketsOwnedByTechnician() , and
getOpenTickets() opeations return the
TicketResultType JAXB type instead of
java.util.List of the
Ticket JPA entity bean
- Use the provided
Adapter helper class for converting the JPA entity bean to the corresponding JAXB type.
Click the arrow below to navigate through the tutorial: