Showing posts with label SOAP. Show all posts
Showing posts with label SOAP. Show all posts

Friday, February 28, 2014

Apache CXF Spring Integration Example

Apache CXF is a robust web service framework written in java that fully supports for the Spring based web service development. the purpose of this article is to share my experience on Apache CXF web service development on Spring framework. this example has been well tested with SoapUI.

the project structure will be as follows.




pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.chathurangaonline.apache.cxf.jaxws.spring.samples</groupId>
    <artifactId>apache-cxf-jaxws-spring-sample</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>apache-cxf-jaxws-spring-sample Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <cxf.version>3.0.4</cxf.version>
        <spring.version>4.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>apache-cxf-jaxws-spring-sample</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>



CalculatorService.java


package com.chathurangaonline.apache.cxf.jaxws.spring.samples;

import javax.jws.WebService;

/**
 * <p>
 *     SIB
 * </p>
 * @author Chathuranga Tennakoon / www.chathurangaonline.com
 */
@WebService
public interface CalculatorService {

    double multiply(double num1,double num2);
}



CalculatorServiceImpl.java


package com.chathurangaonline.apache.cxf.jaxws.spring.samples.impl;

import com.chathurangaonline.apache.cxf.jaxws.spring.samples.CalculatorService;
import javax.jws.WebService;

/**
 * <p>
 *     SIB for {@link com.chathurangaonline.apache.cxf.jaxws.spring.samples.CalculatorService}
 * </p>
 * @author Chathuranga Tennakoon / www.chathurangaonline.com
 */
@WebService
public class CalculatorServiceImpl implements CalculatorService {

    @Override
    public double multiply(double num1, double num2) {
        return num1 * num2;
    }
}



web.xml


<!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>
  <display-name>Archetype Created Web Application</display-name>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext.xml</param-value>
    </context-param>

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

    <servlet>
        <servlet-name>AppCXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>AppCXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>


applicationConxtext.xml


<?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"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>

    <jaxws:endpoint id="calServiceEndpoint"
                    implementor="com.chathurangaonline.apache.cxf.jaxws.spring.samples.impl.CalculatorServiceImpl"
                    address="/calcService"/>

</beans>



Once the web service is successfully deployed on web server(in my case it is tomcat), you can access the WSDL from following url.

http://localhost:8080/apache-cxf-jaxws-spring-sample/calcService?wsdl


The source code can be downloaded at:-
Get Source code From GitHub


Thanks
Chathuranga Tennakoon
www.chathurangaonline.com





Apache CXF First JAX-WS (SOAP Web Service) Example (CXFNonSpringServlet)

The most of the people think that the Apache CXF supports only to develop Spring based Web Services. this is NOT true. is supports to build both Spring based and Non spring based web services.

1. CXFServlet -  this will support for the Spring based web services.
2. CXFNonSpringServlet -  this will support for the non spring web services.


the purpose of this article is to demonstrate how to develop non spring based web service with Apache CXF. i have already developed and  tetsed the service with SoapUI. i am just sharing the source code for your reference.

the project structure looks as below.,


pom.xml



<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.chathurangaonline.apache.csf.jax.ws.samples</groupId>
    <artifactId>apache-cxf-jaxws-sample</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>apache-cxf-jaxws-sample Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <cxf.version>3.0.4</cxf.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>compile</scope>
        </dependency>

    </dependencies>
    <build>
        <finalName>apache-cxf-calculator-service</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <!--compiles with java 7-->
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <!--WAR plugin-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.5</version>
            </plugin>
        </plugins>
    </build>
</project>



CalculatorService.java

the following is the Service Endpoint Interface(SEI).

package com.chathuranga.apache.cxf.jax.ws.samples;

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

/**
 * <p>
 *     SEI
 * </p>
 * @author Chathuranga Tennakoon / www.chathurangaonline.com
 */
@WebService
public interface CalculatorService {

    @WebMethod
    double addNumbers(double num1,double num2);
}
 



CalculatorServiceImpl.java

the following is the Service Implementation Bean (SIB)

package com.chathuranga.apache.cxf.jax.ws.samples.impl;

