Getting certification error in Web Service call - java

I have a web service client which has been used several months, but last days we are getting an error when we execute the invocation to the method.
The error we get is :
[22 mar 2018 09:17:38,828] ERROR com.nisa.sms.EnviarSMS - (EnviarSMS.java:51) - Error al enviar el sms: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
the method is called with axis and this is the code :
public void enviarMensaje(int hospital, java.lang.String telefono, java.lang.String mensaje, javax.xml.rpc.holders.StringHolder respuesta, javax.xml.rpc.holders.StringHolder error) throws java.rmi.RemoteException {
if (super.cachedEndpoint == null) {
throw new org.apache.axis.NoEndPointException();
}
org.apache.axis.client.Call _call = createCall();
_call.setOperation(_operations[1]);
_call.setUseSOAPAction(true);
_call.setSOAPActionURI("");
_call.setEncodingStyle(null);
_call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
_call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
_call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
_call.setOperationName(new javax.xml.namespace.QName("http://webservices.nisa.com/", "enviarMensaje"));
setRequestHeaders(_call);
setAttachments(_call);
try { java.lang.Object _resp = _call.invoke(new java.lang.Object[] {new java.lang.Integer(hospital), telefono, mensaje});
if (_resp instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException)_resp;
}
else {
extractAttachments(_call);
java.util.Map _output;
_output = _call.getOutputParams();
try {
respuesta.value = (java.lang.String) _output.get(new javax.xml.namespace.QName("", "respuesta"));
} catch (java.lang.Exception _exception) {
respuesta.value = (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("", "respuesta")), java.lang.String.class);
}
try {
error.value = (java.lang.String) _output.get(new javax.xml.namespace.QName("", "error"));
} catch (java.lang.Exception _exception) {
error.value = (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("", "error")), java.lang.String.class);
}
}
} catch (org.apache.axis.AxisFault axisFaultException) {
throw axisFaultException;
}
}
this method is included in a Java application and we don't have certification problem in it. The certificate is validated and the problem comes in the line:
java.lang.Object _resp = _call.invoke(new java.lang.Object[] {new java.lang.Integer(hospital), telefono, mensaje});
we have the code of the web service too, the application who contains it is right certificated too.
Anyway I was reviewing the certificates and they are not timed out.
Any idea?
Thank you.

Related

How to fix SimpleDeserializer encountered a child element, which is NOT expected?

