[英]kSoap2 POJO mapping class cast exception
我在使用Android的kSOAP2库时遇到困难。 我能够发送请求并获得响应,但是我想将响应的内容映射到普通的Java对象。 基本上,kSOAP2允许您通过在addMapping()方法中指定映射参数来做到这一点。 无论如何,当尝试将响应转换为Java对象时,我都遇到了类转换异常。 这是我的实现:
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
任何帮助都将是巨大的,因为这是使我迈向Web服务实现的最后一步。
谢谢 !
更新:
这是我为客户准备的课程。 现在,尝试将客户映射到我的RexUser类时出现错误。 我添加了envelope.addMapping("rexwebservices","RexUser",RexUser.class);
映射到我的信封。 我有一个Caused by: java.lang.RuntimeException: Unknown Property: FirstName
将客户数据保存到用户对象时出现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;
}
}
}
首先确保您的结构(GetCustomerByIdPwdResponse)中大多数外部对象的名称空间是“ rexwebservices”,因此要添加映射。 像那样:
envelope.addMapping("rexwebservices", "GetCustomerByIdPwdResponse", GetCustomerByIdPwdResponse.class);
envelope.addMapping("rexwebservices", "GetCustomerByIdPwdResult", GetCustomerByIdPwdResult.class);
第二件事-您定义的类只是响应的外部框。 我试图定义响应的可序列化和Your结构的第一层。 您包含的回复已正确解析给他们。
public class GetCustomerByIdPwdResponse implements KvmSerializable {
GetCustomerByIdPwdResult getCustomerByIdPwdResult;
@Override
public Object getProperty(int arg0) {
if(arg0==0){
return getCustomerByIdPwdResult;
}
return null;
}
@Override
public int getPropertyCount() {
return 1;
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
if(arg0==0){
arg2.name="GetCustomerByIdPwdResult";
arg2.type=GetCustomerByIdPwdResult.class;
}
}
@Override
public void setProperty(int arg0, Object arg1) {
if(arg0==0){
getCustomerByIdPwdResult=(GetCustomerByIdPwdResult)arg1;
}
}
}
public class GetCustomerByIdPwdResult implements KvmSerializable {
SoapObject Customer; //here goes Customer class ofcourse
String ErrorMessage;
String SessionId;
@Override
public Object getProperty(int arg0) {
switch(arg0){
case 0: return Customer;
case 1: return ErrorMessage;
case 2: return SessionId;
}
return null;
}
@Override
public int getPropertyCount() {
return 3;
}
@Override
public void getPropertyInfo(int arg0, Hashtable arg1, PropertyInfo arg2) {
switch(arg0){
case 0: arg2.name="Customer"; arg2.type=SoapObject.class;break; //Customer class
case 1: arg2.name="ErrorMessage"; arg2.type=PropertyInfo.STRING_CLASS;break;
case 2: arg2.name="SessionId"; arg2.type=PropertyInfo.STRING_CLASS;break;
}
}
@Override
public void setProperty(int arg0, Object arg1) {
switch(arg0){
case 0: Customer=(SoapObject)arg1;break;//Customer class
case 1: ErrorMessage=(String)arg1;break;
case 2: SessionId=(String)arg1;break;
}
}
}
我为您留下了Customer类-这就是为什么GetCustomerByIdPwdResult类中的Customer字段被声明为SoapObject。
希望它会有所帮助。 马尔钦
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.