import com.chathuranga.apache.cxf.jax.ws.samples.CalculatorService;
import javax.jws.WebMethod;
import javax.jws.WebService;

/**
 * <p>
 *     SIB for {@link com.chathuranga.apache.cxf.jax.ws.samples.CalculatorService}
 * </p>
 * @author Chathuranga Tennakoon / www.chathurangaonline.com
 */
@WebService
public class CalculatorServiceImpl implements CalculatorService {

    @WebMethod
    public double addNumbers(double num1, double num2) {
        return num1 + num2;
    }
}



AppCXFNonSpringServletImpl.java

the custom implementation for the CXFNonSpringServlet.

package com.chathuranga.apache.cxf.jax.ws.samples.impl;

import org.apache.cxf.frontend.ServerFactoryBean;
import org.apache.cxf.transport.servlet.CXFNonSpringServlet;
import javax.servlet.ServletConfig;

/**
 * <p>
 *    Application Specific Custom Implementation for the {@link org.apache.cxf.transport.servlet.CXFNonSpringServlet}
 * </p>
 * @author Chathuranga Tennakoon / www.chathurangaonline.com
 */
public class AppCXFNonSpringServletImpl extends CXFNonSpringServlet{

    @Override
    public void loadBus(ServletConfig servletConfig){
        super.loadBus(servletConfig);
        ServerFactoryBean factory = new ServerFactoryBean();
        factory.setBus(bus);
        factory.setServiceClass(CalculatorServiceImpl.class);
        factory.setAddress("/calcService");
        factory.create();
    }
} 


web.xml

<web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Archetype Created Web Application</display-name>
    <servlet>
        <servlet-name>AppCXFNonSpringServlet</servlet-name>
        <servlet-class>com.chathuranga.apache.cxf.jax.ws.samples.impl.AppCXFNonSpringServletImpl</servlet-class>
    </servlet>

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



Source code can be downloaded at :- https://github.com/chathurangat/apache-cxf-jax-ws-first-service


Chathuranga Tennakoon
www.chathurangaonline.com
chathuranga.t@gmail.com

Friday, February 14, 2014

JAX-WS Web Service with SOAP 1.2

JAX-WS uses the SOAP 1.1 for the Web Services if the SOAP version is not explicitly defined (By Default). this is the default behavior.  if you want to use SOAP 1.2 for your web service, then you may need to explicitly declare it in the web service. then following annotation can be used to explicitly define the SOAP version of the web service.

For SOAP 1.2

@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING) 


Sample Java Implementation

package com.chathurangaonline.sample.jaxws;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.xml.ws.soap.SOAPBinding;

/**
 * <p>
 *     Service Implementation Bean (SIB) for CalculatorService endpoint interface
 * </p>
 */
@WebService
@BindingType(value = SOAPBinding.SOAP12HTTP_BINDING)
public class CalculatorServiceImpl implements CalculatorService{


    @WebMethod
    public long add(long number1, long number2) {
        return number1+number2;
    }

    @WebMethod
    public long subtract(long number1, long number2) {
        return number1+number2;
    }

    @WebMethod
    public long multiply(long number1, long number2) {
        return number1*number2;
    }
}
 
Hope this will be helpful for you!

Thanks and Regards

Chathuranga Tennakoon
www.chathurangaonline.com

Wednesday, February 12, 2014

How to Determine the SOAP Version of a Message

References :- http://wso2.com/library/articles/differentiating-between-soap-versions-looking-soap-message/


Thanks Mr. Eran Chinthaka for the Nice Article!

Thursday, January 16, 2014

JAX-WS (SOAP Web Services) with JAXB

JAXB - Java Architecture for XML Binding. support for marshalling and unmarshalling.

marshalling :- converting java objects to XML files/contents

unmarshalling :- converting XML contents back to the java objects


here i have develop a sample application to demonstrate simple java web service with JAXB support.

you can get the fully source code of the project with following gitHub Repo.

https://github.com/chathurangat/jax-ws-jaxb-sample-app


this is just a sample implementation with some hard coded values in the back-end.


WebService

Employee.java

package com.chathurangaonline.samples.jax.ws.jaxb.model;

public class Employee {

    private int id;
    private String empId;
    private String name;
    private String email;
    private String website;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEmpId() {
        return empId;
    }

