SOAP Problem in Appcelerator Titanium (using suds.js) - does not work with Android
we're programming a little "home device control" app within our studying using Appcelerator Titanium. We programmed a back-end in Java which is connected to our front-end apps with an interface which can receipt requests through a SOAP call. Therefore we used the suds.js. All works fine with iOS but nothing seems to happen in Android and we do not know why. :-( First of all we want to provide a user-login to authorize the user. Name and password will be send to the back-end which provides a user-token afterwards. In iOS all works fine, Android seems to have a problem with the following code which I noticed through different test comments because the comments within this code are not shown in the developer console:
suds.invoke('login', callparams, function(xmlDoc) {
Titanium.API.info("Test after function is called");
var results = xmlDoc.documentElement.getElementsByTagName('return');
Titanium.API.info("another test comment");
Titanium.API.info(results);
if (results && results.length>0) {
var isAdmin = results.item(0).getElementsByTagName('admin');
if(isAdmin.item(0).开发者_C百科text == "true") {
Titanium.API.info("isAdmin: true");
Titanium.App.Properties.setBool('isAdmin', true);
} else {
Titanium.API.info("isAdmin: false");
Titanium.App.Properties.setBool('isAdmin', false);
}
var userToken = results.item(0).getElementsByTagName('userToken');
Titanium.API.info("userToken: " + userToken.item(0).text);
Titanium.App.Properties.setString('userToken', userToken.item(0).text);
Titanium.App.Properties.setString('username', username.value);
//Rein oder raus???
//alert("Login erfolgreich! \n isAdmin: " + isAdmin.item(0).text + " \n userToken: " + userToken.item(0).text)
//Aufruf Hauptmenüfenster
openWindow('js/menue.js', 'Hauptmenü', true);
} else {
var resultsError = xmlDoc.documentElement.getElementsByTagName('S:Fault');
var errorString = resultsError.item(0).getElementsByTagName('faultstring');
Titanium.API.info("error: " + errorString.item(0).text);
alert(errorString.item(0).text);
}
});
The url-link to the back-end: http://localhost:8888 Localhost because the back-end is running on my desktop for testing. I am not sure if the request will be receipt of the back-end at all.
Thanks for help in advance! Best regards, Stefan
The whole code: Part of app.js: (sorry for german code comments)
// Checkbox bekommt Eventlistener, der Angibt ob das Passwort gespeichert werden soll.
checkbox.addEventListener('click', function(e) {
if(Titanium.App.Properties.getBool('loginAuto') == true){
imageUrl = 'images/checkbox_unchecked.png';
Titanium.App.Properties.setBool('loginAuto', false);
Titanium.API.info('Setze loginAuto = false');
} else if(Titanium.App.Properties.getBool('loginAuto') == false){
imageUrl = 'images/checkbox_checked.png';
Titanium.App.Properties.setBool('loginAuto', true);
Titanium.API.info('Setze loginAuto = true');
}
checkbox.image = imageUrl;
});
// Loginbutton bekommt Eventlistener, der bei Klick den Login durchführt.
loginBtn.addEventListener('click', function(e) {
// Datenbank wird erneut initialisiert, falls noch nicht vorhanden
var db_userdata = Titanium.Database.install("db/myHome4.sqlite", 'myHome4');
// Für den Fall das Benutzername und Passwort gespeichert werden sollen, werden sie hier in die DB geschrieben.
if(Titanium.App.Properties.getBool('loginAuto') == true){
Titanium.API.info('Speichere Name und Password in der Datenbank.');
db_userdata.execute("DELETE FROM login");
db_userdata.execute("INSERT INTO login (id, name, password) VALUES (1, ?, ?)", username.value, password.value);
Titanium.App.Properties.setString('loginName', username.value);
Titanium.App.Properties.setString('loginPassword', password.value);
} else {
db_userdata.execute("DELETE FROM login");
}
db_userdata.close();
var url = Titanium.App.Properties.getString('url') + '/services?wsdl';
var callparams = {
username: username.value,
password: password.value
};
/* Im Folgenden der suds Client (SOAP Client), der die SOAP Abfragen ausführt und Werte zurück liefert.
Login-Vorgang und Aufruf des Hauptmenüfensters
*/
Titanium.API.info(Titanium.App.Properties.getString('url'));
var suds = new SudsClient({
endpoint: url,
targetNamespace: Titanium.App.Properties.getString('url')
});
Titanium.API.info("TEST1111");
try {
Titanium.API.info("Test before function");
suds.invoke('login', callparams, function(xmlDoc) {
Titanium.API.info("Test after function is called");
var results = xmlDoc.documentElement.getElementsByTagName('return');
Titanium.API.info("another test comment");
Titanium.API.info(results);
if (results && results.length>0) {
var isAdmin = results.item(0).getElementsByTagName('admin');
if(isAdmin.item(0).text == "true") {
Titanium.API.info("isAdmin: true");
Titanium.App.Properties.setBool('isAdmin', true);
} else {
Titanium.API.info("isAdmin: false");
Titanium.App.Properties.setBool('isAdmin', false);
}
var userToken = results.item(0).getElementsByTagName('userToken');
Titanium.API.info("userToken: " + userToken.item(0).text);
Titanium.App.Properties.setString('userToken', userToken.item(0).text);
Titanium.App.Properties.setString('username', username.value);
//Rein oder raus???
//alert("Login erfolgreich! \n isAdmin: " + isAdmin.item(0).text + " \n userToken: " + userToken.item(0).text)
//Aufruf Hauptmenüfenster
openWindow('js/menue.js', 'Hauptmenü', true);
} else {
var resultsError = xmlDoc.documentElement.getElementsByTagName('S:Fault');
var errorString = resultsError.item(0).getElementsByTagName('faultstring');
Titanium.API.info("error: " + errorString.item(0).text);
alert(errorString.item(0).text);
}
});
} catch(e) {
alert(e);
Ti.API.error('Error: ' + e);
}
});
/* Eventlistener für den Logout-Button, bei Klick wird das Menüfenster geschlossen und die Variablen username, userToken und is
isadmin gelöscht
*/
Ti.App.addEventListener('eventLogout', function(event)
{
Titanium.App.Properties.removeProperty("username");
Titanium.App.Properties.removeProperty("userToken");
Titanium.App.Properties.removeProperty("isAdmin");
Titanium.API.info("Lösche Einstellungen...");
win2.close();
});
suds.js:
/*
* Definition der Parameter, die für SOAP Client notwendig sind
*
*/
var url = Titanium.App.Properties.getString('url') + '/services?wsdl';
/**
* Suds: A Lightweight JavaScript SOAP Client
* Copyright: 2009 Kevin Whinnery (http://www.kevinwhinnery.com)
* License: http://www.apache.org/licenses/LICENSE-2.0.html
* Source: http://github.com/kwhinnery/Suds
*/
function SudsClient(_options) {
function isBrowserEnvironment() {
try {
if (window && window.navigator) {
return true;
} else {
return false;
}
} catch(e) {
return false;
}
}
function isAppceleratorTitanium() {
try {
if (Titanium) {
return true;
} else {
return false;
}
} catch(e) {
return false;
}
}
//Funktion zur Erweiterung von Variablen (Objekten)
function extend(original, extended) {
for (var key in (extended || {})) {
if (original.hasOwnProperty(key)) {
original[key] = extended[key];
}
}
return original;
}
//Prüfung ob ein Objekt ein Array ist
function isArray(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
//Holt per get eine XMLHTTPRequest Object
function getXHR() {
return Titanium.Network.createHTTPClient();
}
//Aus einem String wird ein XML DOM object
function xmlDomFromString(_xml) {
xmlDoc = Titanium.XML.parseString(_xml);
return xmlDoc;
}
// Konvertiert ein Javascript OBbjekt in ein XML string
function convertToXml(_obj, namespacePrefix) {
var xml = '';
if (isArray(_obj)) {
for (var i = 0; i < _obj.length; i++) {
xml += convertToXml(_obj[i], namespacePrefix);
}
} else {
for (var key in _obj) {
if (namespacePrefix && namespacePrefix.length) {
xml += '<' + namespacePrefix + ':' + key + '>';
} else {
xml += '<'+key+'>';
}
if (isArray(_obj[key]) || (typeof _obj[key] == 'object' && _obj[key] != null)) {
xml += convertToXml(_obj[key]);
}
else {
xml += _obj[key];
}
if (namespacePrefix && namespacePrefix.length) {
xml += '</' + namespacePrefix + ':' + key + '>';
} else {
xml += '</'+key+'>';
}
}
}
return xml;
}
// Client Konfiguration
var config = extend({
endpoint:'https://localhost:8888/service',
targetNamespace: 'https://localhost:8888/service?wsdl',
envelopeBegin: '',
envelopeEnd: ''
},_options);
// Aufruf web service
this.invoke = function(_soapAction,_body,_callback) {
//Erstelle request body
var body = _body;
//Erlaubt einen String in einen XML body einzufügen - Ansonsten wird dieser aus einem XML Objekt erzeugt.
if (typeof body !== 'string') {
body = '<fron:'+_soapAction+'>';
body += convertToXml(_body);
body += '</fron:'+_soapAction+'>';
}
var ebegin = config.envelopeBegin;
config.envelopeBegin = ebegin.replace('PLACEHOLDER', config.targetNamespace);
//Erzeugt den Soapaction header
var soapAction = '';
if (config.targetNamespace.lastIndexOf('/') != config.targetNamespace.length - 1) {
soapAction = config.targetNamespace+'/'+_soapAction;
}
else {
soapAction = config.targetNamespace+_soapAction;
}
//Sende das XML document per HTTP_Post zum service endpoint
var xhr = getXHR();
xhr.onload = function() {
_callback.call(this, xmlDomFromString(this.responseText));
};
xhr.open('POST',config.endpoint);
xhr.setRequestHeader('Content-Type', 'text/xml;charset=UTF-8');
// xhr.setRequestHeader('SOAPAction', soapAction);
xhr.send(config.envelopeBegin+body+config.envelopeEnd);
Titanium.API.info(config.envelopeBegin+body+config.envelopeEnd);
Titanium.API.info("Test SUDS!");
};
}
I suppose that localhost will be the mobile (emulator) and not the hosting computer. Try binding the endpoints in Java to the machine name (not localhost) which is available in the network. Then point your SOAP connections to that machine.
精彩评论