【问题标题】:WebService with Apache CXF and custom headers带有 Apache CXF 和自定义标头的 WebService
【发布时间】:2009-10-23 16:02:09
【问题描述】:

我使用Apache cfx 和 spring 创建了一个 Web 服务,它可以工作,但我需要响应包含此标头

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

这是暴露服务的spring的bean的配置。

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

}

有什么想法吗?

【问题讨论】:

    标签: java cxf spring-ws


    【解决方案1】:

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

    【讨论】:

    • 添加 endpoint.getProperties().put(StaxOutInterceptor.FORCE_START_DOCUMENT, Boolean.TRUE.toString());到 EndpointImpl 做同样的伎俩,但序言将是错误的,它。用单笔划而不是双笔划。
    • 为了澄清,它将添加 而不是
    【解决方案2】:

    检查以下

    How can I add soap headers to the request/response?

    Adding JAX-WS handlers to web services

    Converting JAX-WS handlers to Apache CXF interceptors

    然后决定其中一个选项并实现一个处理程序/拦截器来添加您需要的内容。

    【讨论】:

      【解决方案3】:

      好吧,我实现了一个 Handler,首先我从 CXF 下载了示例并修改了 logging Handler,它可以工作。

      spring的配置:

      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

      【讨论】:

      • 当您将输出打印到“System.out”时,这只会在处理程序中显示。但是一旦处理程序完成,CXF 会覆盖响应,最终响应不会有 XML 声明。
      【解决方案4】:

      按照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();
      

      【讨论】:

        【解决方案5】:

        我没有 Apache CXF 的具体知识,但是添加 xml 声明的 jax-ws 方式似乎是制作一个处理程序并使用 SOAPMessage.setProperty() 来打开该功能:

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

        您应该能够通过在该 spring 配置中添加 jaxws:handlers 元素来将 jax-ws 处理程序添加到您的端点。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-01-14
          • 1970-01-01
          • 1970-01-01
          • 2017-12-28
          • 2011-03-03
          • 2014-02-18
          • 2021-10-26
          相关资源
          最近更新 更多