    public void setEmpId(String empId) {
        this.empId = empId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }
}




EmployeeService.java

package com.chathurangaonline.samples.jax.ws.jaxb;

import com.chathurangaonline.samples.jax.ws.jaxb.model.Employee;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface EmployeeService {

    @WebMethod
    Employee create(Employee employee);

    @WebMethod
    Employee findEmployeeById(String empId);
}




EmployeeServiceImpl.java

package com.chathurangaonline.samples.jax.ws.jaxb;

import com.chathurangaonline.samples.jax.ws.jaxb.model.Employee;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;


@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class EmployeeServiceImpl implements EmployeeService{

    @WebMethod
    public Employee create(Employee employee) {
        //todo sample implementation
        if(employee!=null && employee.getEmail()!=null && employee.getEmail().equals("chathuranga.t@gmail.com")){
            employee.setEmpId("emp4235");
            employee.setName("chathuranga tennakoon");
            employee.setWebsite("www.chathurangaonline.com");
        }
        return employee;
    }

    @WebMethod
    public Employee findEmployeeById(String empId) {
        //todo sample implementation
        if(empId!=null && empId.equals("emp4235")){
            Employee employee = new Employee();
            employee.setId(123);
            employee.setEmpId("emp4235");
            employee.setName("chathuranga tennakoon");
            employee.setWebsite("www.chathurangaonline.com");
            employee.setEmail("chathuranga.t@gmail.com");
        }
        Employee employee = new Employee();
        employee.setName("chathuranga tennakoon");
        return employee;
    }
}




web.xml

<!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>
  <display-name>Archetype Created Web Application</display-name>

    <listener>
        <listener-class>
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>empService</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>empService</servlet-name>
        <url-pattern>/empServiceUrl</url-pattern>
    </servlet-mapping>
</web-app>





sun-jaxws.xml

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
        xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
        version="2.0">
    
    <endpoint name="empService" 
              implementation="com.chathurangaonline.samples.jax.ws.jaxb.EmployeeServiceImpl" 
              url-pattern="/empServiceUrl"/>
</endpoints>




pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.chathurangaonline.jax.ws.samples</groupId>
    <artifactId>jaxb-sample-web-service</artifactId>
    <packaging>war</packaging>
    <version>1.0</version>
    <name>jaxb-sample-web-service Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <finalName>employee-service</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <!--compiles with java 7-->
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
            <!--WAR plugin-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.5</version>
            </plugin>
        </plugins>
    </build>
</project>








WebClient

web client can be generated with the wsimport tool. the sample command is as follows. replace the value with your configurations.

wsimport  -keep  -verbose -d /home/chathuranga/Projects/jax-ws-tutorial/jax-ws-jaxb-sample-app/webClient/jaxb-client/src/main/java/  http://localhost:8080/employee-service/empServiceUrl?wsdl


EmpServiceClient.java


import com.chathurangaonline.samples.jax.ws.jaxb.Employee;
import com.chathurangaonline.samples.jax.ws.jaxb.EmployeeServiceImpl;
import com.chathurangaonline.samples.jax.ws.jaxb.EmployeeServiceImplService;

/**
 * <p>
 *     sample web service client implementation
 * </p>
 * 
 * @Author Chathuranga Tennakoon
 */
public class EmpServiceClient {

    public static void main(String[] args) {

        EmployeeServiceImplService employeeServiceImplService = new EmployeeServiceImplService();
        EmployeeServiceImpl employeeService = employeeServiceImplService.getEmployeeServiceImplPort();

        //creating the employee
        Employee employeeOb = new Employee();
        employeeOb.setEmail("chathuranga.t@gmail.com");

        Employee employeeCreated = employeeService.create(employeeOb);

        System.out.println(" employee created  ["+employeeCreated.getEmpId()+"]");

        //find the employee with id
        Employee employee = employeeService.findEmployeeById("emp4235");

        System.out.println(" employee found ["+ employee.getName()+"]");
    }
}






hope this will be helpful for you!


Thanks
Cahthuranga Tennakoon
www.chathurangaonline.com


Saturday, November 2, 2013

