SimpleXMLConverter 和改造 2.30。为啥序列化会因 ValueRequiredException 而崩溃?
Posted
技术标签:
【中文标题】SimpleXMLConverter 和改造 2.30。为啥序列化会因 ValueRequiredException 而崩溃?【英文标题】:SimpleXMLConverter and Retrofit 2.30. Why serialization crashes with ValueRequiredException?SimpleXMLConverter 和改造 2.30。为什么序列化会因 ValueRequiredException 而崩溃? 【发布时间】:2019-02-15 22:48:01 【问题描述】:在 android 应用程序中,我正在使用管道 Retrofit + SimpleXmlConverter 发送 XMl 发布请求获取 XML 响应:
@Provides
@AuthorizationScope
Retrofit provideAuthorizationRetrofit(@Named("BASE_CRM_URL") String baseUrl,
OkHttpClient client)
return new Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(SimpleXmlConverterFactory.createNonStrict())
.client(client)
.build();
@Provides
@AuthorizationScope
ApiAuthorizationService provideAuthorizationService(Retrofit retrofit)
return retrofit.create(ApiAuthorizationService.class);
public interface ApiAuthorizationService
@POST("/")
Call<CardHolder> searchHolderByPhoneCard(@Body String messageSearchHolders2);
在 searchHolderByPhoneCard 调用中,我发送没有任何标题的原始字符串(我的 api 应用它)。请求和响应的实例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Message Action="Search holders 2" Terminal_Type="77" Global_Type="ABC" Unit_ID="1" User_ID="1">
<Include>Holder_Card</Include>
<Item Mode="Clear" />
<Item Mode="Add">
<Contacts>
<Phone Value="+79600040318" IsNumber="True" />
</Contacts>
</Item>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Holders Message_ID="0" IndexFrom="1" IndexTo="1" Count="1" Search_GUID="5BDE0E0A-2CD4-4B96-AD07-2D4BB5A15409">
<Holder>
<Deleted>No</Deleted>
<Group_ID>1</Group_ID>
<Group_Name>
<![CDATA[Владельцы карт "Перец"]]>
</Group_Name>
<Division_ID>1</Division_ID>
<Division_Name>Головное подразделение</Division_Name>
<Holder_ID>10000000040834</Holder_ID>
<INN></INN>
<External_Code></External_Code>
<Unpay_Type_ID></Unpay_Type_ID>
<Unpay_Type_Name></Unpay_Type_Name>
<L_Name>Ермолин</L_Name>
<F_Name>Павел</F_Name>
<M_Name>Сергеевич</M_Name>
<Full_Name>Ермолин Павел Сергеевич</Full_Name>
<Birth>1992-12-14</Birth>
<Gender>Male</Gender>
<Marrital>Unknown</Marrital>
<Smoke>No</Smoke>
<Verification>Yes</Verification>
<Image>No</Image>
<Language_ID>1049</Language_ID>
<Language_Name>
<![CDATA[[RUS] Русский (Россия)]]>
</Language_Name>
<Source></Source>
<Remarks></Remarks>
<Holders_Cards>
<Holder_Card>
<Holder_ID>10000000040834</Holder_ID>
<Card>
<Card_Code>900221</Card_Code>
<Is_Virtual_Card>Yes</Is_Virtual_Card>
<Is_Confirm_Manager>No</Is_Confirm_Manager>
<Status>Active</Status>
<Carrier_Data></Carrier_Data>
<Offered>2018-08-25</Offered>
<Expired>2019-08-25</Expired>
<Group_ID>5</Group_ID>
<Group_Name>Virtual</Group_Name>
<Holder_ID>10000000040834</Holder_ID>
<Owner_ID></Owner_ID>
<Verification>Yes</Verification>
</Card>
</Holder_Card>
</Holders_Cards>
</Holder>
为了解析响应,我创建了非严格模型(我在大多数领域都没有需要)。型号代码:
@Root(name = "Holders", strict = false)
public class CardHolder
@Attribute(name = "Count")
private int count;
@Element (name = "L_Name", required = false)
@Path("Holder")
private String secondName;
@Element (name = "F_Name", required = false)
@Path("Holder")
private String firstName;
@Element (name = "M_Name", required = false)
@Path("Holder")
private String thirdName;
@Element (name = "Birth", required = false)
@Path("Holder")
private String birth;
@Element (name = "Gender")
@Path("Holder")
private String gender;
@Element(name = "is_Virtual_Card", required = false)
@Path("Holder/Holders_Cards/Holder_Card/Card")
private String isVirtualCard;
public CardHolder()
public int getCount()
return count;
public void setCount(final int count)
this.count = count;
public String getIsVirtualCard()
return isVirtualCard;
public void setIsVirtualCard(final String isVirtualCard)
this.isVirtualCard = isVirtualCard;
public String getSecondName()
return secondName;
public void setSecondName(final String secondName)
this.secondName = secondName;
public String getFirstName()
return firstName;
public void setFirstName(final String firstName)
this.firstName = firstName;
public String getThirdName()
return thirdName;
public void setThirdName(final String thirdName)
this.thirdName = thirdName;
public String getBirth()
return birth;
public void setBirth(final String birth)
this.birth = birth;
public String getGender()
return gender;
public void setGender(final String gender)
this.gender = gender;
结果,执行的 api 调用方法在 onFailure 回调异常中抛出这样的消息:
原因:org.simpleframework.xml.core.ValueRequiredException: Unable 满足@org.simpleframework.xml.Attribute(empty=, name=Count, required=true) 在字段“计数”私有 int 上
我已阅读有关此错误的文档,并且我了解这与无效的模型结构有关。但我不知道我哪里出错了,需要你的帮助来解决问题
【问题讨论】:
我猜count
没有得到值,因为默认情况下required=True
会导致错误。
【参考方案1】:
我找到了解决方案。问题是我试图将字符串原始请求作为@Body 发送。所有“text/plain”请求都应该这样包装:
String requestText = RequestBodyUtil.searchHolderByPhoneCard(phone);
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), requestText);
对于这种情况,阅读https://futurestud.io/tutorials/retrofit-2-how-to-send-plain-text-request-body 非常有用
【讨论】:
以上是关于SimpleXMLConverter 和改造 2.30。为啥序列化会因 ValueRequiredException 而崩溃?的主要内容,如果未能解决你的问题,请参考以下文章