Wednesday, October 3, 2012

Packt Publishing reaches 1000 IT titles and celebrates with an open invitation

Birmingham-based IT publisher Packt Publishing is about to publish its 1000th title. Packt books are renowned among developers for being uniquely practical and focused, but you’d be forgiven for not yet being in the know – Packt books cover highly specific tools and technologies which you might not expect to see a high quality book on.

Packt is certain that in its 1000 titles there is at least one book that everyone in IT will find useful right away, and are inviting anyone to choose and download any one of its eBooks for free over its celebration weekend of 28-30th Sep 2012. Packt is also opening its online library for a week for free to give customers an easy to way to research their choice of free eBook.

Packt supports many of the Open Source projects covered by its books through a project royalty donation, which has contributed over $400,000 to Open Source projects up to now. As part of the celebration Packt is allocating $30,000 to share between projects and authors as part of the weekend giveaway, allocated based on the number of copies of each title downloaded.

Dave Maclean, founder of Packt Publishing: “At Packt we set out 8 years ago to bring practical, up to date and easy to use technical books to the specialist tools and technologies that had been largely overlooked by IT publishers. Today, I am really proud that with our authors and partners we have been able to make useful books available on over 1000 topics and make our contribution to the development community.”

I personally appeal all the readers to utilize this opportunity, register, browse PacktLib, their online library, read as many books you want, download the free ebook of your choice.

Sunday, June 3, 2012

Spring Webservices 2 Cookbook


I would like to proudly present this book to the Java and Spring Developer Community. This blog and the posts published here are the starting point of this book. 

And this book was the reason for such a big delay between the past posts and this one. I(along with my friend and colleague, Hamid Reza Sattari) was busy writing the book.

I want to thank all of you to keep this blog live by visiting and posting comments. I will keep publishing more posts that would be helpful for the developer community.


The book is now available in the publisher's website and the major online book stores.

Sharing few links...



Found few reviews about the book online.. I thank the reviewers for their time and genuine approach.




A chapter published in Service-Tech Magazine [Testing and Monitoring Web Services]

Thanks again for all who supported and contributed.

Thursday, November 4, 2010

Web Service Client with Spring-WS



Spring-WS fares beautifully at the client-side as well. With its simple API for client side web service, Spring-ws simplifies web service client programming. This post demonstrates how easy it is to develop a web service client using Spring-WS.

WebServiceTemplate, the convenient helper class provided by Spring-WS, provides a set of easy to use helper methods to perform common operations, plus the callback methods for more sophisticated operations, similar to the other familiar Spring template classes.

You may take a quick look at the Spring-WS documentation for an overview and the useful methods that the WebServiceTemplate offers. The usage is straight forward, hence no scope further explanation. 

The ws-client program given here is exactly a Java version of the one developed in the C# language[.Net framework] with the WCF technology, in the part 4 of this series. A client API is developed implementing the OrderService.java (the service interface) as a proxy. Then it is springified in the ApplicationContext.xml, along with the other required components to make the web service wiring. Instead of a Form as in the part 4, here it is a JUnit Testcase, which calls the API. 

Here is the summary of tools and methods used in this program.

IDESpringsource Tool Suite(STS), based on Eclipse (Download from here)    
Transport MechanismHTTP
Message FactorySAAJSoapMessageFactory (SAAJ-specific implementation of WebserviceMessageFactory)
XML Marshaling TechnologyJAXB 2   