I am trying to invoke a SOAP method from Axis 1.4 client generated by Eclipse as follows :
FNCEWS40ServiceLocator locator = new FNCEWS40ServiceLocator();
ObjectReference sourceSpecification = new ObjectReference();
sourceSpecification.setClassId("Document");
sourceSpecification.setObjectStore("OS");
sourceSpecification.setSerializationDuplicate(false);
sourceSpecification.setObjectId("{93040C0F-285E-4613-BC8E-BBB39136D7EE}");
ElementSpecificationType elementSpecificationType = new ElementSpecificationType();
elementSpecificationType.setElementSequenceNumber(0);
elementSpecificationType.setItemIndex(0);
ContentRequestType contentRequestType = new ContentRequestType();
contentRequestType.setElementSpecification(elementSpecificationType);
contentRequestType.setSourceSpecification(sourceSpecification);
ContentRequestType[] array = { contentRequestType };
ContentResponseType[] response = locator.getFNCEWS40MTOMPort().getContent(array);
getContent method implementation :
public com.filenet.www.ns.fnce._2006._11.ws.schema.ContentResponseType[] getContent(
com.filenet.www.ns.fnce._2006._11.ws.schema.ContentRequestType[] request)
throws java.rmi.RemoteException, com.filenet.www.ns.fnce._2006._11.ws.schema.FaultStackType {
if (super.cachedEndpoint == null) {
throw new org.apache.axis.NoEndPointException();
}
org.apache.axis.client.Call _call = createCall();
_call.setOperation(_operations[4]);
_call.setUseSOAPAction(true);
_call.setSOAPActionURI("http://www.filenet.com/ns/fnce/2006/11/ws/MTOM#GetContent");
_call.setEncodingStyle(null);
_call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
_call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);
_call.setProperty(org.apache.axis.AxisEngine.PROP_XML_DECL, Boolean.FALSE);
_call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
_call.setOperationName(new javax.xml.namespace.QName("", "GetContent"));
setRequestHeaders(_call);
setAttachments(_call);
try {
java.lang.Object _resp = _call.invoke(new java.lang.Object[] { request });
if (_resp instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException) _resp;
} else {
extractAttachments(_call);
try {
return (com.filenet.www.ns.fnce._2006._11.ws.schema.ContentResponseType[]) _resp;
} catch (java.lang.Exception _exception) {
return (com.filenet.www.ns.fnce._2006._11.ws.schema.ContentResponseType[]) org.apache.axis.utils.JavaUtils
.convert(_resp, com.filenet.www.ns.fnce._2006._11.ws.schema.ContentResponseType[].class);
}
}
} catch (org.apache.axis.AxisFault axisFaultException) {
MessageContext messageContext = _call.getMessageContext();
String requestXML = messageContext.getRequestMessage() != null
? messageContext.getRequestMessage().getSOAPPartAsString()
: null;
String responseXML = messageContext.getResponseMessage() != null
? messageContext.getResponseMessage().getSOAPPartAsString()
: null;
System.out.println("########## requestXML: " + requestXML);
System.out.println("########## responseXML: " + responseXML);
if (axisFaultException.detail != null) {
if (axisFaultException.detail instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException) axisFaultException.detail;
}
if (axisFaultException.detail instanceof com.filenet.www.ns.fnce._2006._11.ws.schema.FaultStackType) {
throw (com.filenet.www.ns.fnce._2006._11.ws.schema.FaultStackType) axisFaultException.detail;
}
}
throw axisFaultException;
}
}
GetContent Operation definition :
oper = new org.apache.axis.description.OperationDesc();
oper.setName("GetContent");
param = new org.apache.axis.description.ParameterDesc(
new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema", "GetContentRequest"),
org.apache.axis.description.ParameterDesc.IN,
new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema", "GetContentRequest"),
com.filenet.www.ns.fnce._2006._11.ws.schema.ContentRequestType[].class, false, false);
param.setItemQName(
new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema", "ContentRequest"));
oper.addParameter(param);
oper.setReturnType(new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema",
"GetContentResponse"));
oper.setReturnClass(com.filenet.www.ns.fnce._2006._11.ws.schema.ContentResponseType[].class);
oper.setReturnQName(new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema",
"GetContentResponse"));
param = oper.getReturnParamDesc();
param.setItemQName(
new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema", "ContentResponse"));
oper.setStyle(org.apache.axis.constants.Style.DOCUMENT);
oper.setUse(org.apache.axis.constants.Use.LITERAL);
oper.addFault(new org.apache.axis.description.FaultDesc(
new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema", "ErrorStack"),
"com.filenet.www.ns.fnce._2006._11.ws.schema.FaultStackType",
new javax.xml.namespace.QName("http://www.filenet.com/ns/fnce/2006/11/ws/schema", "FaultStackType"),
true));
_operations[4] = oper;
when invoking the client I get the following exception :
Jan 31, 2023 3:08:33 PM org.apache.axis.client.Call invoke
SEVERE: Exception:
org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
at org.apache.axis.encoding.ser.SimpleDeserializer.onStartChild(SimpleDeserializer.java:145)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.filenet.www.ns.fnce._2006._11.ws.MTOM.wsdl.FNCEWS40MTOMBindingStub.getContent(FNCEWS40MTOMBindingStub.java:1268)
at com.filenet.www.ns.fnce._2006._11.ws.MTOM.wsdl.Test.main(Test.java:24)
Exception in thread "main" AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
faultSubcode:
faultString: org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
at org.apache.axis.encoding.ser.SimpleDeserializer.onStartChild(SimpleDeserializer.java:145)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.filenet.www.ns.fnce._2006._11.ws.MTOM.wsdl.FNCEWS40MTOMBindingStub.getContent(FNCEWS40MTOMBindingStub.java:1268)
at com.filenet.www.ns.fnce._2006._11.ws.MTOM.wsdl.Test.main(Test.java:24)
{http://xml.apache.org/axis/}hostname:MY_PC_NAME_HERE
org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
at org.apache.axis.AxisFault.makeFault(AxisFault.java:101)
at org.apache.axis.client.Call.invoke(Call.java:2470)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at com.filenet.www.ns.fnce._2006._11.ws.MTOM.wsdl.FNCEWS40MTOMBindingStub.getContent(FNCEWS40MTOMBindingStub.java:1268)
at com.filenet.www.ns.fnce._2006._11.ws.MTOM.wsdl.Test.main(Test.java:24)
Caused by: org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
at org.apache.axis.encoding.ser.SimpleDeserializer.onStartChild(SimpleDeserializer.java:145)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
... 4 more
I can see in the logs that the request is sent successfully and received success response
requestXML: <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Header><Security soapenv:mustUnderstand="1" xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext"><UsernameToken><Username>myuser</Username><Password>mypassword</Password></UsernameToken></Security></soapenv:Header><soapenv:Body><GetContentRequest xmlns="http://www.filenet.com/ns/fnce/2006/11/ws/schema"><ContentRequest cacheAllowed="false" maxBytes="0"><SourceSpecification classId="Document" objectId="{93040C0F-285E-4613-BC8E-BBB39136D7EE}" objectStore="os" serializationDuplicate="false"/><ElementSpecification elementSequenceNumber="0" itemIndex="0"/></ContentRequest></GetContentRequest></soapenv:Body></soapenv:Envelope>
responseXML: <?xml version="1.0" encoding="UTF-8"?><e:Envelope xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:fn35="http://www.filenet.com/ns/fnce/2005/02/ws/schema" xmlns:fn40m="http://www.filenet.com/ns/fnce/2006/11/ws/MTOM/schema" xmlns:fn40="http://www.filenet.com/ns/fnce/2006/11/ws/schema" xmlns:xop="http://www.w3.org/2004/08/xop/include" xmlns:e="http://schemas.xmlsoap.org/soap/envelope/"><e:Body><GetContentResponse xmlns="http://www.filenet.com/ns/fnce/2006/11/ws/schema"><ContentResponse i:type="fn40:ContentElementResponse" retrievalName="contract.pdf" totalSize="1453230" bufferedSize="1048576" continueFrom="offset=1048576;id={F3FAE2B3-2781-406F-A40F-D7386DE2C5AC};"><SourceSpecification i:type="fn40:ObjectReference" classId="Document" objectId="{93040C0F-285E-4613-BC8E-BBB39136D7EE}" objectStore="MCIDEV"/><ElementSpecification elementSequenceNumber="0"/><Content i:type="fn40:InlineContent"><Binary><xop:Include href="cid:v1-4f309df492ff50f-18607ba7645#mtom.p8ce.filenet.com"/></Binary></Content></ContentResponse></GetContentResponse></e:Body></e:Envelope>
I was able to get request and response in the catch exception as follows :
MessageContext messageContext = _call.getMessageContext();
String requestXML = messageContext.getRequestMessage() != null
? messageContext.getRequestMessage().getSOAPPartAsString()
: null;
String responseXML = messageContext.getResponseMessage() != null
? messageContext.getResponseMessage().getSOAPPartAsString()
: null;
When I copy the request XML and try it in SOAPUI it works fine with no issues.

Java - Override a WebRequest on Web Service Call

Quick background, our company connects to an ERP system (Sage) via web services for some functions. We have both c# (.net) and java code that performs calls to the Web Service (WS). Recently Sage introduced Basic Authentication into their WS.
Please note: This is a JAVA question, but I'll show an example in C# first to explain.
In the c# program, I first would create an object that is for accessing the WS:
var sageService = new CAdxWebServiceXmlCCServiceBasicAuth();
I then set up credential information:
var sageServiceCallContext = SageFactory.Instance.GetCallContext();
sageService.Credentials = new NetworkCredential(SageUser, SagePwd);
sageService.PreAuthenticate = true;
then finally the call to the specific web service method:
sageCustomerSvcResponse = sageService.run(sageServiceCallContext, "YTDPROF", sageCustomerRequestInXml);
When I set up the service object I use a custom class that looks like this:
public class CAdxWebServiceXmlCCServiceBasicAuth : CAdxWebServiceXmlCCService
{
protected override WebRequest GetWebRequest(Uri uri)
{
HttpWebRequest webRequest = (HttpWebRequest)base.GetWebRequest(uri);
NetworkCredential credentials = Credentials as NetworkCredential;
if (credentials != null)
{
string authInfo = "";
if (credentials.Domain != null && credentials.Domain.Length > 0)
{
authInfo = string.Format(#"{0}\{1}:{2}", credentials.Domain, credentials.UserName, credentials.Password);
}
else
{
authInfo = string.Format(#"{0}:{1}", credentials.UserName, credentials.Password);
};
authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
webRequest.Headers["Authorization"] = "Basic " + authInfo;
}
return webRequest;
}
}
What happens is that now, when I perform any call to the web service methods, the GetWebRequest from the class is invoked every time. This is how we implemented basis authentication in c#.
How do I do this in Java?
In the java code currently, I create the service object (that which accesses the web services) this way:
WebServiceInvoker service = new WebServiceInvoker(SageWSURL,"");
and the WebServiceInvoker looks like this (truncated for brevity):
public WebServiceInvoker(String url, String dummy) throws ServiceException, IOException {
serviceLocator = new CAdxWebServiceXmlCCServiceLocator();
service = serviceLocator.getCAdxWebServiceXmlCC(url);
cc = new CAdxCallContext();
cc.setCodeLang("ENG");
cc.setCodeUser("USER");
cc.setPassword("PAWWORD");
cc.setPoolAlias("POOL");
cc.setRequestConfig("adxwss.trace.on=on&adxwss.trace.size=16384&adonix.trace.on=on&adonix.trace.level=3&adonix.trace.size=8");
log = new PrintWriter(new BufferedWriter(new FileWriter("C:/Kalio/service/orders/log.txt")));
}
the webservice locator looks like this:
public class CAdxWebServiceXmlCCServiceLocator extends org.apache.axis.client.Service implements com.adonix.www.WSS.CAdxWebServiceXmlCCService {
public CAdxWebServiceXmlCCServiceLocator() {
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC() throws javax.xml.rpc.ServiceException {
java.net.URL endpoint;
System.out.println("using local Sage Web Servivce URL:" + CAdxWebServiceXmlCC_address);
try {
endpoint = new java.net.URL(CAdxWebServiceXmlCC_address);
}
catch (java.net.MalformedURLException e) {
throw new javax.xml.rpc.ServiceException(e);
}
return getCAdxWebServiceXmlCC(endpoint);
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(java.net.URL portAddress) throws javax.xml.rpc.ServiceException {
try {
com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub _stub = new com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub(portAddress, this);
_stub.setPortName(getCAdxWebServiceXmlCCWSDDServiceName());
return _stub;
}
catch (org.apache.axis.AxisFault e) {
return null;
}
}
and the specific method within that class is this:
public String getCustomer(String constructedXML) throws RemoteException {
**CAdxResultXml result = service.run(cc, "XTDPROF", constructedXML);**
CAdxMessage[] messages = result.getMessages();
for (int i = 0; i<messages.length; i++) {
CAdxMessage message = messages[i];
log.println("X3 get customer message: " + message.getMessage());
log.println("X3 get customer message type: " + message.getType());
}
return result.getResultXml();
}
So my questions is, how to I emulate that override that I see in the .net program in Java? It seems like it would be somewhere in either the service locator or invoker, but the program does not use standard http classes, but this adxwss stuff. I tried a straight c# to java conversion and that way didn't help. I have seen examples where basicAuth is implemented, but not against web service calls.
The c# is pretty clear cut, because once I create the service object using the basicAuth override, every web service calls goes through the orderride. How does that happen in Java?
I'll be happy to provide more info if needed and I'll continue to look/experiment, but at the moment I'm treading water.
Adding:
In tracing through the java code I found the specific web service call (run) where an apache "call" object is created. Is this where basicauth can be added?
public com.adonix.www.WSS.CAdxResultXml run(com.adonix.www.WSS.CAdxCallContext callContext, java.lang.String publicName, java.lang.String inputXml) throws java.rmi.RemoteException {
if (super.cachedEndpoint == null) {
throw new org.apache.axis.NoEndPointException();
}
org.apache.axis.client.Call _call = createCall();
_call.setOperation(_operations[0]);
_call.setUseSOAPAction(true);
_call.setSOAPActionURI("");
_call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
_call.setOperationName(new javax.xml.namespace.QName("http://www.adonix.com/WSS", "run"));
setRequestHeaders(_call);
setAttachments(_call);
try { java.lang.Object _resp = _call.invoke(new java.lang.Object[] {callContext, publicName, inputXml});
if (_resp instanceof java.rmi.RemoteException) {
throw (java.rmi.RemoteException)_resp;
}
else {
extractAttachments(_call);
try {
return (com.adonix.www.WSS.CAdxResultXml) _resp;
} catch (java.lang.Exception _exception) {
return (com.adonix.www.WSS.CAdxResultXml) org.apache.axis.utils.JavaUtils.convert(_resp, com.adonix.www.WSS.CAdxResultXml.class);
}
}
} catch (org.apache.axis.AxisFault axisFaultException) {
throw axisFaultException;
}
}
The solution I came up with is not elegant, but then I'm not a guru in Java, just know enough to be given these tasks.
Our company uses Sage as our ERP system and Sage has a WSDL to define the basic web services it provides.
Sage Web Servicew WSDL
In their latest version of Sage they went with basic authentication, but did not build it into the new WSDL. Since I could not seem to extend the class (CAdxWebServiceXmlCCService), I just copied/pasted a new class called CAdxWebServiceXmlCCServiceBasicAuth. The full code is shown below if anyone ever has need to deal with something like this in a web service.
The key point where BaiscAuth set set up is in the getCAdxWebServiceXmlCC method. I added setPassword and setUserName to the stub that is returned. What this accomplishes is that every time I perform a webservice method call, that stub is now part of the header.
package com.adonix.www.WSS;
import java.net.URL;
import java.util.Base64;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import javax.xml.rpc.ServiceException;
public class CAdxWebServiceXmlCCServiceBasicAuth extends org.apache.axis.client.Service implements com.adonix.www.WSS.CAdxWebServiceXmlCCService {
public CAdxWebServiceXmlCCServiceBasicAuth() {
}
public CAdxWebServiceXmlCCServiceBasicAuth(org.apache.axis.EngineConfiguration config) {
super(config);
}
public CAdxWebServiceXmlCCServiceBasicAuth(java.lang.String wsdlLoc, javax.xml.namespace.QName sName) throws javax.xml.rpc.ServiceException {
super(wsdlLoc, sName);
}
// Use to get a proxy class for CAdxWebServiceXmlCC
private java.lang.String CAdxWebServiceXmlCC_address = "http://10.28.0.7:8124/soap-generic/syracuse/collaboration/syracuse/CAdxWebServiceXmlCC";
public java.lang.String getCAdxWebServiceXmlCCAddress() {
return CAdxWebServiceXmlCC_address;
}
// The WSDD service name defaults to the port name.
private java.lang.String CAdxWebServiceXmlCCWSDDServiceName = "CAdxWebServiceXmlCC";
public java.lang.String getCAdxWebServiceXmlCCWSDDServiceName() {
return CAdxWebServiceXmlCCWSDDServiceName;
}
public void setCAdxWebServiceXmlCCWSDDServiceName(java.lang.String name) {
CAdxWebServiceXmlCCWSDDServiceName = name;
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(String userName,String password) throws javax.xml.rpc.ServiceException {
java.net.URL endpoint;
try {
endpoint = new java.net.URL(CAdxWebServiceXmlCC_address);
}
catch (java.net.MalformedURLException e) {
throw new javax.xml.rpc.ServiceException(e);
}
return getCAdxWebServiceXmlCC(endpoint,userName,password);
}
public com.adonix.www.WSS.CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(java.net.URL portAddress,String userName,String password) throws javax.xml.rpc.ServiceException {
try {
com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub _stub = new com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub(portAddress, this);
_stub.setPortName(getCAdxWebServiceXmlCCWSDDServiceName());
_stub.setPassword(password);
_stub.setUsername(userName);
return _stub;
}
catch (org.apache.axis.AxisFault e) {
return null;
}
}
public void setCAdxWebServiceXmlCCEndpointAddress(java.lang.String address) {
CAdxWebServiceXmlCC_address = address;
}
/**
* For the given interface, get the stub implementation.
* If this service has no port for the given interface,
* then ServiceException is thrown.
*/
public java.rmi.Remote getPort(Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
try {
if (com.adonix.www.WSS.CAdxWebServiceXmlCC.class.isAssignableFrom(serviceEndpointInterface)) {
com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub _stub = new com.adonix.www.WSS.CAdxWebServiceXmlCCSoapBindingStub(new java.net.URL(CAdxWebServiceXmlCC_address), this);
_stub.setPortName(getCAdxWebServiceXmlCCWSDDServiceName());
return _stub;
}
}
catch (java.lang.Throwable t) {
throw new javax.xml.rpc.ServiceException(t);
}
throw new javax.xml.rpc.ServiceException("There is no stub implementation for the interface: " + (serviceEndpointInterface == null ? "null" : serviceEndpointInterface.getName()));
}
/**
* For the given interface, get the stub implementation.
* If this service has no port for the given interface,
* then ServiceException is thrown.
*/
public java.rmi.Remote getPort(javax.xml.namespace.QName portName, Class serviceEndpointInterface) throws javax.xml.rpc.ServiceException {
if (portName == null) {
return getPort(serviceEndpointInterface);
}
java.lang.String inputPortName = portName.getLocalPart();
if ("CAdxWebServiceXmlCC".equals(inputPortName)) {
return getCAdxWebServiceXmlCC();
}
else {
java.rmi.Remote _stub = getPort(serviceEndpointInterface);
((org.apache.axis.client.Stub) _stub).setPortName(portName);
return _stub;
}
}
public javax.xml.namespace.QName getServiceName() {
return new javax.xml.namespace.QName("http://www.adonix.com/WSS", "CAdxWebServiceXmlCCService");
}
private java.util.HashSet ports = null;
public java.util.Iterator getPorts() {
if (ports == null) {
ports = new java.util.HashSet();
ports.add(new javax.xml.namespace.QName("http://www.adonix.com/WSS", "CAdxWebServiceXmlCC"));
}
return ports.iterator();
}
/**
* Set the endpoint address for the specified port name.
*/
public void setEndpointAddress(java.lang.String portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
if ("CAdxWebServiceXmlCC".equals(portName)) {
setCAdxWebServiceXmlCCEndpointAddress(address);
}
else
{ // Unknown Port Name
throw new javax.xml.rpc.ServiceException(" Cannot set Endpoint Address for Unknown Port" + portName);
}
}
/**
* Set the endpoint address for the specified port name.
*/
public void setEndpointAddress(javax.xml.namespace.QName portName, java.lang.String address) throws javax.xml.rpc.ServiceException {
setEndpointAddress(portName.getLocalPart(), address);
}
#Override
public CAdxWebServiceXmlCC getCAdxWebServiceXmlCC() throws ServiceException {
// TODO Auto-generated method stub
return null;
}
#Override
public CAdxWebServiceXmlCC getCAdxWebServiceXmlCC(URL portAddress) throws ServiceException {
// TODO Auto-generated method stub
return null;
}
}

Remove invalid characters from soap response in JAX-WS

I am trying to get the lists present on a sharepoint site using SP webservice.
Lists listsSevice = new Lists(new URL(spSiteURL + "/_vti_bin/Lists.asmx?wsdl"));
listsSevice.setHandlerResolver(new SPHandlerResolver());
spListsServiceIfx = listsSevice.getListsSoap();
// Calling the List Web Service
GetListItemsResponse.GetListItemsResult result = spListsServiceIfx .getListItems(listName, viewName, query, viewFields, rowLimit, queryOptions, webID);
However, I get this error because of some invalid character present in soap response.
com.sun.xml.ws.encoding.soap.DeserializationException: Failed to read a response: javax.xml.bind.UnmarshalException
- with linked exception:
[com.ctc.wstx.exc.WstxParsingException: Illegal character entity: expansion character (code 0x15 at [row,col {unknown-source}]: [1125,122]]
I tried to modify the SOAPMessage to remove invalid characters from response.
public class SOAPMessageHandler implements SOAPHandler<SOAPMessageContext> {
public boolean handleMessage(SOAPMessageContext smc) {
System.out.println("in handleMessage");
Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
System.out.println("outboundProperty: " + outboundProperty);
try {
if (outboundProperty.booleanValue()) {
System.out.println(" SOAP Request ");
} else {
System.out.println(" SOAP Response ");
SOAPMessage message = smc.getMessage();
message.writeTo(System.out);
ByteArrayOutputStream out = new ByteArrayOutputStream();
message.writeTo(out);
String messageAsString = new String(out.toByteArray());
/*smc.setMessage(new SOAPMessage(
stripNonValidXMLCharacters(message.getSOAPPart().toString())));*/
}
} catch (SOAPException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("in soap msg handler..." + e.getMessage());
e.printStackTrace();
}
System.out.println("");
return true;
}
But I get an exception at
SOAPMessage message = smc.getMessage();
The stack trace is:
javax.xml.ws.WebServiceException: javax.xml.soap.SOAPException: org.xml.sax.SAXParseException; lineNumber: 1125; columnNumber: 122; Illegal character entity: expansion character (code 0x15
at [row,col {unknown-source}]: [1125,122]
at com.sun.xml.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:86)
at com.cah.ecm.sharepoint.migrator.util.SOAPMessageHandler.handleMessage(SOAPMessageHandler.java:25)
at com.cah.ecm.sharepoint.migrator.util.SOAPMessageHandler.handleMessage(SOAPMessageHandler.java:1)
at com.sun.xml.ws.handler.HandlerProcessor.callHandleMessageReverse(HandlerProcessor.java:341)
at com.sun.xml.ws.handler.HandlerProcessor.callHandlersResponse(HandlerProcessor.java:214)
at com.sun.xml.ws.handler.ClientSOAPHandlerTube.callHandlersOnResponse(ClientSOAPHandlerTube.java:163)
at com.sun.xml.ws.handler.HandlerTube.processResponse(HandlerTube.java:164)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:651)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:600)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:585)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:482)
at com.sun.xml.ws.client.Stub.process(Stub.java:323)
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:161)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:113)
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:93)
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:144)
at com.sun.proxy.$Proxy28.getListItems(Unknown Source)
at com.cah.ecm.sharepoint.migrator.sharepoint.client.SharepointClient.getListItemNodes(SharepointClient.java:292)
at com.cah.ecm.sharepoint.migrator.sharepoint.client.SharepointClient.getListItems(SharepointClient.java:389)
at com.cah.ecm.sp.jde.main.TestIterateAllSPFiles.main(TestIterateAllSPFiles.java:35)
Please help me with where I am wrong and if there is an alternate way to remove invalid characters from SOAP response.
Thanks!
One option is to implement your own SAAJMetaFactory that will create custom MessageFactory. Like this:
import java.io.IOException;
import java.io.InputStream;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import com.sun.xml.internal.messaging.saaj.soap.SAAJMetaFactoryImpl;
public class OwnSAAJMetaFactoryImpl extends SAAJMetaFactoryImpl {
#Override
protected MessageFactory newMessageFactory(String protocol) throws SOAPException {
final MessageFactory f = super.newMessageFactory(protocol);
return new MessageFactory() {
#Override
public SOAPMessage createMessage(MimeHeaders headers, InputStream in) throws IOException, SOAPException {
in = doCleaingStuff(in);
return createMessage(headers, in);
}
#Override
public SOAPMessage createMessage() throws SOAPException {
return f.createMessage();
}
};
}
private InputStream doCleaingStuff(InputStream in) {
// TODO implement it
return null;
}
}
According to SAAJMetaFactory#getInstance() documentation your OwnSAAJMetaFactoryImpl can be exposed through system property
System.setProperty("javax.xml.soap.MetaFactory", "own.package.OwnSAAJMetaFactoryImpl");
or any of this way
Use the javax.xml.soap.MetaFactory system property.
Use the properties file "lib/jaxm.properties" in the JRE directory. This configuration file is in standard java.util.Properties format and
contains the fully qualified name of the implementation class with the
key being the system property defined above.
Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API will look for
a classname in the file META-INF/services/javax.xml.soap.MetaFactory
in jars available to the runtime.
Default to com.sun.xml.messaging.saaj.soap.SAAJMetaFactoryImpl.

Create a jax-ws client where the message will pass in parent and child form

we are creating a web service client for our client. which sends the request to third party and third party register that client in the CRM. The soap message is creating as per parent and child node basis in the following manner.
<Claim>
<Client_SSN_No>123</Client_SSN_No>
<Other_Detail>
<Address> </Address>
<Phone_No> </Phone_No>
</Other_Detail>
</Claim>
In the above example the Client_SSN_No is passed successfully using getter and setter but if we try to create the message for Other_Detail tag if pass without other_details. like this
<Claim>
<Client_SSN_No>123</Client_SSN_No>
<Other_Detail> </Other_Detail>
<Address> </Address>
<Phone_No> </Phone_No>
</Claim>
Following is my code that invoke the web service.
public java.lang.String consultaXmlStub(BPAval.ParametrosConsultaDTO parametrosConsulta) throws java.rmi.RemoteException
{
org.apache.axis.client.Call _call = createCall();
_call.setOperation(_operations[2]);
_call.setUseSOAPAction(true);
_call.setSOAPActionURI("");
_call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS);
_call.setOperationName(new javax.xml.namespace.QName("http://XYZ", "RegisterClient"));
_call.setTargetEndpointAddress(locator);
setRequestHeaders(_call);
setAttachments(_call);
try
{
java.lang.Object _resp = _call.invoke(new java.lang.Object[] {parametrosConsulta});
if (_resp instanceof java.rmi.RemoteException)
{
throw (java.rmi.RemoteException)_resp;
}
else
{
extractAttachments(_call);
try
{
return (java.lang.String) _resp;
}
catch (java.lang.Exception _exception)
{
return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_resp, java.lang.String.class);
}
}
}
catch (org.apache.axis.AxisFault axisFaultException)
{
System.out.println(axisFaultException.toString());
throw axisFaultException;
}
}