Application Authentication for JAX-WS web services

 the fully source code for this example can be found at  following gitHub repository.

Download code From GitHub

clone the project from gitHub and use the maven to build the project.
then deploy the web service in the tomcat server. (just copy the war file and i have already done the required web.xml and sun-haxws.xml configurations.)

if you want  to know, how to deploy the web service in tomcat, you can refer my previous blog post here

once the web service is deployed, you can run the web service client to test the web service and see how it works.


In application authentication, then authentication logic will be implemented there in the web service. therefore the web service will be responsible for handling the user authentication.

the web service client will send the user credentials (username and password) to the web service. please refer the following WebService Client.


package com.chathurangaonline.jaxws.samples.client;

import com.chathurangaonline.jaxws.samples.impl.*;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class WebServiceClientImpl {

    public static void main(String [] args){

        CalculatorServiceImplService calculatorServiceImplService = new CalculatorServiceImplService();
        CalculatorServiceImpl calculatorService = calculatorServiceImplService.getCalculatorServiceImplPort();

        Map<String, Object> req_ctx = ((BindingProvider)calculatorService).getRequestContext();
        Map<String, List<String>> headers = new HashMap<String, List<String>>();

        //setting up the username and password 
        headers.put("Username", Collections.singletonList("chathuranga"));
        headers.put("Password", Collections.singletonList("chathu@123"));
        req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);

        //in order to invoke the add method, you need to have valid login credentials
        double answer =  calculatorService.add(45,10);
        System.out.println(" answer is ["+answer+"]");
    }
}


The web service will extract the user login credentials (username and password) from the HTTP Request Headers and  will perform the user authentication.
(here we have hard coded the username and password for the demostration purpose and to make it more simple. in the production mode, you need to move then  database) 
 if the user authentication is successful, he will be able to access the web service. otherwise it will throw a HttpException as implemented.  refer the following web service implementation.


package com.chathurangaonline.jaxws.samples.impl;

import com.chathurangaonline.jaxws.samples.CalculatorService;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPException;
import java.util.List;
import java.util.Map;


@WebService
public class CalculatorServiceImpl implements CalculatorService{

    @Resource
    private WebServiceContext webServiceContext;

    @Override
    public double add(double num1, double num2) {
        //todo username and password was hardcoded only for the demonstration purpose. this should be configured to look up from database or somewhere else
        if(isAuthenticated("chathuranga","chathu@123")){
            //allowing the operation for the authenticated user
            return num1 + num2;
        }
        else{
            //non-authenticated user.
            throw  new HTTPException(401);
        }
    }

    @Override
    public double multiply(double num1, double num2) {
        return num1 * num2;
    }


    /**
     * <p>
     *     method for checking the application level authentication using the username and password provided.
     * </p>
     * @param username - username provided as {@link java.lang.String}
     * @param password - password provided as {@link java.lang.String}
     * @return {@link java.lang.Boolean} (true if user authenticated, otherwise false)
     */
    private boolean isAuthenticated(String username, String password){
        if(username!=null && password!=null){
            MessageContext messageContext = webServiceContext.getMessageContext();
            Map httpHeaders  = (Map) messageContext.get(MessageContext.HTTP_REQUEST_HEADERS);

            List usernameList  = (List) httpHeaders.get("username");
            List passwordList = (List) httpHeaders.get("password");

            if((usernameList!=null && usernameList.contains(username)) && (passwordList!=null && passwordList.contains(password))){
                return true;
            }
        }
        return false;
    }
}


The main problem with Application Authentication is the mix of security logic with the business logic might mess the code. it add some unnecessary complexity for the code with tight coupling. as a solution for this, we can go for the Container Managed Authentication and that will be my next blog post ;)

Thanks
Chathuranga Tennakoon
chathuranga.t@gmail.com

Monday, September 30, 2013

How to generate JAX-WS client and integrate with client application

 my previous post explained about  how to deploy the web service in the tomcat web server.   So, our web service is up and running now. it is time to create/generate the web service client and integrate it with our application.

  we can generate the Web Service client from the WSDL file. wsimport utility will help to generate java based web service client from the given WSDL.So in our scenario, we can generate the web service client with following linux command.

