Wednesday, October 30, 2013

SOAP

1. Writing a Web service Client: Stub generation
------------------------------------------------
1. http://webservicex.net/ws/WSDetails.aspx?WSID=64&CATID=12
2. command prompt
3. create directory c:/SEI>wsimport http://www.webservicex.net/geoipservice.asmx?WSDL
we get only .class files, if we want .java files
c:/SEI>wsimport -keep -s src http://www.webservicex.net/geoipservice.asmx?WSDL

2. Writing a Web service Client: Calling the Service
----------------------------------------------------
1. Create package net.webservices
2. Copy all the java files
3. Create GeoIPservice
GeoIpService ipService = new GeoIPService();
GeoIPServiceSoap geoIPServiceSoap = ipService.getGeoIPServiceSoap();
GeoIP geoIp = geoIPServiceSoap.getGeoIP(ipAddress);
System.out.printLn(geoIp.getCountryName());

3. Setting up java EE7 SDK
--------------------------
1. Make sure you Java JDK version 6 or 7
2. Download SDK from oracle and install
orcle.com java->java enterprise edition download sdk 7 download sdk
OR http://www.oracle.com/technetwork/java/javaee/downloads/java-ee-7-sdk-update1-2025644.html
3. To access admin port http://localhost:4848

4. Writing a Web Service: Eclipse setup
---------------------------------------
1. Create new server in eclipse (try to download new eclipse kepler)
2. new server -> click on server adapter - > select glassfish server tool
3. Create new web dynamic project (TestMart)
4. Create test web page and test the page in web browser.
public class ProductCatalog {

                public List<String> getProductCategories(){
                                List<String> categories = new ArrayList<String>();
                                categories.add("Books");
                                categories.add("Music");
                                categories.add("Movies");
                                return categories;
                }
}

5. Writing a Web Service: Code and Deploy
-----------------------------------------
1. Add annotation @WebService to class and add @WebMethod to method
@WebService
public class ProductCatalog {
               
                @WebMethod
                public List<String> getProductCategories(){
                                List<String> categories = new ArrayList<String>();
                                categories.add("Books");
                                categories.add("Music");
                                categories.add("Movies");
                                return categories;
                }
}
2. Deploy the files and run the server.
3. Access http://localhost:4848/ click on Applications->TestMart->View EndPoint-> Can able to see Tester and WSDL URLs

6. Adding Input Arguments
-------------------------
1. Create a new java class org.yash.business ProductServiceImpl.java
ProductServiceImpl.java

package org.yash.business;

import java.util.ArrayList;
import java.util.List;

public class ProductServiceImpl {
                List<String> bookList = new ArrayList<String>();
                List<String> musicList = new ArrayList<String>();
                List<String> movieList = new ArrayList<String>();

                public ProductServiceImpl() {
                                bookList.add("book1");
                                bookList.add("book2");
                                bookList.add("book3");

                                musicList.add("music1");
                                musicList.add("music2");
                                musicList.add("music3");

                                movieList.add("movie1");
                                movieList.add("movie2");
                                movieList.add("movie3");
                }

                public List<String> getProductCategories() {
                                List<String> categories = new ArrayList<String>();
                                categories.add("Books");
                                categories.add("Music");
                                categories.add("Movies");
                                return categories;
                }

                public List<String> getProducts(String category) {
                                if (category.equalsIgnoreCase("books")) {
                                                return bookList;
                                } else if (category.equalsIgnoreCase("music")) {
                                                return musicList;
                                } else if (category.equalsIgnoreCase("movies")) {
                                                return movieList;
                                }
                                return null;

                }

                public boolean addProduct(String category, String product) {

                                if (category.equalsIgnoreCase("books")) {
                                                bookList.add(product);
                                } else if (category.equalsIgnoreCase("music")) {
                                                musicList.add(product);
                                } else if (category.equalsIgnoreCase("movies")) {
                                                movieList.add(product);
                                }
                                return true;
                }

}


ProductCatalog.java

package org.yash;

import java.util.List;

import javax.jws.WebMethod;
import javax.jws.WebService;
import org.yash.business.ProductServiceImpl;

@WebService
public class ProductCatalog {
               
                ProductServiceImpl productService = new ProductServiceImpl();
               
                @WebMethod
                public List<String> getProductCategories(){
                                return productService.getProductCategories();
                }
               
                @WebMethod
                public List<String> getProduct(String category){
                                return productService.getProducts(category);
                }
               
                @WebMethod
                public boolean addProduct(String category, String product){
                                return productService.addProduct(category, product);
                }

}


2. Run on server
3. Goto admin http://localhost:4848/
4. Applications->TestMart->View->Tester
5. Tester take the input eg:music, books, movie

6. Want to add products - add below method in ProductServiceImpl.java
                public boolean addProduct(Stromg category,     String product){
               
                                switch(category.toLowerCase()){
                                                case "books";
                                                                bookList.add(product);
                                                                break;
                                                case "music";
                                                                musicList.add(product);
                                                                break;
                                                case "movies":
                                                                movieList.add(product);
                                                                break;
                                                default:
                                                                return false;
                                                }
                                                return true;
                                }
                }

