WebService с Apache CXF и пользовательскими заголовками

Я создал веб-сервис, используя Apache cfx и spring, он работает, но мне нужно, чтобы ответ включал этот заголовок

<?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>

Но должно быть так

<?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>

Это конфигурация bean-компонентов Spring, которые предоставляют сервис.

<?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>

это интерфейс

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);

}

Есть идеи ?


person atomsfat    schedule 23.10.2009    source источник


Ответы (5)


Или используйте встроенные возможности конфигурации CXF. Просто добавьте это в свою конфигурацию CXF Spring:

<jaxws:properties>
    <entry key="org.apache.cxf.stax.force-start-document">
        <bean class="java.lang.Boolean">
            <constructor-arg value="true"/>
        </bean>
    </entry>
</jaxws:properties>
person avianey    schedule 27.09.2012
comment
Добавление endpoint.getProperties().put(StaxOutInterceptor.FORCE_START_DOCUMENT, Boolean.TRUE.toString()); to EndpointImpl делает тот же трюк, но пролог будет неверным, это. с одинарными ударами сверху вместо двойных. - person JRA_TLL; 13.02.2019
comment
Чтобы уточнить, он добавит ‹?xml version='1.0' encoding='UTF-8'?› вместо ‹?xml version=1.0 encoding=UTF-8?› - person JRA_TLL; 14.02.2019

Проверьте следующее

Как добавить заголовки мыла к запросу/ответу?

Добавление обработчиков JAX-WS в веб-службы

Преобразование обработчиков JAX-WS в перехватчики Apache CXF

затем выберите один из вариантов и реализуйте обработчик/перехватчик, который добавляет то, что вам нужно.

person jitter    schedule 23.10.2009

Что ж, я реализую обработчик, сначала я загрузил примеры из CXF и изменил обработчик регистрации, и он работает.

Конфигурация пружины:

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);
        }
    }
}

Примечание: в попытке я использую MessageContext.MESSAGE_OUTBOUND_PROPERTY, как предложил Джастин.

person atomsfat    schedule 26.10.2009
comment
Это будет отображаться только в обработчике, когда вы печатаете вывод в System.out. Но как только обработчик завершает работу, CXF перезаписывает ответ, и в окончательном ответе не будет объявления XML. - person ulab; 02.08.2017

По ссылкам, предоставленным jitter, я перешел на http://cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest%252Fresponse%253F и нашел следующее решение:

    // My object of the custom header
    AuthenticationHeader aut = new AuthenticationHeader();
    aut.setUserName("ws");
    aut.setPassword("ws123");

    IntegrationWS integration = new IntegrationWS();

    List<Header> headers = new ArrayList<Header>();
    Header dummyHeader;
    try {
        dummyHeader = new Header(new QName("http://www.company.com/ws/", "AuthenticationHeader"), auth, new JAXBDataBinding(AuthenticationHeader.class));
    } catch (JAXBException e) {
        throw new IllegalStateException(e);
    }
    headers.add(dummyHeader);

    IntegrationWSSoap soapPort = integration.getIntegrationWSSoap12();

    //client side:
    ((BindingProvider)soapPort).getRequestContext().put(Header.HEADER_LIST, headers);

    ArrayOfBrand arrayBrand = soapPort.syncBrands();
person BrunoJCM    schedule 06.12.2012

У меня нет специальных знаний Apache CXF, но способ jax-ws добавить объявление xml, похоже, состоит в том, чтобы создать обработчик и использовать SOAPMessage.setProperty(), чтобы включить эту функцию. :

message.setProperty(SOAPMessage.WRITE_XML_DECLARATION, "true");

Вы должны иметь возможность добавить обработчик jax-ws в свою конечную точку, добавив элемент jaxws:handlers в эту конфигурацию spring.

person Justin W    schedule 23.10.2009