WSSecurityEngine says password was not supplied during callback even though it is provided

I'm in the process of creating a client for a web service. I keep getting the following error:
AxisFault
faultCode: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}InvalidSecurity
faultSubcode:
faultString:
Security Data : General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
faultActor:
faultNode:
faultDetail: {http://xml.apache.org/axis/}
stackTrace:
Security Data : General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
This is my environment here:
Intellij IDEA IDE
Apache Axis
Apache WSS4J 1.5.1
Apache XML Security 1.4.0
JDK 1.6
Max OS X
Although searching on the internet provides a lot of examples of how the security header can be added to the request via XML configuration, my requirement is to do this dynamically via the program. So here is my code:
public class AxisClient implements CallbackHandler {
ServerEnvironment environment;
AxisClient(ServerEnvironment environment) {
this.environment = environment;
}
public enum ServerEnvironment {
LIVE("https://ics2ws.ic3.com/commerce/1.x/transactionProcessor"),
TEST("https://ics2wstest.ic3.com/commerce/1.x/transactionProcessor");
String url;
ServerEnvironment (String url) {
this.url = url;
}
public String getUrl() {
return url;
}
}
public enum Merchant {
TestMerchant ("testpassword");
private String transactionKey;
Merchant(String transactionKey) {
this.transactionKey = transactionKey;
}
public String getTransactionKey() {
return transactionKey;
}
}
public static void main(String[] argv) {
String ani = "7162502800";
String zipCode = "14221";
String ccNum ="5555555555554444";
String expMonth = "01";
String expYear = "15";
String cvv = "123";
String unitPrice = "9.99";
String qty = "2";
try {
new AxisClient(ServerEnvironment.TEST).doAuth(Merchant.TestMerchant, ani, zipCode, ccNum, expMonth, expYear, cvv, String.valueOf(new Date().getTime()), unitPrice, qty);
}
catch (Exception e) {
e.printStackTrace();
}
}
public Boolean doAuth(Merchant merchant, String ani, String zipCode, String ccNum, String expMonth, String expYear, String cvv, String id, String unitPrice, String qty) throws Exception {
Boolean result = false;
RequestMessage request;
BillTo billTo;
Card card;
PurchaseTotals purchaseTotals;
Item item;
Item[] items;
ReplyMessage reply;
try {
// billing info
billTo = new BillTo();
billTo.setPhoneNumber(ani);
billTo.setPostalCode(zipCode);
// card info
card = new Card();
card.setAccountNumber(ccNum);
card.setExpirationMonth(new BigInteger(expMonth));
card.setExpirationYear(new BigInteger(expYear));
card.setCvNumber(cvv);
// currency info
purchaseTotals = new PurchaseTotals();
purchaseTotals.setCurrency("USD");
// item
item = new Item();
item.setId(new BigInteger(id));
item.setUnitPrice(unitPrice);
item.setQuantity(new BigInteger(qty));
// add item to items array
items = new Item[1];
items[0] = item;
// create our request
request = new RequestMessage();
request.setMerchantID(merchant.toString());
request.setCcAuthService(new CCAuthService());
request.getCcAuthService().setRun("true");
// add request specific params
request.setBillTo(billTo);
request.setCard(card);
request.setPurchaseTotals(purchaseTotals);
request.setItem(items);
reply = post(merchant, request);
if (reply != null) {
System.out.println(ReflectionToStringBuilder.toString(reply, ToStringStyle.MULTI_LINE_STYLE));
}
}
catch (Exception e) {
throw e;
}
return result;
}
public EngineConfiguration createConfigurationWithSecurityHeaders(Merchant merchant) throws Exception {
SimpleProvider result;
Handler securityHandler;
SimpleChain requestHandler;
SimpleChain responseHandler;
Handler pivot;
Handler transport;
try {
result = new SimpleProvider();
securityHandler = new WSDoAllSender();
securityHandler.setOption(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
securityHandler.setOption(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
securityHandler.setOption(WSHandlerConstants.PW_CALLBACK_REF, this);
securityHandler.setOption(WSHandlerConstants.USER, merchant.toString());
securityHandler.setOption(WSHandlerConstants.MUST_UNDERSTAND, "false");
requestHandler = new SimpleChain();
requestHandler.addHandler(securityHandler);
responseHandler = new SimpleChain();
responseHandler.addHandler(securityHandler);
pivot = new HTTPSender();
transport = new SimpleTargetedChain(requestHandler, pivot, responseHandler);
result.deployTransport(HTTPTransport.DEFAULT_TRANSPORT_NAME, transport);
}
catch (Exception e) {
throw e;
}
return result;
}
public ReplyMessage post (Merchant merchant, RequestMessage request) throws Exception {
ReplyMessage result;
TransactionProcessorLocator locator;
URL endPoint;
ITransactionProcessorStub stub;
EngineConfiguration configuration;
try {
locator = new TransactionProcessorLocator();
// use client config
configuration = createConfigurationWithSecurityHeaders(merchant);
locator.setEngineConfiguration(configuration);
locator.setEngine(new org.apache.axis.client.AxisClient(configuration));
endPoint = new URL(environment.getUrl());
stub = (ITransactionProcessorStub) locator.getportXML(endPoint);
stub._setProperty(WSHandlerConstants.USER, request.getMerchantID());
stub._setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
stub._setProperty(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
stub._setProperty(WSHandlerConstants.PW_CALLBACK_REF, this);
stub._setProperty(WSHandlerConstants.MUST_UNDERSTAND, "false");
result = stub.runTransaction(request);
}
catch (Exception e) {
throw e;
}
return result;
}
#Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (Callback callback : callbacks) {
System.out.println(ReflectionToStringBuilder.toString(callback, ToStringStyle.MULTI_LINE_STYLE));
if (callback instanceof WSPasswordCallback) {
WSPasswordCallback passwordCallback = (WSPasswordCallback) callback;
switch (Merchant.valueOf(passwordCallback.getIdentifer())) {
case TestMerchant:
passwordCallback.setPassword(Merchant.TestMerchant.getTransactionKey());
System.out.println(ReflectionToStringBuilder.toString(passwordCallback, ToStringStyle.MULTI_LINE_STYLE));
break;
default:
throw new UnsupportedCallbackException(callback, "Unrecognized prompt!");
}
}
else {
throw new UnsupportedCallbackException(callback, "Unrecognized callback!");
}
}
}
}
As you can see from the above, my class implements CallbackHandler and I'm overriding handle() which provides the password for WSPasswordCallback.
Here is the output of the print statement for when I get the callback first:
org.apache.ws.security.WSPasswordCallback#50c713d2[
identifier=TestMerchant
password=<null>
key=<null>
usage=2
passwordType=<null>
]
Here is the output for after setting the password:
org.apache.ws.security.WSPasswordCallback#50c713d2[
identifier=TestMerchant
password=testpassword
key=<null>
usage=2
passwordType=<null>
]
So I'm not really sure why I keep getting that error message. Any help in solving this issue will be greatly appreciated.
Also recommendations for a different approach (axis2, cxf) are welcome.
Here is my full stack trace if it is of any help:
AxisFault
faultCode: {http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}InvalidSecurity
faultSubcode:
faultString:
Security Data : General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:
Security Data : General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2939)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at itg.cybersource.axis.ITransactionProcessorStub.runTransaction(ITransactionProcessorStub.java:1284)
at itg.AxisClient.post(AxisClient.java:208)
at itg.AxisClient.doAuth(AxisClient.java:132)
at itg.AxisClient.main(AxisClient.java:75)
{http://xml.apache.org/axis/}hostname:C02GD302DRJL.local
Security Data : General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
General security error (WSSecurityEngine: Callback supplied no password for: TestMerchant)
at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:222)
at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:129)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2939)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
at javax.xml.parsers.SAXParser.parse(SAXParser.java:395)
at org.apache.axis.encoding.DeserializationContext.parse(DeserializationContext.java:227)
at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:696)
at org.apache.axis.Message.getSOAPEnvelope(Message.java:435)
at org.apache.axis.handlers.soap.MustUnderstandChecker.invoke(MustUnderstandChecker.java:62)
at org.apache.axis.client.AxisClient.invoke(AxisClient.java:206)
at org.apache.axis.client.Call.invokeEngine(Call.java:2784)
at org.apache.axis.client.Call.invoke(Call.java:2767)
at org.apache.axis.client.Call.invoke(Call.java:2443)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at itg.cybersource.axis.ITransactionProcessorStub.runTransaction(ITransactionProcessorStub.java:1284)
at itg.AxisClient.post(AxisClient.java:208)
at itg.AxisClient.doAuth(AxisClient.java:132)
at itg.AxisClient.main(AxisClient.java:75)
After many days of trying very many different things, I finally figured out the answer to my problem. Talk about the problem being in between the keyboard and the chair!!!!!
So without further ado here is what the issue was:
securityHandler.setOption(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PASSWORD_TEXT);
Now WSConstants.PASSWORD_TEXT actually equates to "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText". What I must have really been using is WSConstants.PW_TEXT which equates to "PasswordText" which is exactly what I needed in my code. Once I made the change, everything works beautifully.
Contrary to popular belief, you can do all this entirely in a programmatic manner. You DO NOT need to configure the WSDD xml for you to intercept a message and handle WS-Security in the SOAP header. To tidy up loose ends, here is what the modified methods look like:
public EngineConfiguration createConfigurationWithSecurityHeaders(Merchant merchant) throws Exception {
SimpleProvider result;
Handler securityHandler;
SimpleChain requestHandler;
SimpleChain responseHandler;
Handler pivot;
Handler transport;
try {
result = new SimpleProvider();
securityHandler = new WSDoAllSender();
securityHandler.setOption(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
securityHandler.setOption(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
securityHandler.setOption(WSHandlerConstants.USER, merchant.toString());
securityHandler.setOption(WSHandlerConstants.MUST_UNDERSTAND, "false");
requestHandler = new SimpleChain();
requestHandler.addHandler(securityHandler);
responseHandler = new SimpleChain();
responseHandler.addHandler(securityHandler);
pivot = new HTTPSender();
transport = new SimpleTargetedChain(requestHandler, pivot, responseHandler);
result.deployTransport(HTTPTransport.DEFAULT_TRANSPORT_NAME, transport);
}
catch (Exception e) {
throw e;
}
return result;
}
public ReplyMessage post (Merchant merchant, RequestMessage request) throws Exception {
ReplyMessage result;
TransactionProcessorLocator locator;
URL endPoint;
ITransactionProcessorStub stub;
EngineConfiguration configuration;
try {
locator = new TransactionProcessorLocator();
// use client config
configuration = createConfigurationWithSecurityHeaders(merchant);
locator.setEngineConfiguration(configuration);
locator.setEngine(new org.apache.axis.client.AxisClient(configuration));
endPoint = new URL(environment.getUrl());
stub = (ITransactionProcessorStub) locator.getportXML(endPoint);
stub._setProperty(WSHandlerConstants.PW_CALLBACK_REF, this);
result = stub.runTransaction(request);
}
catch (Exception e) {
throw e;
}
return result;
}
Once these modifications are made, your client will work. Please keep in mind that a few of the settings above are specific to the service I'm integrating with. You might have to tweak these to suit your integration which might require a little trial and error.
Thanks again to all the people who post incredibly knowledgeable articles in SO enabling users like me solve problems we come across every now and then.

Categories