7. add one more method in ProductCatalog.java
                @WebMethod
                public boolean addProduct(String category, String product){
                                return productService.addProduct(category, product);
                }

8. Run on server
9. http://localhost:4848/
10. Goto Tester.
                test getProducts, addProduct

               
7.Service First(code first) and Contract First(WSDL first) Web Services
-----------------------------------------------
1. Interface - class implementation
2. WSDL - WebService implementation
3. Contract First means write WSDL first
4. Contract Last means generation WSDL from service implementaion which is not suggested.

8. Understanding the WSDL
-------------------------
1. @WebMethod(exclude=true)
2. Publish and refresh WSDL file
3. High level elements of WSDL
                types : It defines custom input types eg: int, string, MyDataType
                messsage : Port input and out message types
                portType : here operations defined which takes input and give output
                binding : on which protocal it is defined eg: http
                service : It defines URL
               
               
9. Customizing the WSDL
-----------------------
Having understood the important elements of the WSDL, we'll now learn some annotations that help us configure and override the various defaults that are used when the WSDL is generated.
1. To change name: @WebService(name="TestMartCatalog")   
2. @WebService(name="TestMartCatalog", portName="TestMartCatalogPort",
                                                                serviceName="TestMartCatalogService",
                                                                targetNamespace="http://testmart.com")
                portName="TestMartCatalogPort" -> to change port name
                serviceName="TestMartCatalogService" -> to change service URL
                i.e from http://hydhtc91906l:8080/TestMart/ProductCatalogService?wsdl to http://hydhtc91906l:8080/TestMart/TestMartCatalogService?wsdl
                targetNamespace="http://testmart.com" -> to change definition name
                i.e from <definitions targetNamespace="http://yash.org/" name="ProductCatalogService"> to <definitions targetNamespace="http://testmart.com" name="ProductCatalogService">
3. @WebMethod(action="fetch_categories", operationName="fetchCategories")                                                         

10. Schema Types and Binding Styles
-----------------------------------
we'll understand how types are handled in the WSDL. We'll also explore the two styles we can choose from for our WSDL - Document style and RPC style.
1. org.yash.ShopInfo
@WebService
@SOAPBinding(style = Style.RPC)
public class ShopInfo {
                @WebMethod
                @WebResult(partName = "lookupOutput")
                public String getShopInfo(
                                                @WebParam(partName = "lookupInput") String property) {
                                String response = "Invalid property";
                                if ("shopName".equals(property)) {
                                                response = "Test Mart";
                                } else if ("since".equals(property)) {
                                                response = "since 2012";
                                }
                                return response;
                }
}
1. We have two types of styles a.Document(default) b. RPC
                for RPC style we do not have "Types"

2. @WebResult(partName = "lookupOutput")
   It changes message part name i.e
   From <message name="getShopInfoResponse"><part name="parameters" element="tns:getShopInfoResponse"/></message>
   To   <message name="getShopInfoResponse"><part name="lookupOutput" type="xsd:string"/></message>

3. public String getShopInfo(@WebParam(partName = "lookupInput") String property)
   Changes from
                <message name="getShopInfo"><part name="arg0" type="xsd:string"/></message>  
   To       
                <message name="getShopInfo"><part name="lookupInput" type="xsd:string"/></message>


11.Service Interface and Custom Types
-------------------------------------
1. Add a method
                public List<Product> getProductsv2(String category){
                                List<Product> productList = new ArrayList<Product>();
                                productList.add(new Product("Book1", " 2222", 100.00));
                                productList.add(new Product("Book2", " 4444", 120.00));
                                return productList;
                }

2. Create interface for the class ProductCatalog.java (right click -> Refactory -> Extract Interface)
3. Copy all annotation in Interface.
4. Bind ProductCatalog.java file using below annotation
@WebService(endpointInterface="org.yash.ProductCatalogInterface")
5. Create model class i.e. Product.java
package org.yash.model;

public class Product {
                private String name;
                private String sku;
                private double price;
               
                Product(){
                               
                }
               
                public Product(String name, String sku, double price){
                                this.name = name;
                                this.sku = sku;
                                this.price = price;
                }
               
                public String getName() {
                                return name;
                }
                public void setName(String name) {
                                this.name = name;
                }
                public String getSku() {
                                return sku;
                }
                public void setSku(String sku) {
                                this.sku = sku;
                }
                public double getPrice() {
                                return price;
                }
                public void setPrice(double price) {
                                this.price = price;
                }

}

ProductCatalogInterface.java
----------------------------
package org.yash;

import java.util.List;

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

import org.yash.model.Product;

@WebService(name="TestMartCatalog", targetNamespace="http://testmart.com")
public interface ProductCatalogInterface {

                @WebMethod(action = "fetch_categories", operationName = "fetchCategories")
                public abstract List<String> getProductCategories();

                @WebMethod
                public abstract List<String> getProduct(String category);

                @WebMethod
                public abstract boolean addProduct(String category, String product);

