[JAX-WS] @HandlerChain example with unit test

JAX-WS @WebService component use a handler chain to alter incoming and outgoing SOAP messages. SOAP Handlers are similar to Servlet Filters or EJB/CDI Interceptors.

1. Project Layout (you can create an example WebService project)
layout

2. LogService interface (this is the interface for our web service)

package org.me.calculator;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface LogService {
    int multiply(int mul1, int mul2);
    int sum(@WebParam(name = "add0") int add1, @WebParam(name = "add1") int add2);
}

3. The implementing class

package org.me.calculator;

import javax.ejb.Singleton;
import javax.jws.HandlerChain;
import javax.jws.WebParam;
import javax.jws.WebService;

@Singleton
@WebService (name="LogService", portName="LogPort", serviceName="LogWebService")
@HandlerChain (file = "handlers.xml")
public class LogServiceImpl implements LogService {
    /**
     * Web service operation
     * @param add1
     * @param add2
     * @return 
     */
    @Override
    public int sum(@WebParam(name = "add0") int add1, @WebParam(name = "add1") int add2) {
        return add1 + add2;
    }
    
    @Override
    public int multiply(int mul1, int mul2) {
        return mul1 * mul2;
    }
}

4. Handlers.xml (in the same package)

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
<handler-chain>
    <handler>
        <handler-name>org.me.calculator.Inflate</handler-name>
        <handler-class>org.me.calculator.Inflate</handler-class>
    </handler>
    <handler>
        <handler-name>org.me.calculator.Increment</handler-name>
        <handler-class>org.me.calculator.Increment</handler-class>
    </handler>
</handler-chain>
</handler-chains>

5. One of the SOAPHandlers (Inflate)

package org.me.calculator;

import java.util.Collections;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.w3c.dom.Node;

public class Inflate implements SOAPHandler<SOAPMessageContext> {

    @Override
    public Set<QName> getHeaders() {
        return Collections.emptySet();
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        try {
            final SOAPMessage message = context.getMessage();
            final SOAPBody body = message.getSOAPBody();
            final String localName = body.getFirstChild().getLocalName();

            if ("sumResponse".equals(localName) || "multiplyResponse".equals(localName)) {
                final Node responseNode = body.getFirstChild();
                final Node returnNode = responseNode.getFirstChild();
                final Node intNode = returnNode.getFirstChild();
                final int value = new Integer(intNode.getNodeValue());
                intNode.setNodeValue(Integer.toString(value * 1000));
            }
            return true;
        } catch (SOAPException ex) {
            return false;
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return true;
    }

    @Override
    public void close(MessageContext context) {
        
    }
}

6. The other SOAPHandler (Increment)

package org.me.calculator;


import java.util.Collections;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import org.w3c.dom.Node;

public class Increment implements SOAPHandler<SOAPMessageContext> {

    @Override
    public Set<QName> getHeaders() {
        return Collections.emptySet();
    }

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        try {
            final SOAPMessage message = context.getMessage();
            final SOAPBody body = message.getSOAPBody();
            final String localName = body.getFirstChild().getLocalName();

            if ("sumResponse".equals(localName) || "multiplyResponse".equals(localName)) {
                final Node responseNode = body.getFirstChild();
                final Node returnNode = responseNode.getFirstChild();
                final Node intNode = returnNode.getFirstChild();
                final int value = new Integer(intNode.getNodeValue());
                intNode.setNodeValue(Integer.toString(value + 999));
            }
            return true;
        } catch (SOAPException ex) {
            return false;
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return true;
    }

    @Override
    public void close(MessageContext context) {
        
    }
}

7. And the unit test

package org.me.calculator;

import java.net.URL;
import java.util.Properties;
import javax.ejb.embeddable.EJBContainer;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;


public class NewEmptyJUnitTest {
    
    public NewEmptyJUnitTest() {
    }
    
    @BeforeClass
    public static void setUpClass() {
        Properties properties = new Properties();
        properties.setProperty("openejb.embedded.remotable", "true");
        EJBContainer.createEJBContainer(properties);
    }
    
    @AfterClass
    public static void tearDownClass() {
    }
    
    @Before
    public void setUp() {
    }
    
    @After
    public void tearDown() {
    }
   
     @Test
     public void hello() throws Exception{
         final Service calculatorService = Service.create(
                 new URL("http://localhost:8080/CalculatorApp/LogWebService?WSDL"),
                 new QName("http://calculator.me.org/", "LogWebService"));
         assertNotNull(calculatorService);
         final LogService calculator = calculatorService.getPort(LogService.class);
         
         assertEquals(10999, calculator.sum(4,6));
         assertEquals(12999, calculator.multiply(3, 4));

     }
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s