SOAPNetBeans6
Creating SOAP Web Services with NetBeans 6
Contributed by Siegfried Bolz
In this document I will show you how easily you can create Web Services with NetBeans 6. In future postings I will discuss how to manipulate the SOAP Message before the Web Service Operation is called.
For this example I am using JAX-WS 2.1 with NetBeans 6.0.
Contents |
Web Services Description Language (WSDL)
There are many ways to get started with Web Services. One variant is beginning with the creation of the WSDL. First, you must know what the Web Service should do. You have to consider what is the input and output of each Web Service Operation. In our example we have only one Operation, named "getcalculateValues". The input consists of two numbers, and the result is only the sum of both.
Create these two files for our example: webservices.wsdl
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns:ns1="soapwebservices.jdevelop.eu" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns="http://schemas.xmlsoap.org/soap/encoding/" name="SOAPWebServices" targetNamespace="soapwebservices.jdevelop.eu">
<types>
<xsd:schema>
<xsd:import namespace="soapwebservices.jdevelop.eu" schemaLocation="webservices.xsd"/>
</xsd:schema>
</types>
<message name="calculateValues">
<part name="calculateValues" element="ns1:calculateValues"/>
</message>
<message name="calculateValuesResponse">
<part name="calculateValuesResponse" element="ns1:calculateValuesResponse"/>
</message>
<portType name="SOAPWebServices">
<operation name="getCalculateValues">
<input message="ns1:calculateValues"/>
<output message="ns1:calculateValuesResponse"/>
</operation>
</portType>
<binding name="SOAPWebServicesPortBinding" type="ns1:SOAPWebServices">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getCalculateValues">
<soap:operation soapAction="urn:http://blog.jdevelop.eu/services/getCalculateValues"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="SOAPService">
<port name="WebServices" binding="ns1:SOAPWebServicesPortBinding">
<soap:address location="http://blog.jdevelop.eu:80/services"/>
</port>
</service>
</definitions>
webservices.xsd
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:ns1="http://blog.jdevelop.eu/soapwebservices.xsd" xmlns:tns="soapwebservices.jdevelop.eu"
xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="soapwebservices.jdevelop.eu" version="1.0">
<xs:element name="calculateValues">
<xs:complexType>
<xs:sequence>
<xs:element name="value1" type="xs:decimal"/>
<xs:element name="value2" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="calculateValuesResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="result" type="xs:decimal"/>
<xs:element name="errormessage" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Create the NetBeans application
Start your NetBeans 6 and create a new "Web Application" Project.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws1.png
Name the project "SOAPWebServices", clear the "Context Path", and click "Finish".
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws2.png
Now go to File -> New File -> Web Services and choose "Web Service from WSDL". If this menu is missing, you need to install the “Web Service Plugin” (Tools -> Plugins -> Available Plugins).
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws3.png
Enter the Web Service Name “ServiceImpl“, use “eu.jdevelop.soapwebservices.service” as
the package-name and browse to the file “webservices.wsdl“, which you have created in the previous step.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws4.png
After pressing “Finish”, you will see this screen:
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws5.png
It’s now time to change the url-pattern. Open the file “sun-jaxws.xml” and exchange the url-pattern with “/soapwebservices“.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws6.png
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws7.png
Do the same with the file “web.xml“.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws8.png
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws9.png
Go to the file “index.jsp” and insert in the “body“-tag:
<jsp:forward page="soapwebservices"></jsp:forward>
Your Dummy Web Service is now ready for testing. Right-click on the project name and choose “Clean and Build“.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws11.png
After that, click “run“.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws12.png
Browse to the url “http://localhost:8084” to see the result.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws13.png
You can see the WSDL and the XML-Schema.
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws14.png
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws15.png
It’s now time to insert the business logic. Add the following Java classes to receive this package-structure:
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws16.png
ServiceImpl.java
package eu.jdevelop.soapwebservices.service;
import eu.jdevelop.soapwebservices.CalculateValues;
import eu.jdevelop.soapwebservices.CalculateValuesResponse;
import eu.jdevelop.soapwebservices.SOAPWebServices;
import eu.jdevelop.soapwebservices.wrapper.impl.CalculateValuesWrapper;
import javax.jws.WebService;
/**
* This is the Service-Implementation of the Web Service. Here are the
* operations which can be called from web clients.
*
* @author Siegfried Bolz
*/
@WebService(serviceName = "SOAPService", portName = "WebServices",
endpointInterface = "eu.jdevelop.soapwebservices.SOAPWebServices",
targetNamespace = "soapwebservices.jdevelop.eu", wsdlLocation = "WEB-INF/wsdl/ServiceImpl/webservices.wsdl")
public class ServiceImpl implements SOAPWebServices {
public CalculateValuesResponse getCalculateValues(CalculateValues calculateValues) {
try {
CalculateValuesWrapper wrapper = new CalculateValuesWrapper();
return wrapper.getResult(calculateValues);
} catch (Exception x) {
throw new IllegalStateException(x);
}
}
} // .EOF
ILogic.java
package eu.jdevelop.soapwebservices.logic;
/**
* Use this interface to create logic-implementations for
* each web service operation.
*
* @author Siegfried Bolz
*/
public interface ILogic<T, V> {
public T doAction(V var)
throws Exception;
} // .EOF
CalculateValuesLogic.java
package eu.jdevelop.soapwebservices.logic.impl;
import eu.jdevelop.soapwebservices.CalculateValues;
import eu.jdevelop.soapwebservices.CalculateValuesResponse;
import eu.jdevelop.soapwebservices.logic.ILogic;
import java.math.BigDecimal;
/**
* This implementation is normaly used for executing operations.
* Here we calculate some values.
*
* @author Siegfried Bolz
*/
public class CalculateValuesLogic implements ILogic<CalculateValuesResponse, CalculateValues>{
public CalculateValuesResponse doAction(CalculateValues var) throws Exception {
CalculateValuesResponse response = new CalculateValuesResponse();
try {
/**
* Simple addition of two values
*/
BigDecimal value1 = var.getValue1();
BigDecimal value2 = var.getValue2();
double sum = value1.doubleValue() + value2.doubleValue();
response.setResult(BigDecimal.valueOf(sum));
} catch (Exception x) {
/**
* On errors, return a valid bean with values. Do not send null!
*/
CalculateValuesResponse errorResponse = new CalculateValuesResponse();
errorResponse.setResult(BigDecimal.valueOf(0.0));
errorResponse.setErrormessage("An error has occurred!");
return errorResponse;
}
return response;
}
} // .EOF
IWrapper.java
package eu.jdevelop.soapwebservices.wrapper;
/**
* Use this interface to create wrapper-implementations for
* each web service operation.
*
* @author Siegfried Bolz
*/
public interface IWrapper<T, V> {
public T getResult(V var)
throws Exception;
} // .EOF
CalculateValuesWrapper.java
package eu.jdevelop.soapwebservices.wrapper.impl;
import eu.jdevelop.soapwebservices.CalculateValues;
import eu.jdevelop.soapwebservices.CalculateValuesResponse;
import eu.jdevelop.soapwebservices.logic.impl.CalculateValuesLogic;
import eu.jdevelop.soapwebservices.wrapper.IWrapper;
/**
* The wrapper calls the logic-implementation. Exchange or modify
* the wrapper if you want to use other logic-implementations.
*
* @author Siegfried Bolz
*/
public class CalculateValuesWrapper implements IWrapper<CalculateValuesResponse, CalculateValues>{
public CalculateValuesResponse getResult(CalculateValues var) throws Exception {
CalculateValuesLogic logic = new CalculateValuesLogic();
return logic.doAction(var);
}
} // .EOF
When you are finished, you should see something similar to the following in the Files View:
http://blog.jdevelop.eu/uploads/2008/02/netbeans_ws17.png
Testing
Download, install and start “soapui” from http://www.soapui.org. Import the soapui project file “SOAPWebServices-soapui-project.xml” (located in the example). Open “Request1” and submit the request (click the green arrow).
http://blog.jdevelop.eu/uploads/2008/02/soapui.png
Congratulations, your Web Service is now running!
Possible Problems
If you get the error:
Caused by: java.lang.LinkageError: JAXB 2.0 API is being loaded from the bootstrap classloader, but this RI (from jar: file:/C:/temp/SOAPWebServices/build/web/WEB-INF/lib/jaxb-impl.jar!/com/sun/xml/bind/v2/model/impl/ModelBuilder.class) needs 2.1 API. Use the endorsed directory mechanism to place jaxb-api.jar in the bootstrap classloader. (See http://java.sun.com/j2se/1.5.0/docs/guide/standards/)
This means that your JAX-WS version is newer than the JAXB 2.0 and JAX-WS 2.0 versions that are part of JDK 6. To solve this problem, just copy all JARs from $NETBEANS_HOME/java1/modules/ext/jaxws21/api/ to $TOMCAT_INSTALL_DIR/endorsed/ (the directory “endorsed” must be created if it doesn’t exist).
http://blog.jdevelop.eu/uploads/2008/02/endorsed_error.png
For further informations, look at http://wiki.netbeans.org/FaqEndorsedDirTomcat
Downloads
NetBeans 6 Project: download
