CXF:添加SOAP标头以进行请求

时间:2016-01-06 15:49:07

标签: cxf soapheader

我尝试通过BindingProvider.getRequestContext().put(Header.HEADER_LIST, headers)将SOAP标头添加到我的请求中,但缺少SOAP标头。我的代码如下:

CXF生成的标准WebService类:

@WebService(targetNamespace = "...", name = "...")
@XmlSeeAlso({...ObjectFactory.class})
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface MyService {
    ... 
    @WebMethod(operationName = "...")
    public Future<?> sendAsync(
        @WebParam(partName = "parameters", name = "...", targetNamespace = "...")
        MyRequestMessageType parameters,
        @WebParam(name = "asyncHandler", targetNamespace = "")
        AsyncHandler<MyResponseMessageType> asyncHandler
    );
}

CXF生成的标准WebServiceClient类

@WebServiceClient(name = "...", wsdlLocation = "...", targetNamespace = "...") 
public class MyService_Service extends Service {
    ...
    @WebEndpoint(name = "...")
    public MyService getVendorManagementService() {
        return super.getPort(MY_SERVICE, MyService.class);
    }
}

发送我的请求的类:

@Inject
private MyService_Service myService;

public void send() {        
    BindingProvider port = (BindingProvider) myService.getWebEndpointPort(); 
    port.getRequestContext().put("thread.local.request.context", "true");

    List<Header> headers = getHeaders(port.getRequestContext());
    Header messageIDHeader = new Header(new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa"), "some_id", new JAXBDataBinding(String.class));
    headers.add(messageIDHeader);
    port.getRequestContext().put(Header.HEADER_LIST, headers);        

    MyRequestMessageType message = messageCreator.createMyRequestMessage();
    MyAsyncHandler asyncHandler = new MyAsyncHandler();
    ((MyService) port).sendAsync(message, asyncHandler);
}

private static List<Header> getHeaders(Map<String, Object> messageContext) {
    if (messageContext == null) {
        return null;
    }
    List<Header> headers = CastUtils.cast((List<?>) messageContext.get(Header.HEADER_LIST));
    if (headers == null){
        return new ArrayList<Header>();
    }
    return headers;
}

它会生成正确的请求,但缺少SOAP Header。该请求仅包含SOAP Body:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
  ... the message is OK
  </soap:Body>
</soap:Envelope>

我不知道出了什么问题。 谢谢你的任何建议。

2 个答案:

答案 0 :(得分:0)

现在我直接使用WebService(MyService)而不是从WebServiceClient获取它并且它可以工作。我的send方法如下:

@Inject
private MyService port;

public void send() {
    ((BindingProvider) port).getRequestContext().put("thread.local.request.context", "true");

    List<Header> headers = getHeaders(((BindingProvider) port).getRequestContext());
    Header messageIDHeader = new Header(new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa"), "some_id", new JAXBDataBinding(String.class));
    headers.add(messageIDHeader);
    ((BindingProvider) port).getRequestContext().put(Header.HEADER_LIST, headers);        

    MyRequestMessageType message = messageCreator.createMyRequestMessage();
    MyAsyncHandler asyncHandler = new MyAsyncHandler();
    port.sendAsync(message, asyncHandler);
}

答案 1 :(得分:0)

另一种获得正确 ctx 映射的方法如下:

org.apache.cxf.endpoint.Client p = 
  org.apache.cxf.frontend.ClientProxy.getClient(myService);
Map<String, Object> ctx = p.getRequestContext();
ctx.put(Header.HEADER_LIST, headers);