wsimport  -keep  -verbose  -d <directory_to_create_web_service_client>  <wsdl_url>

-verborse (print the status of the operation being  executed to the terminal)
 -d  (path to the directory where the web service client should be created)

 wsimport  -keep  -verbose -d /home/chathuranga/java/jax-ws/client  http://localhost:8080/calculator-service/calcServiceUrl?wsdl 


now we have successfully completed the process of generating the web service client. it can be integrated with your application now.

The source code for the complete example can be found at following github url.


Hope this will helpful for you!

Cheers
Chathuranga Tennakoon
chathuranga.t@gmail.com






Thursday, September 26, 2013

Deploy JAX-WS web service in Tomcat Server

if the web service is going to be deployed in the tomcat server,it has to be developed as a web application project with some added configurations.
in order to start the web application project, i prefer to use maven archetype generate command as follows.

mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp


then it will give me a basic web application project that can be built with maven.
now this is the time to integrate my predefined web service with the web application project.

1. first create the relevant package structure in the web-app project and copy the web service src files there.


2. create the web service deployment descriptor ( sun-jaxws.xml ) file under the webapp/WEB-INF directory. (same directory where the web.xml resides).
 the endpoints should be defined as follows.

<?xml version="1.0" encoding="UTF-8"?>

<endpoints
        xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
        version="2.0">
    <endpoint
            name="calcService"     
            implementation="com.chathurangaonline.jaxws.samples.impl.CalculatorServiceImpl"

            url-pattern="/calcServiceUrl"/>
</endpoints>




3. in web.xml file (standard deployment descriptor) defines the WSServletContextListener and WSServlet class as follows.

<!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>

  <display-name>Archetype Created Web Application</display-name>

   <listener>
      <listener-class>
            com.sun.xml.ws.transport.http.servlet.WSServletContextListener
       </listener-class>
    </listener>

    <servlet>
        <servlet-name>calcService</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>calcService</servlet-name>
        <url-pattern>/calcServiceUrl</url-pattern>
    </servlet-mapping>

</web-app>



3.  if you do all the above steps correctly, you project structure should be as follows.




now it is the time to build the web service. since the web service is published in the tomcat server, it should be built as a WAR file similar to simple web app.



4.  once the web service is compiled and package, copy the WAR file to the webapps directory in the tomcat server.


5. sometimes the web service not be loaded because the tomcat does not have the required libraries to server for web services (By default, Tomcat does not comes with any JAX-WS dependencies). In that case you need to download those dependencies and copy to the “${Tomcat}/lib” directory.

  •  Go here http://jax-ws.java.net/
  • Download JAX-WS RI distribution.
  • Unzip it and copy following JAX-WS dependencies to Tomcat library folder “{$TOMCAT}/lib“.
    • jaxb-impl.jar
    • jaxws-api.jar
    • jaxws-rt.jar
    • gmbal-api-only.jar
    • management-api.jar
    • stax-ex.jar
    • streambuffer.jar
    • policy.jar

once the above depdencies are copied, restart the tomcat server and try to access the web serice with following URL.

http://localhost:8080/calculator-service/calcServiceUrl

if the web service is working, it should display the following page in the browser.
then we are done.




Summary

the all steps taken for publishing a web service in tomcat can be summarized as below.
  1. Create a web service
  2. Create a sun-jaxws.xml, defines web service implementation class.
  3. Create a standard web.xml, defines WSServletContextListener, WSServlet and structure of a web project
  4. Copy JAX-WS dependencies to “${Tomcat}/lib” directory.
  5. Generate WAR file and copy to “${Tomcat}/webapp” directory.
  6. access the web service from browser and check whether it is up and running.


 SOURCE CODE : - https://github.com/chathurangat/jaxws-calculator-service-webapp

Hope this might be helpful for you!

Cheers
Chathuranga Tennakoon


Thursday, September 19, 2013

Simple JAX-WS Webservice - Calculator Implementation

First we will create a Simple JAX-WS Web Service. if you do not know how to create such web service, you can refer my previous article that describes how to develop simple JAX-WS Service.

Click Here to See How To Create Simple JAX-WS Service

i assumed that you have created a simple web service and it is up and running. we will modify that web service to provide the calculator based web service operations. in this calculator web service, we support for three operations.

