Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Java Web Service: Top-Down Approach

DZone's Guide to

Java Web Service: Top-Down Approach

Web services can be created with either top-down or bottom-up development. Here's a look at top-down development with a Java web service.

Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Web services can be created using two methods: top-down development and bottom-up development.

In a top-down approach, we create the WSDL first and then generate the web service artifact using the tool available in JDK.

By creating the WSDL file first you will ultimately have more control over the web service, and can eliminate interoperability issues that may arise when creating a web service using the bottom-up method

Pre-requisite:

  • Java should be installed and JAVA_HOME and PATH Environment is set.
  • Any IDE of your preference. I used Eclipse.

We generate the web service artifact using the wsimport tool available in JDK.
https://docs.oracle.com/javase/6/docs/technotes/tools/share/wsimport.html

Usage: wsimport [options] <WSDL_URI>
where [options] include:

  -b <path>                 specify jaxws/jaxb binding files or additional schemas 
   (Each <path> must have its own -b)
  -B<jaxbOption>            Pass this option to JAXB schema compiler
  -catalog <file>           specify catalog file to resolve external entity references
                            supports TR9401, XCatalog, and OASIS XML Catalog format.
  -d <directory>            specify where to place generated output files
  -extension                allow vendor extensions - functionality not specified
                            by the specification.  Use of extensions may
                           result in applications that are not portable or
                            may not interoperate with other implementations
  -help                    display help
  -httpproxy:<host>:<port>  specify a HTTP proxy server (port defaults to 8080)
  -keep                    keep generated files
  -p <pkg>                  specifies the target package
  -quiet                    suppress wsimport output
  -s <directory>            specify where to place generated source files
  -target <version>         generates code as per the given JAXWS spec version
                            Defaults to 2.2, Accepted values are 2.0, 2.1 and 2.2
                            e.g. 2.0 will generate compliant code for JAXWS 2.0 spec
  -verbose                output messages about what the compiler is doing
  -version                  print version information
  -wsdllocation <location>  @WebServiceClient.wsdlLocation value
  -clientjar <jarfile>      Creates the jar file of the generated artifacts along with the
                           WSDL metadata required for invoking the web service.

We will try to create a web service which has one service (Weather Service) with one operation (GetCurrentTemperature) which  takes the City name as an input and returns the temperature.

Below the WSDL that was created to satisfy our purpose.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
 xmlns:tns="http://www.example.org/WeatherService/" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
name="WeatherService" 
targetNamespace="http://www.example.org/WeatherService/">
  <wsdl:types>
    <xsd:schema targetNamespace="http://www.example.org/WeatherService/">
      <xsd:element name="GetCurrentTemperatureRq">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="city" type="xsd:string"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="GetCurrentTemperatureRs">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="temperature" type="xsd:string"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="GetCurrentTemperatureRq">
    <wsdl:part element="tns:GetCurrentTemperatureRq" name="parameters"/>
  </wsdl:message>
  <wsdl:message name="GetCurrentTemperatureRs">
    <wsdl:part element="tns:GetCurrentTemperatureRs" name="parameters"/>
  </wsdl:message>
  <wsdl:portType name="WeatherServicePortType">
    <wsdl:operation name="GetCurrentTemperature">
      <wsdl:input message="tns:GetCurrentTemperatureRq"/>
      <wsdl:output message="tns:GetCurrentTemperatureRs"/>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="WeatherServiceSOAP" type="tns:WeatherServicePortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="GetCurrentTemperature">
      <soap:operation soapAction="http://www.example.org/WeatherService/GetCurrentTemperature"/>
      <wsdl:input>
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="WeatherService">
    <wsdl:port binding="tns:WeatherServiceSOAP" name="WeatherServiceSOAP">
      <soap:address location="http://localhost:80/WeatherServiceApp/WeatherService"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Create a below Folder structure anywhere in your hard drive.

Image title


Now create the WeatherService.wsdl file in the wsdl folder as created above.

Open Command  Prompt and make the above WeatherService folder as root.

Run the below command to create the Web service artifact.

. wsimport -d ./generated -s ./src -p learning.ocdjws.webservice ./wsdl/WeatherService.wsdl

Below files are generated.

Image title

Create a Java project in IDE of your choice and import the files that are generated in src folder

Now have a structure for our web service. We need to create an implementation for our web service. Create a Java class  WeatherServicePortImpl in learning.ocdjws.webservice package and implement the WeatherServicePort interface.

package learning.ocdjws.webservice;

import javax.jws.WebMethod;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService(name = "WeatherServicePort", targetNamespace = "http://www.example.org/WeatherService/")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class WeatherServicePortImpl implements WeatherServicePort {

@Override
@WebMethod(operationName = "GetCurrentTemperature", action = "http://www.example.org/WeatherService/GetCurrentTemperature")
@WebResult(name = "GetCurrentTemperatureRs", targetNamespace = "http://www.example.org/WeatherService/", partName = "parameters")
public GetCurrentTemperatureRs getCurrentTemperature(
GetCurrentTemperatureRq request) {
System.out.println(request.getCity());
ObjectFactory objectfactory = new ObjectFactory();
GetCurrentTemperatureRs response = objectfactory
.createGetCurrentTemperatureRs();
response.setTemperature(Math.random() * 100 + "Degree Celcius");
return response;
}

}

Deploying in JVM Embedded Server

We can publish our web service using Endpoint API  in javax.xml.ws.

JAX-WS RI Endpoint.publish API uses by default a light-weight HTTP server implementation that is included in Sun's Java SE 6.

Below class publishes our web service.

import javax.xml.ws.Endpoint;

public class WeatherServicePublish {

public static void main(String[] args) {
WeatherServicePortImpl implemtor= new WeatherServicePortImpl();
Endpoint.publish("http://localhost:80/WebServices/WeatherService", implemtor);
}
}

If everything goes fine we will be able to access our web service in below URL.

http://localhost/WebServices/WeatherService

Deploying in Web Container

We will now deploy the Web Service in web container. I used tomcat server.

Download and UnZip the JAXWS reference Implementation from https://jax-ws.java.net/2.2.10/

Create a Dyamaic Web Project in IDE of your Choice. And copy the Webservice artifact that are generated earlier using wsimport command and Implementation class to the src folder of new project.

Copy the all jar files from the lib folder(JAXWS RI Unzipped path) to WEB-INF\lib.

Open the web.xml and update the content as below.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>WeatherService</display-name>
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>
<servlet>
<servlet-name>WeatherService</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>WeatherService</servlet-name>
<url-pattern>/WeatherService</url-pattern>
</servlet-mapping>

</web-app>

For Information click WSServletContextListener and WSServlet links.

Create a file named sun-jaxws.xml in WEB-INF folder and update the endpoint details as below.

<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
version="2.0">
<endpoint name="WeatherService"
implementation="learning.ocdjws.webservice.WeatherServicePortImpl"
url-pattern="/WeatherService" />
</endpoints>

Build the war files and deploy in Tomcat server. Check the tomcat console of any errors.

If everything goes fine we will be able to access our web service in below URL.

http://localhost:8080/WeatherService/WeatherService

In the next article we will learn about Bottom-Up Approach.

Happy Learning !!!

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
web service tutorial in java

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}