如何使用wsdl生成的java对象发出soap请求时添加soap标头

我使用JAX-WS RI生成了客户端java对象。 我正在尝试向Web服务发出SOAP请求。 服务需要在标头中进行身份validation,如下所示:

   username@gmail.com password1     true 2    

生成的java对象具有调用服务,创建对象和构造头的方法。 但是,我在拨打电话时设置标头时遇到问题。

这是我正在使用的代码:

 IpsApiService service = new IpsApiService(); IpsApiPortType port = service.getIpsApiSoapPort(); SearchAssetsParam searchAssetsParam = buildSearchAssetsParam(); SearchAssetsReturn response = port.searchAssets(searchAssetsParam); 

buildSearchAssetsParam()构造请求对象。 我创建了头对象,如下所示:

 AuthHeader header = new AuthHeader(); header.setUser("username@gmail.com"); header.setPassword("password1"); 

如何将此AuthHeader设置为服务请求?

谢谢,Venu

一旦我遇到同样的问题。 我需要在每次请求时修改JAX-WS Web服务SOAP标头。 为了解决这个问题,我创建了一个这样的处理程序:

 public class MyHandler implements SOAPHandler { private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class); private String username; private String password; @Override public boolean handleMessage(SOAPMessageContext context) { try { SOAPMessage message = context.getMessage(); SOAPHeader header = message.getSOAPHeader(); SOAPEnvelope envelope = message.getSOAPPart().getEnvelope(); if (header == null) { header = envelope.addHeader(); } QName qNameUserCredentials = new QName("https://your.target.namespace/", "UserCredentials"); SOAPHeaderElement userCredentials = header.addHeaderElement(qNameUserCredentials); QName qNameUsername = new QName("https://your.target.namespace/", "Username"); SOAPHeaderElement username = header.addHeaderElement(qNameUsername ); username.addTextNode(this.username); QName qNamePassword = new QName("https://your.target.namespace/", "Password"); SOAPHeaderElement password = header.addHeaderElement(qNamePassword); password.addTextNode(this.password); userCredentials.addChildElement(username); userCredentials.addChildElement(password); message.saveChanges(); //TODO: remove this writer when the testing is finished StringWriter writer = new StringWriter(); message.writeTo(new StringOutputStream(writer)); LOGGER.debug("SOAP message: \n" + writer.toString()); } catch (SOAPException e) { LOGGER.error("Error occurred while adding credentials to SOAP header.", e); } catch (IOException e) { LOGGER.error("Error occurred while writing message to output stream.", e); } return true; } //TODO: remove this class after testing is finished private static class StringOutputStream extends OutputStream { private StringWriter writer; public StringOutputStream(StringWriter writer) { this.writer = writer; } @Override public void write(int b) throws IOException { writer.write(b); } } @Override public boolean handleFault(SOAPMessageContext context) { LOGGER.debug("handleFault has been invoked."); return true; } @Override public void close(MessageContext context) { LOGGER.debug("close has been invoked."); } @Override public Set getHeaders() { LOGGER.debug("getHeaders has been invoked."); return null; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; } } 

它将所需的参数添加到我的SOAP标头中,并在每个请求上调用它。 您需要做的就是修改handleMessage方法以满足您的需求。

它适用于重写public void setAttribute(String namespace, String localName, String value)方法。

 import javax.xml.namespace.QName; import org.apache.axis.Constants; import org.apache.axis.message.SOAPHeaderElement; @SuppressWarnings("serial") public class ADESHeaderElement extends SOAPHeaderElement { public ADESHeaderElement(QName qname, Object value) { super(qname, value); } @Override public void setAttribute(String namespace, String localName, String value) { if (!Constants.ATTR_MUST_UNDERSTAND.equals(localName)) { // Or any other attribute name you'd want to avoid super.setAttribute(namespace, localName, value); } } } 

像这样创建标题元素:

  ADESHeaderElement custheader = new ADESHeaderElement(qname, clientserv); custheader.setActor(null); 

当您从cxf生成的classess创建服务时,添加自定义拦截器

 Service service = new MyService(wsdlURL, new QName("http://myservice.com/MyService/", "MyService")); MyPort port = service.getMyPort(); Client client = ClientProxy.getClient(port); // adding interceptor programmatically client.getOutInterceptors().add(new MyHeaderHandler()); 

您可以扩展AbstractSoapInterceptor以实现自定义拦截器来处理消息。

 import javax.xml.bind.JAXBException; import javax.xml.namespace.QName; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.headers.Header; import org.apache.cxf.jaxb.JAXBDataBinding; import org.apache.cxf.phase.Phase; import com.rpc.core.utils.DomainContext; public class MyHeaderHandler extends AbstractSoapInterceptor { /** * Constructor */ public MyHeaderHandler() { super(Phase.PRE_LOGICAL); } @Override public void handleMessage(org.apache.cxf.binding.soap.SoapMessage message) throws org.apache.cxf.interceptor.Fault { try { message.getHeaders().add(new Header(new QName("MyCustomHeader"),"value", new JAXBDataBinding(String.class))); } catch (JAXBException e) { e.printStackTrace(); } }; } } 

是的,我按照这个例子做了同样的Rangappa Tungal:

 Service w = new ServiceLocator(); ServiceSoap ws = new ServiceSoapStub(new URL(w.getServiceSoapAddress()),w); Stub mystub = (Stub) ws; AuthHeader up = new AuthHeader("user","pass"); mystub.setHeader("namespace", "AuthHeader", up); ws.get***(); 

链接到示例!