1. Addition
2. Multiplication
3. Subtraction

you can see the SEI (Service Endpoint Interface) and SIB (Service Implementation Bean) as follows.


SEI - CalculatorService.java

package com.chathurangaonline.sample.jaxws;

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

/**
 * <p>
 *     Service Endpoint Interface for the calculator service.
 * </p>
 */
@WebService
public interface CalculatorService {

    @WebMethod
    long add(long number1, long number2);

    @WebMethod
    long subtract(long number1, long number2);

    @WebMethod
    long multiply(long number1, long number2);
}


SIB - CalculatorServiceImpl.java

package com.chathurangaonline.sample.jaxws;

import javax.jws.WebService;

/**
 * <p>
 *     Service Implementation Bean (SIB) for CalculatorService endpoint interface
 * </p>
 */
@WebService
public class CalculatorServiceImpl implements CalculatorService{


    @Override
    public long add(long number1, long number2) {
        return number1+number2;
    }

    @Override
    public long subtract(long number1, long number2) {
        return number1+number2;
    }

    @Override
    public long multiply(long number1, long number2) {
        return number1*number2;
    }
}


Service Publisher (Only for Development Environment)

package com.chathurangaonline.sample.jaxws;

import javax.xml.ws.Endpoint;

/**
 * <p>
 *     simple web service publisher for testing the web service in the development environment.
 *     remove this publisher class in the production environment and deploy the web service with
 *     j2ee compliant web server.
 * </p>
 */
public class CalculatorServicePublisher {

    public static void main(String[] args) {

        Endpoint.publish("http://localhost:6655/jaxWsCalcService",new CalculatorServiceImpl());
    }
}


once everything is added correctly, our project will looks like as follows.



now we have a calculator web service that is ready for the deployment. now we will publish our web service using the Endpoint.publish() method and check whether it is working. since we are uisng this in the test environment, we do not need to deploy this is a J2EE application server at the moment. but in our next article we will look at how to deploy the web service in tomcat server.

once the web service is published you can access the web service in the following url.
http://localhost:6655/jaxWsCalcService

once the web service is published, we need to write/generate a web service client to comsume the web service. it will be discussed in following blog post.


How to generate JAX-WS service client and integrate with Java Application

you can download the source code from following gitHub repo.

https://github.com/chathurangat/jaxws-calculator-service

Hope this will be helpful for you!

Cheers
Chathuranga Tennakoon
www.chathurangaonline.com







Tuesday, September 17, 2013

how to exclude web service operation (web method) from the web service in jax-ws

The annotation @WebService tells the server runtime environment to expose all public methods on that bean as a Web service. In below example, all the public methods in the web service will be exposed as web methods.


package com.chathurangaonline.sample.jax.ws;
 
import javax.jws.WebService;
import com.chathurangaonline.sample.model.Hotel;
 
@WebService
public class HotelWebService{
 
    public Hotel retriveHolelByCity(String cityName) {
        //todo implementation should goes here 
        return new Hotel();
    }


    public void addNewHotel(Hotel hotel) {
        //todo implementation should goes here 
    }
}


suppose that you do not need to expose the  addNewHotel method as a web service operation method. but the default implementation of the @WebService method will expose all public methods as web service operations. but there is a special annotation that will prevent the method by exposing/publishing as a web service operation.

    @WebMethod(exclude = true)


Refer the below class and try to publish the web service.

package com.chathurangaonline.sample.jax.ws;
 
import javax.jws.WebService;
import com.chathurangaonline.sample.model.Hotel;
 
@WebService
public class HotelWebService{
 
    public Hotel retriveHolelByCity(String cityName) 
        //todo implementation should goes here 
        return new Hotel();
    }


    @WebMethod(exclude = true)
    public void addNewHotel(Hotel hotel) {
        //todo implementation should goes here 
    }
}


here the  addNewHotel method will not be exposed or published as a web service operation/method.

i hope that this will be helpful for you!

Cheers
Chathuranga Tennakoon
chathuranga.t@gmail.com
www.chathurangaonline.com  

Monday, July 22, 2013

Simple JAX-WS Web Service (SOAP based) for Beginners


