Web App Next Stop In Our Software Journey - REST Services: Part III
We are almost done with this release of our REST service wrapper to the Shape Calculator.
Join the DZone community and get the full member experience.
Join For FreeGreetings. We are almost done with this release of our REST service wrapper to the Shape Calculator. In Part 2, we were able to invoke every operation of the calculator using the SOAPUI testing tool with XML as the request and response format.
Today, let's do the same with JSON and then finish by merging the SOAP service (see previous articles) into this REST web app.
Start.WADL.SOAPUI.Test
I am being brief since this is Part 3 and we have done several iterations. Make sure MySQL is running. Grab the latest WADL and plop it into SOAPUI, and then let's run the GET /pending
again. However, we need to set up to request JSON, so we add an "accept" header.
We were able to invoke the desired operation, but of course, CXF doesn't know how to respond back to us.
We Need a Provider
POM
I chose Jackson. Add this to the project POM:
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.8.1</version>
</dependency>
WebServiceContext
And add the following:
@Bean
public ShapeCalculatorWebService shapeCalculatorWebServiceImpl() {
logger.debug("\n\n\n\nWebServiceContext shapeCalculatorWebServiceImpl \n\n\n\n");
return new ShapeCalculatorWebServiceImpl();
}
And we need to add the provider to the jaxRsServer() method that we started with back in Part 1:
@Bean
@DependsOn("cxf")
public Server jaxRsServer() {
logger.debug("\n\n\n\nWebServiceContext JaxRsServer \n\n\n\n");
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
factory.setServiceBean(shapeCalculatorWebServiceImpl());
factory.setAddress("/shapecalc");
factory.setProvider(jsonProvider());
logger.debug("\n\n\n\nEND OF WebServiceContext JaxRsServer \n\n\n\n");
return factory.create();
}
An interesting observation: there are no annotations required to handle JSON, other than the @GET
, @PUT
, @DELETE
, and @PATH
.
Update.Build.Deploy.Start.WADL.SOAPUI.Test
Let's re-try the @GET /pending
with both JSON and XML.
Here is a @PUT /pending
with JSON:
And that's it. Our last TO-DO is to merge SOAP and REST.
Add SOAP Service
Back in Part 1 of the articles on this REST service, there are links to the previous SOAP services we've developed. I will just be taking pieces from those.
First, we add the CXF JAX-WS dependency and update.
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
Then, we add the JAX-WS Endpoint to the WebServiceContext.
@Bean
public Endpoint endpoint() {
logger.debug("\n\n\n\nWebServiceContext endpoint \n\n\n\n");
EndpointImpl endpoint = new EndpointImpl(cxf(), shapeCalculatorWebServiceImpl());
endpoint.publish("/ShapeCalculatorWebService");
return endpoint;
}
Now, we need to be able to distinguish whether SOAP or REST in the URL, so let's make a modification to the jaxRsServer() and the endpoint().
Here we are prior to any change:
...and then after:
Finally, we need to add the following to the SEI and the implementation:
Update.Build.Deploy.Start.Test
We use the WSDL and WADL links in SOAPUI:
Test Get Pending
Let's execute the operations to get pending requests for REST (XML & JSON) and for SOAP:
Looks good.
Test Queue Calculation
The @PUT /pending
test for JSON looks good:
...and the @PUT /pending
test for XML looks good...
...however, I am not happy with the SOAP request:
I see <!--Optional:-->
, and <arg0>
and the parameters are not in the order I wanted. Let's see if we can't improve some of this.
Changes to QueueCalculationParms
Build.Deploy.Start.WSDL.Test
We get a fresh copy of the WSDL and create a new SOAP project in SOAPUI. Try our test.
Notice that the order changed to how we want. However, if you want to guarantee this, we need to do something else. While we're at it, let's do something about the <!--Optional:-->
.
More Changes to QueueCalculationParms
Build.Deploy.Start.WSDL.Test
We get a fresh copy of the WSDL and create a new SOAP project in SOAPUI. Try our test.
Looks much better. We're getting there. We still have the <!--Optional:-->
in one place, and the <arg0>
.
This Time, the Change Is in ShapeCalculatorWebService
We add this to the interface's queue operation...
Wash.Rinse.Repeat.
We get a fresh copy of the WSDL and create a new SOAP project in SOAPUI. Try our test.
Looks much better... we are getting there... we removed the <arg0>
but still have the remaining <!--Optional:-->
.
Final Round of Changes and Test
Looks good.
Latest Code
You can get the latest code to this project here. You can get the child project (Shape Calculator) here.
Coming Up Next
We have completed our next iteration of web services. We'll be returning to them again as we begin to develop clients that use them.
To continue our make-believe story about the journey of progression that you have been on with what began as a very humble, simple code to perform some shape calculations....
So far in our series of articles, you have delivered different applications wrapping and exposing the Shape Calculator:
A command-line application, tightly coupled to the calculator.
A web application, tightly coupled.
A SOAP service (bottom-up, code-first).
Another SOAP service (top-down, WSDL-first).
A REST and SOAP service, providing JSON and XML as well as the SOAP.
Since other departments are beginning to take a look at these, you have decided to develop some web-application clients to connect to the services. This is where we begin next time. See you in the next article!
Opinions expressed by DZone contributors are their own.
Comments