Friday, 22 January 2016

2. JAX-WS : Client Example

In continuation to previous JAX-WS example where we created GlobalWeatherService web service with one operation "getTemperatureOfCity" and then generated all portal artifacts using wsimport tool.
In this example, we will see how to invoke this web service using web service client.
Create java project in eclipse. Once created, import complete package in.blogspot.ashish4java.globalweatherservice and all classes from that package in this java project.

Create package in.blogspot.ashish4java.globalweatherservice.client

Once done, project structure will be as below,

Create class to invoke web service as below,
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package in.blogspot.ashish4java.globalweatherservice.client;

import java.util.Map;

import javax.xml.ws.BindingProvider;

import in.blogspot.ashish4java.globalweatherservice.CityNotFoundException_Exception;
import in.blogspot.ashish4java.globalweatherservice.CityTemperature;
import in.blogspot.ashish4java.globalweatherservice.CityTemperatureImplService;

public class MainClient {

 public static final String city = "Sydney";

 public MainClient() {
 }

 public static void main(String[] args) {
  final CityTemperatureImplService cityTempService = new CityTemperatureImplService();
  CityTemperature client = cityTempService.getCityTemperatureImplPort();

  Map<String, Object> reqContext = ((BindingProvider) client).getRequestContext();
  reqContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
    "http://localhost:8080/GlobalWeatherService/CityTemperature?wsdl");

  try {
   String temp = client.getTemperatureOfCity(city);
   System.out.println("Temperature of " + city + " is - " + temp);
  } catch (CityNotFoundException_Exception e) {
   System.out.println("City given is not found -" + e.getMessage());
  }

 }

}

Run this class which gives output successfully -
Temperature of Sydney is -15 Degree Celsius



In next tutorial, we will see how to use handlers to do simple authentication using credentials added to HTTPHeaders.

Saturday, 16 January 2016

1. JAX-WS : wsimport tool example

In this tutorial, we will explore into how to use JAX-WS top-bottom approach to generate JAX-WS portable artifacts once WSDL is finalised. Benefit with finalising "WSDL First" is multiple development team can work on same contract. so parallel development can be done. This would not be possible with bottom-up approach.

JAX-WS provides utilities to generate portable artifacts and web service client with wsimport tool. This tool have 2 purposes:


  1. Generates JAX-WS portable artifacts (Java files) for web service deployment.
  2. Generates web service client for client side development.
Details of different options wsimport command needs:

However , there is one disadvantage with top-bottom approach which is WSDL needs to be written from scratch. If you have complete web service with many operations then creating wsdl manually would be tedious job however there are tools available to create/generate wsdl too.

In this tutorial, we will use bottom-up approach to get wsdl generated first for us then will use that wsdl file/url to generate classes and web service client. 


Let's start with Service Implementation Class first. Create maven project based on CXF archetype as illustrated below,


Select below archetype,

Give artifactId name and click on finish:

This will give project structure as below:



Delete HelloWord.java, HellowWorldImpl.java and HellowWorldImplTest.java

Create SEI - CityTemperature:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package in.blogspot.ashish4java.GlobalWeatherService;

import javax.jws.WebMethod;
import javax.jws.WebService;

import in.blogspot.ashish4java.GlobalWeatherService.exception.CityNotFoundException;


/**
 * @author admin
 * Service Interface defines contract for getting particular city temperature and rain details. * 
 *
 */
@WebService
public interface CityTemperature {

 
    /**
     * Service operation to get temperature of particular city.
     * @param cityName - the name of city
     * @return String - temperature of city.
     * @throws CityNotFoundException - the exception if city name not found.
     */
    @WebMethod(operationName = "getTemperatureOfCity")
 String getCityTemperature(String cityName) throws CityNotFoundException;

 /**
  * @param cityName
  * @return
  * @throws CityNotFoundException
  */
 String getRainDetails(String cityName) throws CityNotFoundException;

}

Implement this interface by creating SIB:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package in.blogspot.ashish4java.GlobalWeatherService;

import javax.jws.WebMethod;
import javax.jws.WebService;

import in.blogspot.ashish4java.GlobalWeatherService.exception.CityNotFoundException;

/**
 * @author admin
 *
 */
