Wednesday, September 2, 2015

ADF Service Interface SOAP Webservice Namespace Change

We can create Service Interface from ADF BC Application Module. When we are creating the Service Interfaces, service is taking default  namespaces. This is changing sometimes, when any server restart or new deployment happens. Due to this issue, webservice fails in mobile application.

Please add the below files the directory where “AppModuleService.java” resides.

hander-chain.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
   <handler-chain>
      <handler>
         <handler-name>SOAPBodyHandler</handler-name>
         <handler-class>com.abc.SOAPBodyHandler</handler-class>
      </handler>
   </handler-chain>
</handler-chains>

SOAPBodyHandler.java

package com.abc;

import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;


public class SOAPBodyHandler implements SOAPHandler<SOAPMessageContext>
{
    static final String DESIRED_NS_PREFIX = "custname";
    static final String DESIRED_NS_URI = " /abc/mobile/si/model/common/types/";
    static final String UNWANTED_NS_PREFIX = "ns3";
   
    public SOAPBodyHandler() {
        super();
    }
    @Override
    public Set<QName> getHeaders() {
        return null;
    }
    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        if ((Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY)) { //Check here that the message being intercepted is an outbound message from your service, otherwise ignore.
                try {   
                  SOAPEnvelope envelope = context.getMessage().getSOAPPart().getEnvelope();
                    SOAPBody body = envelope.getBody();
                    Iterator iter = body.getChildElements();
                    while (iter.hasNext()) {
                        Object object = iter.next();
                        if (object instanceof SOAPElement) {
                            SOAPElement element = (SOAPElement) object;
                            element.removeNamespaceDeclaration(element.getPrefix());
                            element.setPrefix("custname");
                        }
                    }
                   
                } catch (SOAPException ex) {
                    Logger.getLogger(SOAPBodyHandler.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            return true; //indicates to the context to proceed with (normal)message processing
    }
    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return false;
    }
    @Override
    public void close(javax.xml.ws.handler.MessageContext context) {
    }
}

If you want to change the namespace in multiple levels, please iterate the element and change it.

Sample Code given below.

if (object instanceof SOAPElement) {
                            SOAPElement element = (SOAPElement) object;
                            element.removeNamespaceDeclaration(element.getPrefix());
                            element.setPrefix("custname ");
                                Iterator a =element.getChildElements();
                            while(a.hasNext()) {
                                SOAPElement element1=(SOAPElement)a.next();
                                element1.removeNamespaceDeclaration(element1.getPrefix());
                                element1.setPrefix("custname ");
                                Iterator b =element1.getChildElements();
                                while(b.hasNext()) {
                                    SOAPElement element2=(SOAPElement)b.next();
                                    element2.removeNamespaceDeclaration(element1.getPrefix());
                                    element2.setPrefix("custname");
                                }
                            }
                        }

Please change the package names accordingly based on your project package for AppModuleService.java.

Please add the below lines in your webservice project class’s annotation.

@HandlerChain(name = "SOAPBodyHandler",file="handler-chain.xml")

Example:-

import javax.jws.HandlerChain;

@HandlerChain(name = "SOAPBodyHandler",file="handler-chain.xml")
Public class AppModuleService
{


Deploy the application and execute the webservices and you can see the changes. This is mainly happening when we are creating SOAP services for mobile (Titanium Applications) and Android device, need the complete namespace of response tags.

No comments:

Post a Comment