                @WebMethod
                public abstract List<Product> getProductsv2(String category);

}

ProductCatalog.java
-------------------
package org.yash;

import java.util.ArrayList;
import java.util.List;

import javax.jws.WebService;

import org.yash.business.ProductServiceImpl;
import org.yash.model.Product;

@WebService(endpointInterface="org.yash.ProductCatalogInterface", portName="TestMartCatalogPort", serviceName="TestMartCatalogService")
public class ProductCatalog implements ProductCatalogInterface{
               
                ProductServiceImpl productService = new ProductServiceImpl();

                /* (non-Javadoc)
                 * @see org.yash.ProductCatalogInterface#getProductCategories()
                 */
                @Override
                public List<String> getProductCategories(){
                                return productService.getProductCategories();
                }
               
                /* (non-Javadoc)
                 * @see org.yash.ProductCatalogInterface#getProduct(java.lang.String)
                 */
                @Override
                public List<String> getProduct(String category){
                                return productService.getProducts(category);
                }
               
                /* (non-Javadoc)
                 * @see org.yash.ProductCatalogInterface#addProduct(java.lang.String, java.lang.String)
                 */
                @Override
                public boolean addProduct(String category, String product){
                                return productService.addProduct(category, product);
                }

                /* (non-Javadoc)
                 * @see org.yash.ProductCatalogInterface#getProductsv2(java.lang.String)
                 */
                @Override
                public List<Product> getProductsv2(String category){
                                List<Product> productList = new ArrayList<Product>();
                                productList.add(new Product("Book1", " 2222", 100.00));
                                productList.add(new Product("Book2", " 4444", 120.00));
                                return productList;
                }
               
}

* Access WSDL URL http://hydhtc91906l:8080/TestMart/TestMartCatalogService?wsdl

12. Using JAXB Annotations Part 1
---------------------------------
1. If we need to override any of the defaults, JAXB annotations can be used.
2.  @XmlRootElement and @XmlType to annotate the class itself. I provide a name to the root element. Then I configure the order in which the elements show up using the propOrder property of @XmlType.
@XmlRootElement(name="Product")
@XmlType(propOrder={"price", "sku", "name"})
3. The @XmlElement annotation can be used to configure individual attributes. Use this annotation to change the name of the "name" property to "ProductName". Notice that I am annotating the getter of the property.
@XmlElement(name="ProductName")
                public String getName() {
                                return name;
                }
4. Annotate the method in the endpoint interface with @WebResult to customize the result name in the XML.
@WebMethod
@WebResult(name="Product")
public abstract List<Product> getProductsv2(String category);

From
<?xml version="1.0" encoding="UTF-8"?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:getProductsv2Response xmlns:ns2="http://testmart.com">
            <return>
                <price>100.0</price>
                <sku> 2222</sku>
                <ProductName>Book1</ProductName>
            </return>
            <return>
                <price>120.0</price>
                <sku> 4444</sku>
                <ProductName>Book2</ProductName>
            </return>
        </ns2:getProductsv2Response>
    </S:Body>
</S:Envelope>

To

<?xml version="1.0" encoding="UTF-8"?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:getProductsv2Response xmlns:ns2="http://testmart.com">
            <Product>
                <price>100.0</price>
                <sku> 2222</sku>
                <ProductName>Book1</ProductName>
            </Product>
            <Product>
                <price>120.0</price>
                <sku> 4444</sku>
                <ProductName>Book2</ProductName>
            </Product>
        </ns2:getProductsv2Response>
    </S:Body>
</S:Envelope>

13.SOAP Web Services - Handling Faults
-----------------------------------------
1. If some error in output application throw error and it is handled by Faults in SOAP Webservices
2. Create InvalidInputException class

InvalidInputException.java
--------------------------
public class InvalidInputException extends Exception {
                private String errorDetails;
               
                public InvalidInputException(String reason, String errorDetails){
                                super(reason);
                                this.errorDetails = errorDetails;
                }
               
                public String getFaultInfo(){
                                return errorDetails;
                }
}

ShopInfo.java
-------------
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

@WebService
@SOAPBinding(style = Style.DOCUMENT)
public class ShopInfo {
                @WebMethod
                @WebResult(partName = "lookupOutput")
                public String getShopInfo(
                                                @WebParam(partName = "lookupInput") String property) throws InvalidInputException {
                                String response = null;
                                if ("shopName".equals(property)) {
                                                response = "Test Mart";
                                } else if ("since".equals(property)) {
                                                response = "since 2012";
                                }else {
                                                throw new InvalidInputException("Invalid Input", property + "is not valid input");
                                }
                                return response;
                }
}

14. SOAP Web Services - Using SoapUI
1. Add soap UI plugin in eclipse
                1. Select Help > Install New Software...
                2. In the Work with field, type http://www.soapui.org/eclipse/update and click Add...
                3. Enter the following in the dialog that appears:
                                Name: SoapUI
                                Location: http://www.soapui.org/eclipse/update
                                Install and restart eclipse

2. Window->show view ->others ->SoapUI Navigator     

No comments:

Post a Comment