First time working on SOAP services. I need to call this web service. http://demomt.weblite.com.my/TS_Services/SubmissionsService.asmx?WSDL
Here are the 2 out of 11 of the stubs that i have generated using wsimport
I tried for the whole day, but I keep getting this error message. Why? I suspect because i did not pass in the authentication header correctly. But at the same time i'm wondering how come the generated stub does not comes with Authentication header as a method param? is that normal? Need help. I'm so confusing.
Exception in thread "main"
com.sun.xml.internal.ws.fault.ServerSOAPFaultException: Client
received SOAP Fault from server: Server was unable to process request.
---> Object reference not set to an instance of an object. Please see the server log to find more detail regarding exact cause of the
failure.
WebLITETSServicesSoap.java
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
#WebService(name = "WebLITE_TSServicesSoap", targetNamespace = "TransactionalSubmissionsSvcs")
#XmlSeeAlso({
ObjectFactory.class
})
public interface WebLITETSServicesSoap {
#WebMethod(operationName = "GetTemplateList", action = "TransactionalSubmissionsSvcs/GetTemplateList")
#WebResult(name = "GetTemplateListResult", targetNamespace = "TransactionalSubmissionsSvcs")
#RequestWrapper(localName = "GetTemplateList", targetNamespace = "TransactionalSubmissionsSvcs", className = "transactionalsubmissionssvcs.GetTemplateList")
#ResponseWrapper(localName = "GetTemplateListResponse", targetNamespace = "TransactionalSubmissionsSvcs", className = "transactionalsubmissionssvcs.GetTemplateListResponse")
public String getTemplateList();
#WebMethod(operationName = "SendWithXML", action = "TransactionalSubmissionsSvcs/SendWithXML")
#WebResult(name = "SendWithXMLResult", targetNamespace = "TransactionalSubmissionsSvcs")
#RequestWrapper(localName = "SendWithXML", targetNamespace = "TransactionalSubmissionsSvcs", className = "transactionalsubmissionssvcs.SendWithXML")
#ResponseWrapper(localName = "SendWithXMLResponse", targetNamespace = "TransactionalSubmissionsSvcs", className = "transactionalsubmissionssvcs.SendWithXMLResponse")
public String sendWithXML(
#WebParam(name = "xmldoc", targetNamespace = "TransactionalSubmissionsSvcs")
SendWithXML.Xmldoc xmldoc);
#WebMethod(operationName = "SendWithJSON", action = "TransactionalSubmissionsSvcs/SendWithJSON")
#WebResult(name = "SendWithJSONResult", targetNamespace = "TransactionalSubmissionsSvcs")
#RequestWrapper(localName = "SendWithJSON", targetNamespace = "TransactionalSubmissionsSvcs", className = "transactionalsubmissionssvcs.SendWithJSON")
#ResponseWrapper(localName = "SendWithJSONResponse", targetNamespace = "TransactionalSubmissionsSvcs", className = "transactionalsubmissionssvcs.SendWithJSONResponse")
public String sendWithJSON(
#WebParam(name = "emaillist", targetNamespace = "TransactionalSubmissionsSvcs")
String emaillist,
#WebParam(name = "params", targetNamespace = "TransactionalSubmissionsSvcs")
String params);
}
WebLITETSServices.java
import javax.xml.namespace.QName;
import javax.xml.ws.*;
import java.net.MalformedURLException;
import java.net.URL;
#WebServiceClient(name = "WebLITE_TSServices", targetNamespace = "TransactionalSubmissionsSvcs", wsdlLocation = "http://demomt.weblite.com.my/TS_Services/SubmissionsService.asmx?WSDL")
public class WebLITETSServices
extends Service
{
private final static URL WEBLITETSSERVICES_WSDL_LOCATION;
private final static WebServiceException WEBLITETSSERVICES_EXCEPTION;
private final static QName WEBLITETSSERVICES_QNAME = new QName("TransactionalSubmissionsSvcs", "WebLITE_TSServices");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("http://demomt.weblite.com.my/TS_Services/SubmissionsService.asmx?WSDL");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
WEBLITETSSERVICES_WSDL_LOCATION = url;
WEBLITETSSERVICES_EXCEPTION = e;
}
public WebLITETSServices() {
super(__getWsdlLocation(), WEBLITETSSERVICES_QNAME);
}
public WebLITETSServices(WebServiceFeature... features) {
super(__getWsdlLocation(), WEBLITETSSERVICES_QNAME, features);
}
public WebLITETSServices(URL wsdlLocation) {
super(wsdlLocation, WEBLITETSSERVICES_QNAME);
}
public WebLITETSServices(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, WEBLITETSSERVICES_QNAME, features);
}
public WebLITETSServices(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public WebLITETSServices(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
#WebEndpoint(name = "WebLITE_TSServicesSoap")
public WebLITETSServicesSoap getWebLITETSServicesSoap() {
return super.getPort(new QName("TransactionalSubmissionsSvcs", "WebLITE_TSServicesSoap"), WebLITETSServicesSoap.class);
}
#WebEndpoint(name = "WebLITE_TSServicesSoap")
public WebLITETSServicesSoap getWebLITETSServicesSoap(WebServiceFeature... features) {
return super.getPort(new QName("TransactionalSubmissionsSvcs", "WebLITE_TSServicesSoap"), WebLITETSServicesSoap.class, features);
}
private static URL __getWsdlLocation() {
if (WEBLITETSSERVICES_EXCEPTION!= null) {
throw WEBLITETSSERVICES_EXCEPTION;
}
return WEBLITETSSERVICES_WSDL_LOCATION;
}
}
I tried running with TestApplication
public class TestApplication {
public static void main(String[] args) throws MalformedURLException {
MailAdapterApplication adapterApplication = new MailAdapterApplication();
adapterApplication.run();
}
public void run() throws MalformedURLException {
WebLITETSServices services = new WebLITETSServices();
WebLITETSServicesSoap servicesSoap = services.getPort(WebLITETSServicesSoap.class);
Map<String, Object> req_ctx =((BindingProvider)servicesSoap).getRequestContext();
Map<String, List<String>> headers = new HashMap<>();
headers.put("Username",Collections.singletonList("sansun#weblite.com.my"));
headers.put("Password", Collections.singletonList("P#ssW0rd32!"));
headers.put("APIKey", Collections.singletonList("QdrLKxog"));
req_ctx.put(MessageContext.HTTP_REQUEST_HEADERS, headers);
System.out.println(servicesSoap.getTemplateList());
}
}
Client received SOAP Fault from server: Server was unable to process request.
Object reference not set to an instance of an object.
I keep getting this error message. Why?
Indeed you did call the service, but the server returned an error code with error message, where the returned payload has no mapping to any expected return type or soap fault exception. There is no more information in the in the text you've provided.
It would be really usefull to check the response status code and payload which was really returned. How to log the respone payload depends on the webservice library you use (cxf, axis2, ??)
I suspect because i did not pass in the authentication header correctly.
You should confirm that suspission, from the information provided it is not possible to tell. Though if you did not provide any authentication information, it is very possible
But at the same time i'm wondering how come the generated stub does not comes with Authentication header as a method param? is that normal? Need help. I'm so confusing.
I assume under the "Authentication header" you mean AuthHeader header. You may need to enable header generation when invoking the wsimport, as well depends in th framework used. When using wsimport from the default JDK, try to use -XadditionalHeaders parameter
Related
I have the following classes:
WS Interface:
package com.mypackage;
import javax.ejb.Remote;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
#Remote
#SOAPBinding(style = Style.DOCUMENT)
#WebService(name = "MathService", targetNamespace = "http://mypackage.com/")
public interface MathServiceWS {
#WebResult(name = "result", targetNamespace = "http://mypackage.com/")
#RequestWrapper(localName = "addRequest", className = "AddRequest", targetNamespace = "http://mypackage.com/")
#WebMethod(action = "http://mypackage.com/add", operationName = "add")
#ResponseWrapper(localName = "addResponse", className = "AddResponse", targetNamespace = "http://mypackage.com/")
Long add(#WebParam(name = "add", targetNamespace = "http://mypackage.com/") AddBean add);
}
WS Implementation:
package com.mypackage;
import javax.ejb.Stateless;
import javax.jws.WebService;
#Stateless(mappedName = "MathService")
#WebService(serviceName = "MathService", endpointInterface = "com.mypackage.MathServiceWS", portName = "MathServicePort", targetNamespace = "http://mypackage.com/")
public class MathService implements MathServiceWS {
#Override
public Long add(AddBean add) {
Long first = new Long(add.getFirst().intValue());
Long second = new Long(add.getSecond().intValue());
return Long.valueOf(Math.addExact(first.longValue(), second.longValue()));
}
}
The bean:
package com.mypackage;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(
name = "Add",
namespace = "http://mypackage.com/",
propOrder = {
"first",
"second"
}
)
public class AddBean implements Serializable {
private static final long serialVersionUID = -7727938355039425419L;
#XmlElement(required = true)
private Integer first;
#XmlElement(required = true)
private Integer second;
public AddBean() {
}
public Integer getFirst() {
return first;
}
public void setFirst(Integer first) {
this.first = first;
}
public Integer getSecond() {
return second;
}
public void setSecond(Integer second) {
this.second = second;
}
}
After deploying this WS, when I'm adding the WSDL in SoapUI, the add method request is as follows after giving the user input:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:myp="http://mypackage.com/">
<soapenv:Header/>
<soapenv:Body>
<myp:addRequest>
<myp:add>
<first>1</first>
<second>2</second>
</myp:add>
</myp:addRequest>
</soapenv:Body>
</soapenv:Envelope>
Now I want to have the above SOAP request XML in my com.mypackage.MathService.add(AddBean) method with the given user input.
Using JAXB on com.mypackage.AddBean only generates partial request
The WebService Handlers is not useful to fulfill my requirement
Any pointer would be very helpful.
You may create an custom SOAPHandler object and can read the request payload and set it to SOAPMessageContext via custom property. Make sure you set the scope as application.
In your service class, inject the javax.xml.ws.WebServiceContext using #javax.annotation.Resource and access payload set via your custom property.
For example:
1. Create Handler and register it.
public class PopulateSOAPMessagePayloadHandler implements SOAPHandler<SOAPMessageContext> {
public static final String SOAP_MESSAGE_PAYLOAD = "__soap_message_payload";
#Override
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!outboundProperty.booleanValue()) {
// for incoming:
ByteArrayOutputStream bout = new ByteArrayOutputStream(1024);
try {
smc.getMessage().writeTo(bout);
String payload = bout.toString(StandardCharsets.UTF_8.name());
smc.put(SOAP_MESSAGE_PAYLOAD, payload); //Set payload
smc.setScope(SOAP_MESSAGE_PAYLOAD, MessageContext.Scope.APPLICATION); //make it application scope
} catch (SOAPException | IOException e) {
e.printStackTrace();
// handle exception if needed
throw new WebServiceException(e);
}
}
return true;
}
// Other method (no-op) omitted
}
2. Get the payload
public class MathService implements MathServiceWS {
#Resource
private WebServiceContext context;
#Override
public Long add(AddBean add) {
String payload = (String) context.getMessageContext().get(SOAP_MESSAGE_PAYLOAD);
Long first = new Long(add.getFirst().intValue());
Long second = new Long(add.getSecond().intValue());
return Long.valueOf(Math.addExact(first.longValue(), second.longValue()));
}
}
Hope it helps.
You can get full control of the document easily. First lets setup the bean:
#XmlRootElement(name="addRequest")
#XmlAccessorType(XmlAccessType.FIELD) //Probably you don't need this line. it is by default field accessible.
public class AddBean implements Serializable {
private static final long serialVersionUID = -7727938355039425419L;
#XmlElement(name="first",required = true) //you don't need name attribute as field is already exactly the same as soap element
private Integer first;
#XmlElement(name="second",required = true) //you don't need name attribute as field is already exactly the same as soap element
private Integer second;
public AddBean() { }
//Getters and Setters
}
Now, I think this is the part you are looking for. To add custom namespace declarations and set prefix etc. If you are using org.springframework.ws.client.core.support.WebServiceGatewaySupport.getWebServiceTemplate to make SOAP request, then you can do the following:
public class WSCastorClient extends WebServiceGatewaySupport {
public CustomResponseObject callWebService(Addbean add) {
WebServiceTemplate wst = getWebServiceTemplate();
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.afterPropertiesSet();
wst.setMarshaller(marshaller);
wst.setUnmarshaller(marshaller);
wst.afterPropertiesSet();
CustomResponseObject response = (CustomResponseObject)
wst.marshallSendAndReceive(add, new
WebServiceMessageCallback() {
public void doWithMessage(WebServiceMessage message) {
SaajSoapMessage saajSoapMessage = (SaajSoapMessage) message;
SOAPMesage soapMEssage = saajSoapMessage.getSaajMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope soapEnvelope = soapPart.getEnvelope();
SOAPHeader head = soapMessage.getSOAPHeader();
SOAPBody soapBody = soapMessage.getSOAPBody();
//Now you have full control of the soap header, body, envelope. You can add any namespace declaration, prefix, add header element, etc. You can add remove whatever you want.
soapEnvelope.removeNamespaceDeclaration(soapEnvelope.getPrefix()); //clear whatever namespace is there
soapEnvelope.addNamespaceDeclaration("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
soapEnvelope.addNamespaceDeclaration("myp", "http://mypackage.com/");
soapEnvelope.setPrefix("soapenv");
soapHeader.setPrefix("soapenv");
soapBody.setPrefix("soapenv");
Document doc = saajSoapMessage.getDocument();
StringWriter sw = new StringWriter();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(doc), new StreamResult(sw));
}
});
return response;
}
//close off other brackets if I forgot any.
I've developed a SOAP web service with Java7 and JAX-WS. This is an excerpt of the interface:
#WebService(name = "MyWebService",
targetNamespace = "http://www.something.com")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface MyWebServiceInterface
{
#WebMethod(operationName = "handleMsg",
action = "handleMsg")
#Oneway
void handleMsg(#WebParam(name = "MessageHeader",
targetNamespace = "http://www.something.com",
header = true,
partName = "header")
MessageHeader header,
#WebParam(name = "MessageBody",
targetNamespace = "http://www.soemthing.com",
partName = "body")
MessageType body);
}
I've implemented a custom SOAP handler for this web service (it work's fine) to do some additional stuff. In the method handleFault(..) I need to access the original MessageHeader of the web method (see interface above). How can this be done?
public class MyHandler implements SOAPHandler<SOAPMessageContext>
{
// ...
#Override
public boolean handleFault(final SOAPMessageContext context)
{
final Boolean outbound =
( Boolean ) context.get( MessageContext.MESSAGE_OUTBOUND_PROPERTY );
// handle only incoming message which do have a message set
if ( outbound != null && !outbound.booleanValue() && context.getMessage() != null )
{
MessageHeader header =
getOriginalHeaderOfFautlyMessage(); // <-- how can this be done?
}
}
}
SOAPMessage soapMsg = context.getMessage();
SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope();
SOAPHeader soapHeader = soapEnv.getHeader();
Then you will have to extract your header node and unmarshall it.
Java - JDK 1.6.0.7 - WSGEN -version: JAX-WS RI 2.2.3-b01-
I have the following problem:
SOAPBinding binding = (SOAPBinding)((BindingProvider)port).getBinding();
binding.setMTOMEnabled(true);
List<Handler> handlerChain = new ArrayList<Handler>();
handlerChain.addAll(binding.getHandlerChain());
handlerChain.add(new MyHandlerSecurity("admin", "admin"));
binding.setHandlerChain(handlerChain);
With this code the SoapHeader is correct, but the attachment is always a inline base64 text.
//List<Handler> handlerChain = new ArrayList<Handler>();
//handlerChain.addAll(binding.getHandlerChain());
//handlerChain.add(new MyHandlerSecurity("admin", "admin"));
//binding.setHandlerChain(handlerChain);
When handlerChain is commented out, you will see the attachment as an xop reference, but there is no SoapHeader and thus, the client is not authenticated...
How can I add a handler on the client side and enable MTOM correct?
Im not sure if i got the question right, but i think i had your same problem a couple of months ago, so here is my solution:
First you need a HeaderHandler class , wich creates the soap header element, it should look like this:
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext smc) {
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
String AUTH_TK = "http://www.myurl.com:port/subdir/etc/";
String NOPREFIX="";//no prefix
String PREFIX_XMLNS="xmlns";
String value = "123456";
if (outboundProperty.booleanValue()) {
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
//<AuthorizationToken xmlns="http://www.myurl.com:port/subdir/etc/">
SOAPElement authorizationToken = header.addChildElement("AuthorizationToken", PREFIX_XMLNS, AUTH_TK);
//<Token>value</Token>
SOAPElement usernameToken =
authorizationToken.addChildElement("Token", NOPREFIX);
usernameToken.addTextNode(value);
//<Token>value</Token>
SOAPElement usernameToken =
authorizationToken.addChildElement("Token", PREFIX);
usernameToken.addTextNode(value);
} catch (Exception e) {
e.printStackTrace();
}
}
return outboundProperty;
}
public Set<QName> getHeaders() {
return null;
}
public void close(MessageContext arg0) {
}
public boolean handleFault(SOAPMessageContext arg0) {
return false;
}
}
After that you create a HeaderHandlerResolver to handle the header creation and insert it in a handler chain:
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
public class HeaderHandlerResolver implements HandlerResolver {
#SuppressWarnings("unchecked")
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
HeaderHandler hh = new HeaderHandler();
handlerChain.add(hh);
return handlerChain;
}
}
After that, you add in the Client:
try{
//new service instance (your service should be extending javax.xml.ws.Service;)
YourServiceProxy service = new YourServiceProxy();
//calls the header handler resolver ;)
service.setHandlerResolver(new HeaderHandlerResolver());
//get the service
YourService port = (YourService)service.getYourService();
//call the service
port.yourMethod()
} catch (Exception e) {
e.printStackTrace();
}
By the way, i didn't tested this particular header, i modified a previous header handler i had, so it may be not accurate, but i think it's pretty close, i really hope it helps you, try it out and tell us how it comes, i'll try to help you if it still doesn't works.
I generated client java objects using JAX-WS RI. I am trying to make a SOAP request to a web service. Service requires authentication in the header which looks like below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<xsd:authHeader>
<xsd:user>username#gmail.com</xsd:user>
<xsd:password>password1</xsd:password>
</xsd:authHeader>
</soapenv:Header>
<soapenv:Body>
<ns:searchAssetsParam>
<ns:includeSubfolders>true</ns:includeSubfolders>
<ns:resultsPage>2</ns:resultsPage>
</ns:searchAssetsParam>
</soapenv:Body>
</soapenv:Envelope>
The generated java objects have methods for calling the service, creating the objects and constructing the header. But, I am having trouble setting the header while making the call.
Here's the code that I am using:
IpsApiService service = new IpsApiService();
IpsApiPortType port = service.getIpsApiSoapPort();
SearchAssetsParam searchAssetsParam = buildSearchAssetsParam();
SearchAssetsReturn response = port.searchAssets(searchAssetsParam);
buildSearchAssetsParam() constructs the request object.
I created the header object as follows:
AuthHeader header = new AuthHeader();
header.setUser("username#gmail.com");
header.setPassword("password1");
How do I set this AuthHeader to the service request?
Thanks,
Venu
Once I had the same problem. I needed to modify the JAX-WS web service SOAP header at every request. To solve this problem I have created a handler like this:
public class MyHandler implements SOAPHandler<SOAPMessageContext> {
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<QName> 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;
}
}
It adds the needed parameters to my SOAP header and it is invoked on every request. All you need to do is to modify handleMessage method to suit your needs.
It works for me by overriding the public void setAttribute(String namespace, String localName, String value) method.
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);
}
}
}
Create header element like this:
ADESHeaderElement custheader = new ADESHeaderElement(qname, clientserv);
custheader.setActor(null);
When you create your service from classess generated by cxf, add custom interceptor
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());
Your can extend AbstractSoapInterceptor to implement your custom interceptor to handle message.
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();
}
};
}
}
Yes, I did the same that Rangappa Tungal, following this example:
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***();
Link to the example!
I've been asked to rebuild our customer portal, using gwt and connecting to our data using various webservices set up on the server.
I generated all the proxy classes usign the WSDL and Jax-WS/wsimport utility, however when i make the below call:
ReportingApiSoap soap = api.getReportingApiSoap();
ArrayOfReport returnValues = soap.getReports(serverCredentials, true);
My returnValues object is null. I know the webservice itself works because I was able to test it with the same parameters I'm passing in now.
I was previously have some issues sending data to the webservice; that turning out to be the namespaces weren't lining up as they needed to. I suspect something similar is happening here, but haven't been able to figure out what yet.
Anyone ever run into something similiar before? Or if not any idea how I can check the raw xml I'm getting out of the webservice call? That way I can track the problem a step furthur.
-Ian
My Credentials object:
public class ApiCredentials {
#XmlElement(name = "Id", namespace="http://mycompany.com")
protected String id;
#XmlElement(name = "Login", namespace="http://mycompany.com")
protected String login;
#XmlElement(name = "Password", namespace="http://mycompany.com")
protected String password;
...
}
ArrayofReport:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ArrayOfReport", propOrder = {
"report"
})
public class ArrayOfReport {
#XmlElement(name = "Report", nillable = true)
protected List<Report> report;
public List<Report> getReport() {
if (report == null) {
report = new ArrayList<Report>();
}
return this.report;
}
}
Webservice call:
#WebMethod(operationName = "GetReports", action = "http://mycompany.com/GetReports")
#WebResult(name = "GetReportsResult", targetNamespace = "http://mycompany.com")
#RequestWrapper(localName = "GetReports", targetNamespace = "http://mycompany.com", className = "com.mycompany.customerportal.server.GetReports")
#ResponseWrapper(localName = "GetReportsResponse", targetNamespace = "http://mycompany.com", className = "com.mycompany.customerportal.server.GetReportsResponse")
public ArrayOfReport getReports(
#WebParam(name = "credentials", targetNamespace = "http://mycompany.com")
ApiCredentials credentials,
#WebParam(name = "includeFields", targetNamespace = "http://mycompany.com")
boolean includeFields);
I recommend creating a mock web service (e.g. using soapUI). This will allow you to see and validate the request XML against your WSDL. You can cut'n'paste/edit mock responses to the client to see the effect.
JAX-WS implementations are a dime-a-dozen, so any further options depend on the client technology in your runtime. I would ensure that validation is enabled (this might be implemented as a feature, for example).