Now, let us take a look at the simple steps involved in building a Web Service Client program for our OrderService which was built under the part 2 of this series[WCF client for a Spring Web service: An interoperability story].

  1. Prepare the workspace

    1. Create New Java Project[name:LiveRestautantClient] in STS(Springsource Tool Suite)/Eclipse.

    2. Add all the Spring-ws libraries as dependencies to the project.

    3. Create three source folders, src, test and resource.

    4. Add the project, LiveRestaurant as a project dependency to this project (This step is to reuse the OrderService.java (Java Interface) as the base specification for the OrderServiceClient, which is described below. Alternatively, you can copy just that file and keep locally).

    5. Download Jaxb2 XJC Plugin from         https://jaxb-workshop.dev.java.net/servlets/ProjectDocumentList?folderID=4962&expandFolder=4962&folderID=4962 and add to the IDE.  
       
  2. Generate the model(data-types) POJOs from the XSD. (If you have the LiveRestaurant Project, where the web service is built in your work space, you can just add that project to this client project as a dependency, and skip this entire step)

    1. Copy the OrderService.xsd from the LiveRestaurant service project to the resource folder

    2. Right click on the XSD file >> JAXB 2.0 >> Run XJC.



    3. Provide package name: com.live.order.domain

    4. Output Directory: LiveRestaurantClient\src

    5. Click Finish.

    6. Refresh the project and make sure the classes are generated under src.

  3. Write the client side API, OrderServiceClient as a proxy for the OrderService under the source folder, src, inside package, com.live.order.service.client. Here is a sample code that you can reuse. WebServiceTemplate is used here, to invoke the operations.


    package com.live.order.service.client;

    import org.apache.log4j.Logger;

    import org.springframework.ws.client.core.WebServiceTemplate;

    import com.live.order.domain.CancelOrderRequest;
    import com.live.order.domain.CancelOrderResponse;
    import com.live.order.domain.ObjectFactory;
    import com.live.order.domain.Order;
    import com.live.order.domain.PlaceOrderRequest;
    import com.live.order.domain.PlaceOrderResponse;
    import com.live.order.service.OrderService;

    public class OrderServiceClient implements OrderService {

        private static final Logger logger = Logger.getLogger(OrderServiceClient.class);
        private static final ObjectFactory WS_CLIENT_FACTORY = new     ObjectFactory();
               
        private  WebServiceTemplate webServiceTemplate;

        public OrderServiceClient(WebServiceTemplate webServiceTemplate) {
            this.webServiceTemplate = webServiceTemplate;
        }
               
        @Override
        public boolean cancelOrder(String orderRef) {
            logger.debug("Preparing CancelOrderRequest.....");
            CancelOrderRequest request =   WS_CLIENT_FACTORY.createCancelOrderRequest();
            request.setRefNumber(orderRef);

            logger.debug("Invoking Web service Operation[CancelOrder]....");
            CancelOrderResponse response = (CancelOrderResponse) webServiceTemplate.marshalSendAndReceive(request);
               
            logger.debug("Has the order cancelled: " + response.isCancelled());
               
            return response.isCancelled();
        }

        @Override
        public String placeOrder(Order order) {
            logger.debug("Preparing PlaceOrderRequest.....");
                    PlaceOrderRequest request = WS_CLIENT_FACTORY.createPlaceOrderRequest();
                    request.setOrder(order);
               
            logger.debug("Invoking Web service Operation[PlaceOrder]....");
                    PlaceOrderResponse response = (PlaceOrderResponse) webServiceTemplate.marshalSendAndReceive(request);
            logger.debug("Order reference:

    "
    + response.getRefNumber());
            return response.getRefNumber();
        }
    }   
    OrderServiceClient.java


  4. Create the Spring ApplicationContext file wiring the components.



    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
            http://www.springframework.org/schema/util
            http://www.springframework.org/schema/util/spring-util-2.0.xsd">
           
        <bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
            <property name="soapVersion">
                <util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" />
            </property>
        </bean>
           
        <bean id="orderServiceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
            <property name="contextPath" value="com.live.order.domain" />
        </bean>
       
        <bean id="orderServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
            <constructor-arg ref="messageFactory" />
            <property name="marshaller" ref="orderServiceMarshaller"></property>
            <property name="unmarshaller" ref="orderServiceMarshaller"></property>
            <property name="messageSender">
                <bean
                    class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
                </bean>
            </property>
            <property name="defaultUri" value="http://localhost:8080/LiveRestaurant/spring-ws/OrderService" />
        </bean>
       
        <bean id="OrderServiceClient" class="com.live.order.service.client.OrderServiceClient">
            <constructor-arg ref="orderServiceTemplate"></constructor-arg>
        </bean>
    </beans>
    ApplicationContext.xml


  5. OrderServiceClientTest - A Junit Testcase, which acts as the client program. It loads the spring ApplicationContext while startup to take hold of the live Spring-WS components. OrderServiceClientTest primarily invokes the client API with some dummy values, and just logs the response.


    package com.live.order.service.client.test;

    import static org.junit.Assert.assertNotNull;
    import static org.junit.Assert.assertTrue;

    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.List;

    import org.junit.BeforeClass;
    import org.junit.Test;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.live.order.domain.Address;
    import com.live.order.domain.Customer;
    import com.live.order.domain.FoodItem;
    import com.live.order.domain.FoodItemType;
    import com.live.order.domain.Name;
    import com.live.order.domain.Order;
    import com.live.order.service.OrderService;

    import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;

    public class OrderServiceClientTest {

        private static ClassPathXmlApplicationContext context = null;

        @BeforeClass
        public static void setUpBeforeClass() throws Exception {
            context = new ClassPathXmlApplicationContext("/ApplicationContext.xml");
        }

        @Test
        public void testCancelOrder() {
            OrderService client = (OrderService) context.getBean("OrderServiceClient");
            boolean cancelled = client.cancelOrder("Ref-2010-9-15-0.8432452204897198");
           
            assertTrue (cancelled);
        }

        @Test
        public void testPlaceOrder() {
            OrderService client = (OrderService) context.getBean("OrderServiceClient");
           
            Order order = prepareDummyOrder();
            String orderRef = client.placeOrder(order);
           
            assertNotNull(orderRef);
        }

        private Order prepareDummyOrder() {
            Order order = new Order();
            order.setCustomer(prepareCustomer());
            order.setDateSubmitted(prepareDate(2010, 10, 15, 8, 00, 00));
            order.setOrderDate(prepareDate(2010, 10, 15, 12, 00, 00));
            order.getItems().addAll(prepareOrderItems());
            return order;
        }

        private List<FoodItem> prepareOrderItems() {
            List<FoodItem> items = new ArrayList<FoodItem>(5);
            items.add(prepareFoodItem("Vegetable Thali",

    FoodItemType.
    MEALS, 2));
            items.add(prepareFoodItem("Kheer/ Palpayasam",

    FoodItemType.
    DESSERTS, 4));
            items.add(prepareFoodItem("Fresh Orange Juice",

    FoodItemType.
    JUICES, 1));
            items.add(prepareFoodItem("Fresh Carrot Juice",

    FoodItemType.
    JUICES, 1));
            items.add(prepareFoodItem("Sweet Corn Soup",

    FoodItemType.
    STARTERS, 2));
            return items;
        }

        private XMLGregorianCalendarImpl prepareDate(int year, int month, int date, int hour, int minute, int second) {
            GregorianCalendar calendar = new GregorianCalendar();
            calendar.set(Calendar.YEAR, year);
            calendar.set(Calendar.MONTH, month);
            calendar.set(Calendar.DAY_OF_MONTH, date);
            calendar.set(Calendar.HOUR_OF_DAY, hour);
            calendar.set(Calendar.MINUTE, minute);
            calendar.set(Calendar.SECOND, second);
            return new XMLGregorianCalendarImpl(calendar);
        }

        private FoodItem prepareFoodItem(String name, FoodItemType type,
                double quantity) {
            FoodItem item = new FoodItem();
            item.setName(name);
            item.setType(type);
            item.setQuantity(quantity);
            return item;
        }

        private Customer prepareCustomer() {
            Customer customer = new Customer();
            customer.setName(prepareCustomerName());
            customer.setAddressPrimary(prepareAddress("123", "My Office Building",
                    "My Office Street", "Dubai", "United Arab Emirates",
                    "0097150xxxxxxx", "009714xxxxxxx", "shameer@mycompany.com"));
            customer.setAddressSecondary(prepareAddress("234", "My Home Building",
                    "My Home Street", "Dubai", "United Arab Emirates",
                    "0097150xxxxxxx", "009714xxxxxxx", "shameer@myhome.com"));
            return customer;
        }

        private Name prepareCustomerName() {
           
            Name name = new Name();
            name.setLName("Shameer");
            name.setFName("Kunjumohamed");
            return name;
        }

        private Address prepareAddress(String doorNo, String building,
                String street, String city, String country, String phoneMobile,
                String phoneLandline, String email) {
           
            Address address = new Address();
            address.setDoorNo(doorNo);
            address.setBuilding(building);
            address.setStreet(street);
            address.setCity(city);
            address.setCountry(country);
            address.setPhoneMobile(phoneMobile);
            address.setPhoneLandLine(phoneLandline);
            address.setEmail(email);
            return address;
        }
    }
    OrderServiceClientTest.java



  6.  Finally you will have a package structure like this..




  7. Run the OrderServiceClientTest.java - Right click on the file, Run as --> JUnit Test. (Make sure your web service is running). You should be able to see the success message as given below, if your configurations are correct.



  8. Check your log files or the Console view of your Eclipse (or STS), to see the SOAP message logged, and other debug messages.

Now you have your client program ready with you, hope it was straight forward and easily understandable. You may send in the error messages you may get while developing the program as comments here, along with the stack trace, I will try to find some time to check them out and reply. 


The best part you can see here is that you are not writing any web-service specific code in your program, rather you are just invoking the appropriate method of the WebServiceTemplate. Rest all job is done by the framework (provided you configured the components properly).

The above sample program is just one way of developing a web service client program using Spring Web Services. There are many other approaches you can try with, for example, using a different marshaller, say, XMLBeans. You can even construct your own XML, send via a StreamSource and recieve the response as XML as a StreamResult, then manipulate the XML using XPATH. 

 Besides the default HTTPTransport, you may just try the JMSTransport and the EmailTransport as well. It's all fun :) 


Lets us move on to add some security to our web service and client programs in the next few posts. Expect them soon..