i watched too many videos about android webservises
but all them results finished error
"java.net.SocketTimeoutException"
i used
"ksoap2-android-2.5.2.jar"
can you guide me on this
my codes ;
package com.example.acr_soaptest2;
import android.util.Log;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
public class ServiceManager {
private static final String METHOD_NAME = "MySQl_Query";
private static final String NAMESPACE = "http://tempuri.org/";
private static final String SOAP_ACTION = "http://tempuri.org/MySQl_Query";
private static final String URL = "http://localhost:8090/WebService1.asmx";
SoapObject soapObject;
SoapSerializationEnvelope soapSerializationEnvelope;
HttpTransportSE httpTransportSE;
public void PushData(String query) {
soapObject = new SoapObject(NAMESPACE, METHOD_NAME);
soapObject.addProperty("sorgu", query);
soapSerializationEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER12);
soapSerializationEnvelope.dotNet = true;
soapSerializationEnvelope.setOutputSoapObject(soapObject);
httpTransportSE = new HttpTransportSE(URL);
httpTransportSE.debug = true;
try {
httpTransportSE.call(SOAP_ACTION, soapSerializationEnvelope);
SoapPrimitive soapPrimitive=(SoapPrimitive)soapSerializationEnvelope.getResponse();
System.out.println(soapPrimitive.toString());
Log.d("satir:", soapPrimitive.toString());
} catch (Exception ex) {
ex.printStackTrace();
Log.d("satir:", ex.toString());
}
}
}
Related
I'm using msl4j to interact with microsoft products, e.g. emails, calendars. When I call the user informations (without parameters) this will works fine. But, when I try to read messages from the inbox, the call ended with error 404 ("code":"ResourceNotFound","message":"Resource could not be discovered."). I don't know why. The API Permissions seems correct.
import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import com.microsoft.aad.msal4j.ClientCredentialFactory;
import com.microsoft.aad.msal4j.ClientCredentialParameters;
import com.microsoft.aad.msal4j.ConfidentialClientApplication;
import com.microsoft.aad.msal4j.DeviceCode;
import com.microsoft.aad.msal4j.DeviceCodeFlowParameters;
import com.microsoft.aad.msal4j.IAccount;
import com.microsoft.aad.msal4j.IAuthenticationResult;
import com.microsoft.aad.msal4j.IClientCredential;
import com.microsoft.aad.msal4j.MsalException;
import com.microsoft.aad.msal4j.OnBehalfOfParameters;
import com.microsoft.aad.msal4j.PublicClientApplication;
import com.microsoft.aad.msal4j.SilentParameters;
import com.microsoft.aad.msal4j.UserAssertion;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class AppMSAL4J {
private static String userId;
private static String authority;
private static String clientId;
private static String clientSecret;
private static String tenantId;
private static Set<String> scopes;
public static void main(String args[]) throws Exception {
setUpSampleData();
try {
IAuthenticationResult result = acquireToken();
OkHttpClient client = new OkHttpClient().newBuilder().build();
MediaType mediaType = MediaType.parse("application/json");
String bodyString = "";
RequestBody body = RequestBody.create(bodyString, mediaType);
String baseUrl = "https://graph.microsoft.com/v1.0/users/" + userId;
String parameters = "";
// parameters = "/mailfolders('Inbox')/messages";
// parameters = "/messages";
Request request = new Request.Builder()
.url(baseUrl + parameters)
.method("GET", null)
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Bearer " + result.accessToken())
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static IAuthenticationResult acquireToken() throws Exception {
IClientCredential credential = ClientCredentialFactory.createFromSecret(clientSecret);
ConfidentialClientApplication cca = ConfidentialClientApplication
.builder(clientId, credential)
.authority(authority)
.build();
ClientCredentialParameters parameters = ClientCredentialParameters
.builder(scopes)
.build();
return cca.acquireToken(parameters).join();
}
private static void setUpSampleData() {
userId = "b0f***";
tenantId = "fc2***";
authority = "https://login.microsoftonline.com/" + tenantId;
clientId = "b1a***";
clientSecret = "KJ***";
scopes = Collections.singleton("https://graph.microsoft.com/.default");
}
}
I am trying to connect web service with kSOAP Library. code send 4 fields like username and password, name and family to the server but in server everything received null ! this is my code where is the problem?
WebService.java
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.util.Log;
public class WebService {
private static String NAMESPACE = "xxxxxxxxxxxx";
public final static String URL = "xxxxxxxxxxxx";
private static String SOAP_ACTION = "xxxxxxxxxxxxxxx";
private static final String METHOD = "Register";
public static String invokeWS() {
String resTxt = null;
SoapObject request = new SoapObject(NAMESPACE, METHOD);
request.addProperty("username","user");
request.addProperty("password","pass");
request.addProperty("name","MyName");
request.addProperty("family","MyFamily");
Log.v("", ""+request);
SoapSerializationEnvelope envelope =
new SoapSerializationEnvelope( SoapEnvelope.VER12);
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
try {
androidHttpTransport.call(SOAP_ACTION+METHOD, envelope);
SoapPrimitive response = (SoapPrimitive) envelope.getResponse();
resTxt = response.toString();
} catch (Exception e) {
e.printStackTrace();
Log.e("",""+e);
resTxt = "Error !!!!";
}
return resTxt;
}
}
and call invokeWS() in MainActivity.java
AsyncCallWS task = new AsyncCallWS();
//Call execute
task.execute();
private class AsyncCallWS extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... params) {
displayText = WebService.invokeWS();
return null;
}
#Override
protected void onPostExecute(Void result) {
//Set response
Log.v("", "Recive : "+displayText);
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Add This Line To Your Code:
envelope.dotNet=true
I need your help in order to consume the services of this wsdl file:
http://lyrics.wikia.com/server.php?wsdl
For example the service "getArtist" with parameter "artist=U2"
I developed this java code:
public class Constante {
public static final String SOAP_ACTION = "LyricWiki#getArtist";
public static final String METHOD_NAME = "getArtist";
public static final String NAMESPACE = "LyricWiki";
public static final String URL = "http://lyrics.wikia.com/server.php";
public static final String KEY_ARTIST = "artist";
}
import java.io.IOException;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
public class TestWSDL {
public static void run() {
SoapObject soapclient = new SoapObject(Constante.NAMESPACE, Constante.METHOD_NAME);
// Yes you need this one in order to send the whole string or else only
// the first letter
// is going to be send
SoapObject parameters = new SoapObject(Constante.NAMESPACE, Constante.METHOD_NAME);
parameters.addProperty(Constante.KEY_ARTIST, "U2");
soapclient.addProperty(Constante.METHOD_NAME, parameters);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.setOutputSoapObject(soapclient);
HttpTransportSE httpTransportSE = new HttpTransportSE(Constante.URL);
try {
httpTransportSE.call(Constante.SOAP_ACTION, envelope);
Object result = envelope.getResponse();
System.out.println(result);
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
run();
}
}
And I got:
org.xmlpull.v1.XmlPullParserException: unterminated entity ref (position:TEXT ?
I think that my problem is in the class "Constante" but I do not know the right format to use.
Any advice or code solution will be good for me,
Thanks in advance for your help and time
I tested using chartlyrics and I got the lyric,
Now, I share with you my code:
public class Constante {
public static final String SOAP_ACTION = "http://api.chartlyrics.com/SearchLyricDirect";
public static final String METHOD_NAME = "SearchLyricDirect";
public static final String NAMESPACE = "http://api.chartlyrics.com/";
public static final String URL = "http://api.chartlyrics.com/apiv1.asmx";
public static final String KEY_ARTIST = "artist";
public static final String KEY_SONG = "song";
}
import java.io.IOException;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.SoapFault;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.xmlpull.v1.XmlPullParserException;
public class TestWSDL {
public static void run2() throws SoapFault {
SoapObject request = new SoapObject(Constante.NAMESPACE,
Constante.METHOD_NAME);
request.addProperty(Constante.KEY_ARTIST, "U2");
request.addProperty(Constante.KEY_SONG, "One");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(request);
HttpTransportSE androidHttpTransport = new HttpTransportSE(
Constante.URL);
try {
// call the web service method
androidHttpTransport.call(Constante.SOAP_ACTION, envelope);
} catch (Exception e) {
e.printStackTrace();
}// Next task is to get Response and format that response
SoapObject obj;
obj = (SoapObject) envelope.getResponse();
// System.out.println(obj);
System.out.println(obj.getProperty("TrackId"));
System.out.println(obj.getProperty("LyricChecksum"));
System.out.println(obj.getProperty("LyricId"));
System.out.println(obj.getProperty("LyricSong"));
System.out.println(obj.getProperty("LyricArtist"));
System.out.println(obj.getProperty("LyricUrl"));
System.out.println(obj.getProperty("LyricCovertArtUrl"));
System.out.println(obj.getProperty("LyricRank"));
System.out.println(obj.getProperty("LyricCorrectUrl"));
System.out.println(obj.getProperty("Lyric"));
}
public static void main(String[] args) {
try {
run2();
} catch (SoapFault e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I hope to consume the LyricWiki soap api.
Regards.
I try to invoke HTTPS SOAP web service through java code:
URL url = new URL("https://somehost:8181/services/"SomeService?wsdl");
QName qname = new QName("http://services.somehost.com/", "SomeService");
Service service = Service.create(url, qname);
SomeService port = service.getPort(SomeService .class);
port.doSomething();
But get exception:
threw an unexpected exception: javax.xml.ws.soap.SOAPFaultException: Security Requirements not met - No Security header in message
When I analized correct request sample I determined it have to contain header:
<S:Header>
<To xmlns="http://www.w3.org/2005/08/addressing">http://somehost:8181/services/SomeService</To>
<Action xmlns="http://www.w3.org/2005/08/addressing">https://somehost:8181/services/"SomeService/doSomethingRequest</Action>
<ReplyTo xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:3428539e-d645-72ae-adc0-5423c1e68942</MessageID>
<wsse:Security S:mustUnderstand="true">
<wsu:Timestamp wsu:Id="_1" xmlns:ns14="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns13="http://schemas.xmlsoap.org/soap/envelope/">
<wsu:Created>2013-01-15T16:36:30Z</wsu:Created>
<wsu:Expires>2014-01-15T14:06:30Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
So how to add this header to my SOAP request?
I personally add two classes: HeaderHandler and HeaderHandlerResolver:
import java.util.HashSet;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
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);
if (outboundProperty.booleanValue()) {
SOAPMessage message = smc.getMessage();
try {
SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security =
header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken =
security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username =
usernameToken.addChildElement("Username", "wsse");
username.addTextNode("test");
SOAPElement password =
usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("test321");
//Print out the outbound SOAP message to System.out
message.writeTo(System.out);
System.out.println("");
} catch (Exception e) {
e.printStackTrace();
}
} else {
try {
//This handler does nothing with the response from the Web Service so
//we just print out the SOAP message.
SOAPMessage message = smc.getMessage();
message.writeTo(System.out);
System.out.println("");
} catch (Exception ex) {
ex.printStackTrace();
}
}
return outboundProperty;
}
public Set getHeaders() {
// The code below is added on order to invoke Spring secured WS.
// Otherwise,
// http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd
// won't be recognised
final QName securityHeader = new QName(
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security", "wsse");
final HashSet headers = new HashSet();
headers.add(securityHeader);
return headers;
}
public boolean handleFault(SOAPMessageContext context) {
//throw new UnsupportedOperationException("Not supported yet.");
return true;
}
public void close(MessageContext context) {
//throw new UnsupportedOperationException("Not supported yet.");
}
}
And
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 {
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
HeaderHandler hh = new HeaderHandler();
handlerChain.add(hh);
return handlerChain;
}
}
In the HeaderHandler class, you can add needed credentials.
To use them finally:
HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver();
service.setHandlerResolver(handlerResolver);
I have followed the steps mentioned by #LaabidiRaissi. The code works fine but it never appends the security element under the header. I have confirmed it by printing out the outbound SOAP message to System.out. After a deep research, I have found that the SOAPMessage needs to be explicitly saved for reflecting the updated message header.
soapMessage.saveChanges();
For more reference -
Check this link
Sample main Class:
package test;
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.Handler;
// next headers is generated from "NetBeans New Webservice Client"
import sk.firma.wstest.definitions.*;
import sk.firma.wstest.schemas.*;
/**
*
* #author Jan
*/
public class TestWSService {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
try {
WsService service = new WsService();
Ws port = service.getWsKsSoap11();
// This is the block that apply the Ws Security to the request
BindingProvider bindingProvider = (BindingProvider) port;
#SuppressWarnings("rawtypes")
List<Handler> handlerChain = new ArrayList<Handler>();
handlerChain.add(new WSSecurityHeaderSOAPHandler("username", "password"));
bindingProvider.getBinding().setHandlerChain(handlerChain);
// Initialize and Run Service
InVal inVal = new InVal();
ReturnValue retVal = port.test(inVal);
} catch (Exception e) {
e.printStackTrace();
}
}
}
And now WS-Security Header SOAP Handler:
package test;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.TimeZone;
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 WSSecurityHeaderSOAPHandler implements SOAPHandler<SOAPMessageContext> {
private static final String URL_WSSE_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String URL_WSU_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
private final String usernameText;
private final String passwordText;
public WSSecurityHeaderSOAPHandler(String usernameText, String passwordText) {
this.usernameText = usernameText;
this.passwordText = passwordText;
}
public String getCurrentDateTime() {
/* e.g. 2001-10-13T09:00:00Z */
final SimpleDateFormat FORMATTER_DATETIME_NO_MS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
DateFormat dfETC = FORMATTER_DATETIME_NO_MS;
dfETC.setTimeZone(TimeZone.getTimeZone("CET"));
StringBuffer dateETC = new StringBuffer(dfETC.format(new Date()));
dateETC.append('Z');
return dateETC.toString();
}
public String getCurrentDateTimePlusDelay(long delayInSeconds) {
/* e.g. 2001-10-13T09:00:00Z */
final SimpleDateFormat FORMATTER_DATETIME_NO_MS = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
DateFormat dfETC = FORMATTER_DATETIME_NO_MS;
dfETC.setTimeZone(TimeZone.getTimeZone("CET"));
Date date = new Date();
long timeInMsecs = date.getTime();
date.setTime(timeInMsecs + delayInSeconds*1000L);
StringBuffer dateETC = new StringBuffer(dfETC.format(date));
dateETC.append('Z');
return dateETC.toString();
}
#Override
public boolean handleMessage(SOAPMessageContext soapMessageContext) {
Boolean outboundProperty = (Boolean) soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty) {
try {
SOAPEnvelope soapEnvelope = soapMessageContext.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = soapEnvelope.getHeader();
if (header == null) {
header = soapEnvelope.addHeader();
}
SOAPElement securityHeaderElement = header.addChildElement("Security", "wsse", URL_WSSE_NAMESPACE);
securityHeaderElement.addAttribute(soapEnvelope.createName("S:mustUnderstand"), "1");
// Add Timestamp element to "Security" soapHeaderElement
// Sample: <u:Timestamp>
// <u:Created>2011-10-13T08:20:01.183Z</u:Created>
// <u:Expires>2011-10-13T17:25:01.183Z</u:Expires>
// </u:Timestamp>
javax.xml.soap.Name timestampElementName = soapEnvelope.createName("Timestamp", "wsu", URL_WSU_NAMESPACE);
SOAPElement timestampSOAPElement = securityHeaderElement.addChildElement(timestampElementName);
String created = getCurrentDateTime();
String expires = getCurrentDateTimePlusDelay(60L*60L); /* 60 minutes delay */
// Add Created to Timestamp
SOAPElement createdSOAPElement = timestampSOAPElement
.addChildElement("Created"/* local name */, "wsu" /* prefix */, URL_WSU_NAMESPACE);
createdSOAPElement.addTextNode(created);
// Add Expires to Timestamp
SOAPElement expiresSOAPElement = timestampSOAPElement
.addChildElement("Expires"/* local name */, "wsu" /* prefix */,URL_WSU_NAMESPACE);
expiresSOAPElement.addTextNode(expires);
// Add usernameToken to "Security" soapHeaderElement
javax.xml.soap.Name usernameTokenElementName = soapEnvelope.createName("UsernameToken", "wsse",
URL_WSSE_NAMESPACE);
SOAPElement usernameTokenSOAPElement = securityHeaderElement.addChildElement(usernameTokenElementName);
// Add Username to usernameToken
SOAPElement userNameSOAPElement = usernameTokenSOAPElement
.addChildElement("Username"/* local name */, "wsse" /* prefix */, URL_WSSE_NAMESPACE);
userNameSOAPElement.addTextNode(this.usernameText);
// Add password to UsernameToken
javax.xml.soap.Name passwordElementName = soapEnvelope.createName("Password", "wsse", URL_WSSE_NAMESPACE);
SOAPElement passwordSOAPElement = usernameTokenSOAPElement.addChildElement(passwordElementName);
/* Add "Type" attribute to <Password> header element */
//passwordSOAPElement.addAttribute(soapEnvelope.createName("Type", "", ""),
// "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
passwordSOAPElement.addTextNode(this.passwordText);
} catch (Exception e) {
throw new RuntimeException("Error on wsSecurityHandler: " + e.getMessage());
}
}
return true;
}
#Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return true;
}
#Override
public Set<QName> getHeaders() {
// throw new UnsupportedOperationException("Not supported yet.");
final QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
"Security", "wsse");
final HashSet headers = new HashSet();
headers.add(securityHeader);
return headers;
}
}
You can also use Apache wss4j to easily add the header and also encrypt you password.
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecUsernameToken;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.io.ByteArrayOutputStream;
import java.util.Set;
public class WSSecurityHeaderSOAPHandler implements SOAPHandler<SOAPMessageContext> {
private final String usernameText;
private final String passwordText;
public WSSecurityHeaderSOAPHandler(String usernameText, String passwordText) {
this.usernameText = usernameText;
this.passwordText = passwordText;
}
#Override
public boolean handleMessage(SOAPMessageContext context) {
Boolean outboundProperty = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
try {
SOAPMessage soapMessage = context.getMessage();
soapMessage.removeAllAttachments();
SOAPPart soappart = soapMessage.getSOAPPart();
WSSecHeader wsSecHeader = new WSSecHeader();
wsSecHeader.insertSecurityHeader(soappart);
WSSecUsernameToken token = new WSSecUsernameToken();
token.setPasswordType(WSConstants.PASSWORD_DIGEST);
token.setUserInfo(usernameText, passwordText);
token.build(soappart, wsSecHeader);
soapMessage.saveChanges();
} catch (Exception e) {
throw new RuntimeException("Error on wsSecurityHandler: " + e.getMessage());
}
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return false;
}
#Override
public void close(MessageContext context) {
}
#Override
public Set<QName> getHeaders() {
return null;
}
}
And you need to update your request like this:
// This is the block that apply the Ws Security to the request
BindingProvider bindingProvider = (BindingProvider) portType;
List<Handler> handlerChain = new ArrayList<>();
handlerChain.add(new WSSecurityHeaderSOAPHandler("username", "password"));
bindingProvider.getBinding().setHandlerChain(handlerChain);
Maven Dependency:
<dependency>
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
<version>1.6.19</version>
</dependency>
i'm having some issues using Ksoap2 in an android project while conecting to a .net Webservice.
As long as i call the Ws witouth parameters everything works just fine, but when i try to add parameters, the servers never gets them.
here's my code
import java.util.Vector;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class ServicioWeb extends Activity {
SoapObject response;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// String NAMESPACE = "http://tempuri.org/";
String NAMESPACE = "IDBN.WS";
String METHOD_NAME = "getClientesByName";
//String SOAP_ACTION = "http://tempuri.org/getClientesByName";
String SOAP_ACTION = "IDBN.WS/getClientesByName";
//String URL = "http://www.ws.idbnar2.com.ar/wsClientes.asmx";
String URL = "http://www.ws.idbnar2.com.ar/wsClientes.asmx";
SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
PropertyInfo pi = new PropertyInfo();
pi.setName("Nombre");
pi.setValue("RIQUELME");
pi.setType(int.class);
Request.addProperty(pi);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.dotNet = true;
envelope.setOutputSoapObject(Request);
AndroidHttpTransport androidHttpTransport = new AndroidHttpTransport(URL);
ListView Lista = (ListView)findViewById(R.id.Lista);
try
{
androidHttpTransport.call(SOAP_ACTION, envelope);
response = (SoapObject)envelope.getResponse();
String[] Clientes = getStringArrayResponse(response, null);
Lista.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,Clientes));
}
catch(Exception e)
{
Toast toast = Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG);
toast.show();
}
}
public String[] getStringArrayResponse(SoapObject node, Vector<String> strings) {
boolean isFirstCall = false;
if (strings == null) {
isFirstCall = true;
strings = new Vector<String>();
}
int count = response.getPropertyCount();
for (int i = 0; i < count; i++) {
Object obj1 = node.getProperty(i);
if (obj1 instanceof SoapObject) {
// don't recurse empty objects
if (((SoapObject)obj1).getPropertyCount() > 0) {
// recurse into another node to process its nodes/primitives
getStringArrayResponse((SoapObject)obj1, strings);
}
} else if (obj1 instanceof SoapPrimitive) {
strings.add(((SoapPrimitive)obj1).toString());
}
}
// only make this for the original caller
if (isFirstCall) {
return (String[])strings.toArray(new String[strings.size()]);
}
return null;
}
}
I harcode the server side, to return a string + the parameters i send it.. and now all i get it's the hardcoded part, seems like the parameters i add to the soap objets are never receives by the server.
Allready try :
-) removing the "http://" from the namespace on the Webservice
-) not using the "envelope.dotNet = true;"
-) adding the Property directly into the Request
Any idea wha'ts wrong???
These lines confuse me:
PropertyInfo pi = new PropertyInfo();
pi.setName("Nombre");
pi.setValue("RIQUELME");
pi.setType(int.class);
Request.addProperty(pi);
Why do you use a string ("RIQUELME") as value for an integer?
What happens when you run the code? Try setting envelope.debug = true. Trying setting a breakpoint and inspecting the value of envelope.requestDump and envelope.responseDump. That way you can see what is sent and what is received.
pi.setName("Nombre");
pi.setValue("RIQUELME");
pi.setType(int.class);
Request.addProperty(pi);
pi.setValue should either be an integer (1, 2, etc.)
OR
pi.setType should be string.class
Or, you don't need to have pi.setType. If you delete that line, it should work.