У меня возникли трудности с использованием библиотеки kSOAP2 для android. Я могу отправлять запросы и получать ответ, но я хотел бы отобразить содержимое ответа на простой Java-объект. В основном kSOAP2 позволяет вам это сделать, указав параметры отображения в метод addMapping(). В любом случае у меня возникает исключение класса при попытке передать ответ на мой объект Java. Вот моя реализация:kSoap2 класс сопоставления POJO класс исключение
final SoapSerializationEnvelope envelope = LoginInfo.buildLoginObject(login,password);
envelope.addMapping(NAMESPACE, "GetCustomerByIdPwdResponse", new GetCustomerByIdPwdResponse().getClass());
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
HttpTransportSE httpTransport = new HttpTransportSE("URL");
httpTransport.debug = true;
try {
httpTransport.call(URL, envelope);
Log.d("SOAP OBJECT SENT",httpTransport.requestDump);
Log.d("SOAP OBJECT RESPONSE",httpTransport.responseDump);
GetCustomerByIdPwdResponse customerByIdPwd = (GetCustomerByIdPwdResponse)envelope.bodyIn;
} catch (IOException | XmlPullParserException e) {
e.printStackTrace();
}
return null;
}
}.execute();
А вот запрос и ответ я получаю, все они хороши:
Запрос:
<?xml version="1.0" encoding="UTF-8"?>
<v:Envelope xmlns:v="http://www.w3.org/2003/05/soap-envelope" xmlns:c="http://www.w3.org/2003/05/soap-encoding" xmlns:d="http://www.w3.org/2001/XMLSchema" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<v:Header>
<n0:To xmlns:n0="http://www.w3.org/2005/08/addressing">To</n0:To>
<n1:Action xmlns:n1="http://www.w3.org/2005/08/addressing">rexwebservices/IWebShopServices/GetCustomerByIdPwd</n1:Action>
</v:Header>
<v:Body>
<GetCustomerByIdPwd xmlns="rexwebservices" xmlns:ns2="http://schemas.datacontract.org/2004/07/RexWebServices" xmlns:ns3="http://schemas.microsoft.com/2003/10/Serialization/" id="o0" c:root="1">
<loginMail i:type="d:string">...</loginMail>
<pwdSHA1 i:type="d:string">...</pwdSHA1>
</GetCustomerByIdPwd>
</v:Body>
Ответ:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">rexwebservices/IWebShopServices/GetCustomerByIdPwdResponse</a:Action>
</s:Header>
<s:Body>
<GetCustomerByIdPwdResponse xmlns="rexwebservices">
<GetCustomerByIdPwdResult xmlns:b="http://schemas.datacontract.org/2004/07/RexWebServices" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<b:Customer>
<b:FirstName>...</b:FirstName>
<b:Id>...</b:Id>
<b:IsActived>true</b:IsActived>
<b:IsLockedOut>false</b:IsLockedOut>
<b:IsNewsLetterAccepted>false</b:IsNewsLetterAccepted>
<b:LandLinePhone />
<b:LastName>...</b:LastName>
<b:LoginMail>...</b:LoginMail>
<b:MobilePhone />
<b:Title>Mr</b:Title>
</b:Customer>
<b:ErrorMessage>+00X00000</b:ErrorMessage>
<b:SessionId>SID</b:SessionId>
</GetCustomerByIdPwdResult>
</GetCustomerByIdPwdResponse>
</s:Body>
</s:Envelope>
И вот ошибка, которую я получаю при попытке создать мой POJO:
11-18 11:36:57.967: E/AndroidRuntime(19208): Caused by: java.lang.ClassCastException: org.ksoap2.serialization.SoapObject cannot be cast to com.example.ksoaptest.GetCustomerByIdPwdResponse
11-18 11:36:57.967: E/AndroidRuntime(19208): at com.example.ksoaptest.MainActivity$2.doInBackground(MainActivity.java:70)
11-18 11:36:57.967: E/AndroidRuntime(19208): at com.example.ksoaptest.MainActivity$2.doInBackground(MainActivity.java:1)
11-18 11:36:57.967: E/AndroidRuntime(19208): at android.os.AsyncTask$2.call(AsyncTask.java:288)
11-18 11:36:57.967: E/AndroidRuntime(19208): at java.util.concurrent.FutureTask.run(FutureTask.java:237)
11-18 11:36:57.967: E/AndroidRuntime(19208): ... 4 more
Любая помощь будет замечательной, так как это последний шаг, чтобы заставить меня перейти к реализации моего веб-сервиса.
Спасибо!
UPDATE:
Вот мой класс для моего клиента. У меня теперь есть ошибка при попытке сопоставить клиента с моим классом RexUser. Я добавил карту envelope.addMapping("rexwebservices","RexUser",RexUser.class);
в свой конверт. У меня есть ошибка Caused by: java.lang.RuntimeException: Unknown Property: FirstName
, когда дело доходит до сохранения данных клиента в пользовательский объект.
public class RexUser implements KvmSerializable{
public static final int FIRSTNAME = 0;
public static final int ID = 1;
public static final int LASTNAME = 6;
public static final int LOGINMAIL = 7;
public static final int MOBILEPHONE = 8;
public static final int LANDLINEPHONE = 5;
public static final int TITLE = 9;
public static final int IS_ACTIVATED = 2;
public static final int IS_LOCKED_OUT = 3;
public static final int IS_NEWSLETTER_ACCEPTED = 4;
String FirstName;
long Id;
boolean IsActived;
boolean IsLockedOut;
boolean IsNewsLetterAccepted;
String LandLinePhone;
String LastName;
String LoginMail;
String MobilePhone;
String Title;
public RexUser(String firstName, long id, boolean isActivated,
boolean isLockedOut, boolean isNewsLetterAccepted,
String landLinePhone, String lastName, String loginMail,
String mobilePhone, String title) {
super();
this.FirstName = firstName;
this.Id = id;
this.IsActived = isActivated;
this.IsLockedOut = isLockedOut;
this.IsNewsLetterAccepted = isNewsLetterAccepted;
this.LandLinePhone = landLinePhone;
this.LastName = lastName;
this.LoginMail = loginMail;
this.MobilePhone = mobilePhone;
this.Title = title;
}
public RexUser() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
HashMap<String,Object> desc = new HashMap<String,Object>();
desc.put("First name",FirstName);
desc.put("ID",Id);
desc.put("is Actived", IsActived);
desc.put("is Locked Out",IsLockedOut);
desc.put("isNewsLetterAccepted", IsNewsLetterAccepted);
desc.put("Land Line Phone", LandLinePhone);
desc.put("lastname", LastName);
desc.put("login Mail", LoginMail);
desc.put("mobile phone",MobilePhone);
desc.put("title", Title);
return desc.toString();
}
@Override
public Object getProperty(int arg0) {
switch(arg0){
case 0:
return FirstName;
case 1:
return Id;
case 2:
return IsActived;
case 3:
return IsLockedOut;
case 4:
return IsNewsLetterAccepted;
case 5:
return LandLinePhone;
case 6:
return LastName;
case 7:
return LoginMail;
case 8:
return MobilePhone;
case 9:
return Title;
default:
return null;
}
}
@Override
public int getPropertyCount() {
return 10;
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
switch(arg0){
case 0:
arg2.name = "First Name";
arg2.type = String.class;
break;
case 1:
arg2.name = "ID";
arg2.type = int.class;
break;
case 2:
arg2.name = "Is Actived";
arg2.type = boolean.class;
break;
case 3:
arg2.name = "Is Locked Out";
arg2.type = boolean.class;
break;
case 4:
arg2.name = "Is Newsletter Accepted";
arg2.type = boolean.class;
break;
case 5:
arg2.name = "Landline Phone";
arg2.type = String.class; break;
case 6:
arg2.name = "Last Name";
arg2.type = String.class;
break;
case 7:
arg2.name = "Login mail";
arg2.type = String.class;
break;
case 8:
arg2.name = "Mobile Phone";
arg2.type = String.class;
break;
case 9:
arg2.name = "Title";
arg2.type = String.class;
break;
default:
break;
}
}
@Override
public void setProperty(int arg0, Object arg1) {
switch(arg0){
case 0:
FirstName = (String)arg1;
break;
case 1:
Id = (int)arg1;
break;
case 2:
IsActived = (boolean)arg1;
break;
case 3:
IsLockedOut = (boolean)arg1;
break;
case 4:
IsNewsLetterAccepted = (boolean)arg1;
break;
case 5:
LandLinePhone = (String)arg1;
break;
case 6:
LastName = (String)arg1;
break;
case 7:
LoginMail = (String)arg1;
break;
case 8:
MobilePhone = (String)arg1;
break;
case 9:
Title = (String)arg1;
break;
default:
break;
}
}
}
Привет Marcin и спасибо за ваш ответ. Я обязательно попробую это и вернусь к тебе =) – user3476114
Привет снова Марцин. Я пытаюсь решить ваше решение, и оно работает до тех пор, пока мне не нужно отображать примитивные типы. См. Мой обновленный вопрос, чтобы увидеть класс клиента. Это уже огромный шаг, который вы позволили мне поблагодарить за это =) – user3476114
Метод getPropertyInfo должен возвращать точное имя тега. Итак arg2.name = "Имя"; должен быть arg2.name = "FirstName"; Я не знаю, использует ли его a, но для предопределенных типов использует поле из информации о свойствах. Fe. arg2.type = PropertyInfo.STRING_CLASS; и так далее. – mmprog