Java

SOAP Webservices with Maven, Webservice

This is the fourth part in the series about SOAP Webservices with Maven. It continues after SOAP Webservices with Maven, Contract first

Now that the basics are all there, it is time to create the actual web service. This is a class which represents the actual endpoint of the SOAP call. Like the other parts, this isn’t a particularly complex piece of code but there are a few key things to keep in mind.

@WebService
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class Calculator {
    @WebMethod
    public BigDecimal add(AddValuesRequest request) {
        return request.getA().add(request.getB());
    }
}

Class-level

Here we have two annotations on the class level. The first, WebService, marks the class as a web service. The web server will detect this annotation and automatically set up an service which can be called by the class name.

The second annotation, SOAPBinding, tells the web server this is a SOAP web service uses the BARE parameter style. This one is needed because otherwise the web server will expect additional classes. It would then need a wrapper class per method. This is not necessary and not preferred.

Method-level

The annotation on the method level, WebMethod, tells the web server this is an actual endpoint method. This method will show up as a procedure in the generated WSDL.

Advanced annotation settings

Aside from what is shown here, both the WebService and the WebMethod annotation have a lot more options. There is also a WebResult and a WebParam annotation which can be used on the method. These will be covered in a later part of this tutorial.

WAR generation

Now that the actual web service is also available, it is time to do another mvn clean install. This time, it will result in a war file which will contain an actual web service. This war file can then be deployed to the web server. Once this is done, it is possible to call the actual web service in the browser.

This should result in the following result in the browser:

Web Services

EndpointInformation
Service Name{http://soap.tutorials.coding.ractoc.com/}CalculatorImplService Addresshttp://localhost:8080/soap-0.0.1-SNAPSHOT/calculator
Port Name{http://soap.tutorials.coding.ractoc.com/}CalculatorImplPort WSDLhttp://localhost:8080/soap-0.0.1-SNAPSHOT/calculator?wsdl:
Implementation class com.ractoc.coding.tutorials.soap.CalculatorImpl

The actual entries in the right table would off course depend on your precise code.

When you click on the WSDL link, you will get the WSD. This document described the actual web service and can be used to generate the client code.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3-b02-. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3-b02-. -->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:tns="http://soap.tutorials.coding.ractoc.com/"
   	     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	     xmlns="http://schemas.xmlsoap.org/wsdl/"
	     targetNamespace="http://soap.tutorials.coding.ractoc.com/"
	     name="CalculatorImplService">
	<types>
		<xsd:schema>
			<xsd:import namespace="http://soap.tutorials.coding.ractoc.com/" schemaLocation="http://localhost:8080/soap-0.0.1-SNAPSHOT/calculator?xsd=1"></xsd:import>
		</xsd:schema>
		<xsd:schema>
			<xsd:import namespace="http://coding.ractoc.com/tutorials/calculator" schemaLocation="http://localhost:8080/soap-0.0.1-SNAPSHOT/calculator?xsd=2"></xsd:import>
		</xsd:schema>
	</types>
	<message name="add">
		<part name="add" element="tns:add"></part>
	</message>
	<message name="addResponse">
		<part name="addResponse" element="tns:addResponse"></part>
	</message>
	<portType name="CalculatorImpl">
		<operation name="add">
			<input message="tns:add"></input>
			<output message="tns:addResponse"></output>
		</operation>
	</portType>
	<binding name="CalculatorImplPortBinding" type="tns:CalculatorImpl">
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
		<operation name="add">
			<soap:operation soapAction=""></soap:operation>
			<input>
				<soap:body use="literal"></soap:body>
			</input>
			<output>
				<soap:body use="literal"></soap:body>
			</output>
		</operation>
	</binding>
	<service name="CalculatorImplService">
		<port name="CalculatorImplPort" binding="tns:CalculatorImplPortBinding">
			<soap:address location="http://localhost:8080/soap-0.0.1-SNAPSHOT/calculator"></soap:address>
		</port>
	</service>
</definitions>

At the top of the WSDL are two imports. These import the generated XSD files. This is an important point. These XSD files are generated by the web server based on the class files. These class file were in turn generated based on the XSD files you have written. This extra step in code generation is an important one. The reason this is an important step is that certain things get lost in all these code generation steps. For instance, when you have written some nice restrictions in you own XSD files, these will not end up in the Java code. They will also not end up in the generated XSD files. This problem can be remedied to a certain extent though. This will be covered in a later part of the tutorial.

This tutorial continuous in the next part of the series, SOAP webservices with Maven, Client creation