Today, i am going to explain simple JAX-WS web service( based on SOAP) for the beginners who are new to web service development. 
Web Services can be divided into two categories.
1. SOAP based web services
2. RESTful web services.

JAX-WS supports for both SOAP based and RESTful web services. In this post, we are going to discuss about the SOAP based web services. AS an entry point for the SOAP web service, first we will discuss the architecture of the typical SOAP based web service.


 


Here you can see that the SOAP client will communicate with the SOAP service with the aid of the SOAP libraries. SOAP libraries will be responsible to send and receive request and response between client and server. Here the both request and response will be the SOAP documents and those will be exchanged between client underlying SOAP libraries and the Service underlying SOAP libraries. These SOAP libraries will do the marshalling and unmarshaling whenever required.

What is marshalling and unmarshalling?

Marshalling – converting Java objects into the XML files.
Unmarshalling - converting XML files into the Java objects.

JAX-WS uses JAXB (Java Architecture for XML Binding) for the marshalling and unmarshalling.


In this example, we are going to look at the simple SOAP based 
web service that prints the hello concatenating with the provided 
web service input parameter as the output. Refer the below project 
tree structure to identify the components associated with the 
web service.


 
I will briefly explain the web service concepts by getting the
 examples from above sample web service.
  • Service Endpoint Interface (SEI) – HelloWorld.java 
  • Service Implementation Bean (SIB) – HelloWorldImpl.java
  • Web Service Publisher - HelloWorldPublisher.java 
Then we need to look at SEI, SIB and WsPublisher in detail.


SEI : - Service  Endpoint Interface
first of all you need to know what is the SEI. SEI is just a Java interface
that defines/declares all the web service methods. In this example,
the following file will be the SEI.

HelloWorld.java
package com.jax.ws.samples;

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

/**
 * <p>
 *     this will be the SEI that declares all the web service methods
 * </p>
 */
@WebService
public interface HelloWorld {

    @WebMethod
    String printWelcomeMessage(String username);
} 
SIB :- Service Implementation Bean SIB is the implementation of SEI. That means in the SIB, all the 
web methods declared in the SEI will be implemented.
SIB can be implemented as two ways.
 
 1. POJO class
2. Stateless Session EJB

In this example will be using POJO class as SIB to implement SEI as follows.

HelloWorldImpl.java

package com.jax.ws.samples;

import javax.jws.WebService;

/**
 * <p>
 *     this will be the SIB that implements all the web service methods
 *     declared in the SEI.
 * </p>
 */
@WebService(endpointInterface = "com.jax.ws.samples.HelloWorld")
public class HelloWorldImpl implements HelloWorld{

    @Override
    public String printWelcomeMessage(String username) {
        return "Hello "+username;
    }
}
as you can see, the end point interface will be the relevant java 
interface (SEI) that is implemented by the relevant SIB.


Publishing the Web Service 
once the SEI and SIB have been completed  and compiled, the web 
service is ready to be published. In production mode,web service 
should be published using the application servers such as Tomcat, 
JBoss, WebLogic etc... but for the testing purpose it is possible to 
publish the web service with the simple java program as follows.

HelloWorldPublisher.java

package com.jax.ws.samples;

import javax.xml.ws.Endpoint;
/**
 * <p>
 *     this will be the sample web service publisher class
 *     whose responsibility to publish the given web service
 * </p>
 */
public class HelloWorldPublisher {

    public static void main(String []args){
        //1st argument - web service publication URL
        //2nd argument - instance of SIB
        Endpoint.publish("http://localhost:6666/sayHello",new HelloWorldImpl());
    }
}

you can publish the web service by running this simple program (HelloWorldPublisher.java). After running the publisher program, it is time to check whether the 
published web service is up and running. This can be done with web 
browser by getting the related WSDL document as follows.
 
http://localhost:9999/sayHello?wsdl


I think this will be helpful for you to start your first Java web service development.

This sample web service is available in the following GitHub repository. 
https://github.com/chathurangat/jax-ws-helloworld
 
I think this will give you an brief idea about how to develop web services with java. 
Hope this will helpful for you
 
Thanks and Regards
Chathuranga Tennakoon