Search code examples
javacxfspring-ws

WebService with Apache CXF and custom headers


I created a web service using Apache cfx and spring, it works, but I need that the response include this header

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

Right now the response is like this.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:postEncuestaResponse xmlns:ns2="http://webservice.atomsfat.com/">
         <respuestaEncuesta>
            <dn>12315643154</dn>
            <encuestaPosted>true</encuestaPosted>
            <fecha>2009-09-30T16:32:33.163-05:00</fecha>
         </respuestaEncuesta>
      </ns2:postEncuestaResponse>
   </soap:Body>
</soap:Envelope>

But should be like this

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <ns2:postEncuestaResponse xmlns:ns2="http://webservice.atomsfat.com/">
         <respuestaEncuesta>
            <dn>12315643154</dn>
            <encuestaPosted>true</encuestaPosted>
            <fecha>2009-09-30T16:32:33.163-05:00</fecha>
         </respuestaEncuesta>
      </ns2:postEncuestaResponse>
   </soap:Body>
</soap:Envelope>

This is the configuration of the beans of spring that expose the service.

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

    <jaxws:endpoint
      id="encuestas"
      implementor="webservice.serviceImpl"
      address="/Encuestas" >
    </jaxws:endpoint>

</beans>

this is the interface

import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService
public interface Encuestas {

    @WebResult(name= "respuestaEncuesta") 
    RespuestaEncuestaMsg postEncuesta (@WebParam(name = "encuestaMsg") EncuestaMsg message);

}

Any ideas ?


Solution

  • Well I implement a Handler, first I downloaded the examples from CXF and modified the logging Handler, and it works.

    The configuration of spring :

    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-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    
        <jaxws:endpoint
            id="encuestas"
            implementor="com.webservice.EncuestasImpl"
            address="/Encuestas">
        <jaxws:handlers>
                <bean class="com.webservice.HeaderHandler"/>
    
            </jaxws:handlers> 
    
        </jaxws:endpoint>
    

    And the code this is the code for the handler.

    /*
     * To change this template, choose Tools | Templates
     * and open the template in the editor.
     */
    
    package com.webservice;
    
    import java.io.PrintStream;
    import java.util.Map;
    import java.util.Set;
    
    import javax.xml.namespace.QName;
    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;
    
    /*
     * This simple logical Handler will output the payload of incoming
     * and outgoing messages.
     */
    public class HeaderHandler  implements SOAPHandler<SOAPMessageContext> {
    
        private PrintStream out;
    
        public HeaderHandler() {
            setLogStream(System.out);
        }
    
        protected final void setLogStream(PrintStream ps) {
            out = ps;
        }
    
        public void init(Map c) {
            System.out.println("LoggingHandler : init() Called....");
        }
    
        public Set<QName> getHeaders() {
            return null;
        }
    
        public boolean handleMessage(SOAPMessageContext smc) {
            System.out.println("LoggingHandler : handleMessage Called....");
            logToSystemOut(smc);
            return true;
        }
    
        public boolean handleFault(SOAPMessageContext smc) {
            System.out.println("LoggingHandler : handleFault Called....");
            logToSystemOut(smc);
            return true;
        }
    
        // nothing to clean up
        public void close(MessageContext messageContext) {
            System.out.println("LoggingHandler : close() Called....");
        }
    
        // nothing to clean up
        public void destroy() {
            System.out.println("LoggingHandler : destroy() Called....");
        }
    
        /*
         * Check the MESSAGE_OUTBOUND_PROPERTY in the context
         * to see if this is an outgoing or incoming message.
         * Write a brief message to the print stream and
         * output the message. The writeTo() method can throw
         * SOAPException or IOException
         */
        protected void logToSystemOut(SOAPMessageContext smc) {
            Boolean outboundProperty = (Boolean)
                smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    
            if (outboundProperty.booleanValue()) {
                out.println("\nOutbound message:");
            } else {
                out.println("\nInbound message:");
            }
    
            SOAPMessage message = smc.getMessage();
    
    
    
    
            try {
                message.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");
                message.writeTo(out);
                out.println();
            } catch (Exception e) {
                out.println("Exception in handler: " + e);
            }
        }
    }
    

    Note: that in the try I use MessageContext.MESSAGE_OUTBOUND_PROPERTY like Justin suggested.