- Advance:
In a passed
post, you saw how to developan application using the “MethodTemplate” Design Pattern. Now we’re
going to develop a Service tier for this
Business tier developed in the past.
In this
post, you can find a running application to see how
the Service works, using a SOAP implementation built with the Apache cxf library and Jaxb Annotations
Rev: 6.
Also I would like to say, you can deploy this Service in an Application Server (I have selected Tomcat 7.0) and use SoapUI to send request to the Server (I have included a SoapUI Project in the SVN for that purpose)
- Explanation
We want to develop a Service Tier for an
Existing Business Tier, but we want to reutilize all the code previously
developed, also I don’t want to import the code as a jar or as an external Java
Project downloaded in the workspace. For that purpose, we have published the Business
Tier in the Maven Central Repository. Now you can download the project as a Maven Dependency and use it.
For the checkout of the code, you should know this example was developed as a Maven Project, under 1.7 JDK and Spring 3.0.
For this example I have selected Apache cxf because with a little set of Annotations you could develop a Service as follows
o API Tier
Object
|
Description
|
ManageVehicleRequest
|
This object, represent a request to consume the “manageVehicle” operation existing in the Vehicle Service.
|
ManageVehicleResponse
|
This object, represent a response from the Service
Vehicle after the “manageVehicle” operation has been finished
|
VehicleService
|
The definition of our Service including all the operations
we want to publish in our SOAP Architechture. In this case, we only have one
operation (manageVehicle)
|
o SERVICE Tier
Object
|
Description
|
VehicleServiceImpl
|
This is only the
implementation of our Service.
|
o CODE snapshots
VehicleService
|
@WebService(name = "VehicleService") public interface VehicleService { @WebMethod String getVersion(); @WebMethod ManageVehicleResponse manageVehicle(ManageVehicleRequest request); } |
As you can see, we only have to use two annotations,
the first one, is only to declare our Interface as a Service (with a concrete
name). The second annotation is used to indicate what methods must be
published within the Service
ManageVehicleRequest
|
@XmlType(name = "ManageVehicleRequest") @XmlSeeAlso({ EngineVehicleDTO.class, AnimalVehicleDTO.class }) public class ManageVehicleRequest implements Serializable { /** * */ private static final long serialVersionUID = 1144868850362615114L; private VehicleDTO vehicle; /** * @return the vehicle */ public VehicleDTO getVehicle() { return vehicle; } /** * @param vehicle * the vehicle to set */ public void setVehicle(VehicleDTO vehicle) { this.vehicle = vehicle; } } |
This object will be used to pass the information from
the outside to the Service. In this case we should include inside this object
a VehicleDTO instance.
It’s considered as a good practice to use the @XmlType annotation to give a name to our object. If you
don’t follow this tip, you are delegating in the framework the names for all
the XML elements within of the namespace used by the Service. And maybe you would
have errors at deployment time.
As you can see, VehicleDTO
is a parent object of EngineVehicleDTO and AnimalVehicleDTO, our operation has to work with these
child objects, this is the purpose followed by the @XmlSeeAlso
annotation. This annotation says to the framework that at deployment time,
these objects must be part of the WSDL. If you don’t use that annotation, you
only could send instances from VehicleDTO.
ManageVehicleResponse
|
package gazpachito.examples.services.cxf.vehicle.api.response; import java.io.Serializable; import javax.xml.bind.annotation.XmlType; @XmlType(name = "ManageVehicleResponse") public class ManageVehicleResponse implements Serializable { /** * */ private static final long serialVersionUID = -7879894326252286663L; private String errorMessage; /** * @return the errorMessage */ public String getErrorMessage() { return errorMessage; } /** * @param errorMessage * the errorMessage to set */ public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } } |
This object will be used to return the information from
the Service to the outside. In this case
we only just want to pass an error message, but in
fact, we could return whatever you want, collections or a complex object
maybe (with the exception of Maps)
VehicleServiceImpl
|
public class VehicleServiceImpl implements VehicleService { @Autowired private VehicleFacade vehicleFacadeImpl; @Override public String getVersion() { String version = ResourceBundle.getBundle("vehicle").getString( "vehicle.version"); return version; } @Override public ManageVehicleResponse manageVehicle(ManageVehicleRequest request) { ManageVehicleResponse response = new ManageVehicleResponse(); if (request != null && request.getVehicle() != null) { VehicleEnum template = null; if (request.getVehicle() instanceof AnimalVehicleDTO) { template = VehicleEnum.ANIMAL; } else if (request.getVehicle() instanceof EngineVehicleDTO) { template = VehicleEnum.ENGINE; } try { this.vehicleFacadeImpl.manageVehicle(request.getVehicle(), template); } catch (FacadeException e) { response.setErrorMessage(e.getMessage()); } } return response; } |
This is the implementation of our service. As you can see, I only have used a Spring annotation to inject the facade
developed in other post. And we only need to make an implementation for the
two operations publisheds in the Interface VehicleService.
About the “getVersion” method, just return the version extracted from a properties file (using the ${project} variable inside this properties file). The “manageVehicle” method only validate the input from the outside before this information sent to Facade
About the “getVersion” method, just return the version extracted from a properties file (using the ${project} variable inside this properties file). The “manageVehicle” method only validate the input from the outside before this information sent to Facade
-
Conclusions
As you can see, using
a little set of JAXB annotations, we can develop a WebService
based in a SOAP Architecture. In this post I only have
introduced enough annotations to show you how to develop a Service in an easy
way, but you can use more JAXB annotations and different combinations between
them to go further.
But this framework has a weakness. You have to write a little of XML in a configuration file to define the endpoint of all your Services (at least in the version chosen for this example). So you can’t forgive the configuration files and the configuration of the endpoint sometimes is a hard task.
No comments:
Post a Comment