2009-10-23 72 views
4

我创建使用Apache cfx,春季和作品的网络服务,但我需要的响应包含这个头的WebService与Apache CXF和自定义页眉

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

这是春天的暴露服务豆的配置。

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


} 

任何想法?

回答

3

那么我实现一个处理程序,首先我从CXF下载了示例并修改了日志处理程序,并且它可以工作。

弹簧的配置:

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxwshttp://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> 

和代码,这是代码为处理程序。

/* 
* 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像贾斯汀建议。

+0

这将只显示在处理程序为你正在将输出打印到“System.out”。但是一旦处理程序结束,CXF将覆盖响应,最终的响应将不会有XML声明。 – ulab 2017-08-02 10:36:44

0

我没有的Apache CXF具体的知识,但是JAX-WS的方式来增加XML声明似乎是作出处理,并使用SOAPMessage.setProperty()把这一功能上:

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

你应该通过在该spring配置中添加一个jaxws:handlers元素,可以为您的端点添加一个jax-ws处理程序。

3

或者使用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> 
2

如下因素引起的抖动所提供的链接,我去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();