【问题标题】:Add Header To all outgoing CXF request将标头添加到所有传出的 CXF 请求
【发布时间】:2017-04-22 00:36:25
【问题描述】:

是否可以从客户端向所有传出的 cxf 连接添加标头。

使用 Spring 3.0 和 CXF 2.6.0

【问题讨论】:

  • 连接?你是说请求吗?那么是的,这是可能的。
  • 是的请求,如果是这样,如何:)?
  • CXF 拦截器是另一种选择。 stackoverflow.com/a/16743238/1030409

标签: spring client cxf


【解决方案1】:

我想在这里给我两分钱。我在我的帖子中解决了同样的情况-

http://saurzcode.in/2014/05/08/adding-header-to-soap-request-using-cxf-2/

弹簧配置:-

<jaxws:client id="mywebServiceClient"
    serviceClass="com.saurzcode.TestService"
    address="http://saurzcode.com:8088/mockTestService">

    <jaxws:binding>
        <soap:soapBinding version="1.2" mtomEnabled="true" />
    </jaxws:binding>
</jaxws:client>
<cxf:bus>
    <cxf:outInterceptors>
        <bean class="com.saurzcode.ws.caller.SoapHeaderInterceptor" />
    </cxf:outInterceptors>
</cxf:bus>

CXF 拦截器 -

public class SoapHeaderInterceptor extends AbstractSoapInterceptor {

    public SoapHeaderInterceptor() {
        super(Phase.POST_LOGICAL);
    }

    @Override
    public void handleMessage(SoapMessage message) throws Fault {
        List<Header> headers = message.getHeaders();
        TestHeader testHeader = new TestHeader();
        JAXBElement<TestHeader> testHeaders = new ObjectFactory()
        .createTestHeader(testHeader);

        try {
            Header header = new Header(testHeaders.getName(), testHeader,
            new JAXBDataBinding(TestHeader.class));
            headers.add(header);
            message.put(Header.HEADER_LIST, headers);

        } catch (JAXBException e) {
            e.printStackTrace();
        }

    }

【讨论】:

  • 它工作正常,除了我的内部元素没有命名空间前缀 - 像这样:
    ns2:TestHeader>
    有人可以帮忙吗?
  • 如何在没有spring的情况下添加拦截器?只使用 cxf wsdl2java 客户端
【解决方案2】:

我已经知道两种方法。一种是创建您的 SOAP 处理程序并将其注册为您的 Spring 配置中的JAX-WS 处理程序。

查看my answer here 如何创建 SOAP 处理程序。当您希望标头出现在响应(传出请求)中时,请不要忘记您需要检查消息是否出站,这样可以:

Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outbound) {
    //Modify your header.
}

另一种可能更简单的方法。将标头直接放入 CXF 响应上下文中。请注意,此示例仅是概念证明,我不知道您在响应中需要凭据的实际情况。它将显示如何将用户凭据对象添加到标题中,您必须根据需要对其进行修改。

private void modifyResponse(String username, String password) {
    UserCredentials authHeader = new UserCredentials();
    authHeader.setUsername(username);
    authHeader.setPassword(password);
    ArrayList<Header> headers = new ArrayList<Header>(1);
    try {
        Header soapHeader = new Header(
                new QName("http://yournamespaceuri.com/something", "UserCredentials"),
                authHeader,
                new JAXBDataBinding(UserCredentials.class));
        headers.add(soapHeader);
    } catch (JAXBException ex) {
        LOGGER.error("Exception trying to serialize header: {}", ex);
    }
    ((BindingProvider) proxy).getResponseContext().put(Header.HEADER_LIST, headers);
}

此方法需要在您的客户端发出请求后立即调用。

【讨论】:

  • 对不起,我知道这条消息是很久以前发布的,但是这里的代理对象是什么?它从哪里来的?谢谢
  • @AliH 这是一个有效的问题。我认为代理是注入 WebServiceContext 例如@Resource private WebServiceContext proxy;参考这个cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest/…?
  • proxy 是来自 Service 类的 Web 服务端口类型的实例。例如:Service service = Service.create(url, qname); YourWebService proxy = service.getPort(YourWebService.class); 其中 url 是您发布的端点 URL,qname 是与生成的服务类的命名空间映射。
【解决方案3】:

我就是这样做的,

Spring.xml

<import resource="classpath:META-INF/cxf/cxf.xml" />

<bean id="cxf" class="org.apache.cxf.bus.spring.SpringBus">
    <property name="outInterceptors">
        <list>
            <ref bean="headerInterceptor"/>
        </list>
    </property>
    <property name="inInterceptors">
        <list>
            <ref bean="headerInterceptor"/>
        </list>
    </property>
</bean>

<bean id="headerInterceptor" class="logging.Interceptor"/>

拦截器:

 public class UUIDHeaderInterceptor extends AbstractPhaseInterceptor {


private static final Logger logger = LoggerFactory.getLogger(UUIDHeaderInterceptor.class);



public UUIDHeaderInterceptor() {
    super(Phase.RECEIVE);

}

@Override
public void handleMessage(Message message) throws Fault {

        Map<String, List<String>> headers = (Map<String, List<String>>) message.get(Message.PROTOCOL_HEADERS);
        headers.put(REQUEST_ID_ATTRIBUTE_NAME, Arrays.asList(new String[]{"TEST"}));

   }
 }

@Override
public void handleFault(Message message) {
    handleMessage(message);
  }

【讨论】:

    猜你喜欢
    • 2016-04-10
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 2012-12-01
    • 2017-02-15
    相关资源
    最近更新 更多