@WebService(endpointInterface = "in.blogspot.ashish4java.GlobalWeatherService.CityTemperature",
   serviceName = "CityTemperatureService",
   portName = "CityTemperaturePort")
public class CityTemperatureImpl implements CityTemperature {

 @Override
 public final String getCityTemperature(final String cityName) throws CityNotFoundException {
  String temp = null;
  if ( cityName != null && "Sydney".equals(cityName) ) {
   temp = "15 Degree Celsius";
  } else {
   throw new CityNotFoundException("City name is not recognised");
  }
  return temp;  
 }

 @Override
@WebMethod(exclude = true)
public final String getRainDetails(final String cityName) { return "This operation is not implemented yet and that is why excluded from this service"; } }

Once done, update beans.xml -

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
 xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

 <import resource="classpath:META-INF/cxf/cxf.xml" />

 <jaxws:endpoint id="cityTemperature"
  implementor="in.blogspot.ashish4java.GlobalWeatherService.CityTemperatureImpl"
  address="/CityTemperature" />

</beans>

and then web application deployment descriptor web.xml:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">


<web-app>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>WEB-INF/beans.xml</param-value>
 </context-param>

 <listener>
  <listener-class>
   org.springframework.web.context.ContextLoaderListener
  </listener-class>
 </listener>

 <servlet>
  <servlet-name>CXFServlet</servlet-name>
  <display-name>CXF Servlet</display-name>
  <servlet-class>
   org.apache.cxf.transport.servlet.CXFServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>CXFServlet</servlet-name>
  <url-pattern>/*</url-pattern>
 </servlet-mapping>
</web-app>

Once done, deploy this webapp on tomcat server and then hit URL http://localhost:8080/GlobalWeatherService/


Note: operation "getRainDetails" is not listed as we have excluded that operation using @Webmethod.Exclude element in Service Implementation class.

WSDL is available at URL http://localhost:8080/GlobalWeatherService/CityTemperature?wsdl

Now, based on this wsdl using wsimport tool, generate portable artifacts and web service client.

D:\>wsimport -verbose -keep -s D:\generated\src -d D:\generated\bin http://localhost:8080/GlobalWeatherService/CityTemperature?wsdl
parsing WSDL...



Generating code...

in\blogspot\ashish4java\globalweatherservice\CityNotFoundException.java
in\blogspot\ashish4java\globalweatherservice\CityNotFoundException_Exception.java
in\blogspot\ashish4java\globalweatherservice\CityTemperature.java
in\blogspot\ashish4java\globalweatherservice\CityTemperatureImplService.java
in\blogspot\ashish4java\globalweatherservice\GetTemperatureOfCity.java
in\blogspot\ashish4java\globalweatherservice\GetTemperatureOfCityResponse.java
in\blogspot\ashish4java\globalweatherservice\ObjectFactory.java
in\blogspot\ashish4java\globalweatherservice\package-info.java

Compiling code...

javac -d D:\generated\bin -classpath D:\Java\jdk1.8.0_77/lib/tools.jar;D:\Java\jdk1.8.0_77/classes -Xbootclasspath/p:D:\Java\jdk1.8.0_77\jre\lib\rt.jar;D:\Java\jdk1.8.0_77\jre\lib\rt.jar D:\generated\src\in\blogspot\ashish4java\globalweatherservice\CityNotFoundException.java D:\generated\src\in\blogspot\ashish4java\globalweatherservice\CityNotFoundException_Exception.java D:\generated\src\in\blogspot\ashish4java\globalweatherservice\CityTemperature.java D:\generated\src\in\blogspot\ashish4java\globalweatherservice\CityTemperatureImplService.java D:\generated\src\in\blogspot\ashish4java\globalweatherservice\GetTemperatureOfCity.java D:\generated\src\in\blogspot\ashish4java\globalweatherservice\GetTemperatureOfCityResponse.java D:\generated\src\in\blogspot\ashish4java\globalweatherservice\ObjectFactory.java D:\generated\src\in\blogspot\ashish4java\globalweatherservice\package-info.java

D:\>

This has generated all classes which will be useful in creating web service client. This is end of tutorial and in next tutorial, we will see how to create web service client and call this web service.