android - 使用 Retrofit2 和 SimpleXmlConverterFactory 序列化为 XML 时,如何包含 DOCTYPE 声明?
问题描述
我正在尝试将 SimpleXmlConverterFactory 与 Retrofit 一起使用来创建对 REST 服务的 XML 请求。但是,该服务需要请求中的 DTD 声明,就像这样。
<!DOCTYPE paymentService PUBLIC "-//WorldPay//DTD WorldPay PaymentService v1//EN" "http://dtd.worldpay.com/paymentService_v1.dtd">
但是当 SimpleXmlConverterFactory 序列化数据对象时,它会省略 DOCTYPE 声明:
<paymentService merchantCode="..." version="1.4">
<inquiry>
<shopperTokenRetrieval>
<authenticatedShopperID>...</authenticatedShopperID>
</shopperTokenRetrieval>
</inquiry>
</paymentService>
创建 SimpleXmlConverterFactory 并没有什么特别之处:
val builder = Retrofit
.Builder()
.addConverterFactory(
SimpleXmlConverterFactory.create()
)
.baseUrl(BuildConfig.WORLDPAY_BASE_URL)
.build()
.create(WorldPayApiService::class.java)
这是带注释的数据对象
@Root(name = "paymentService")
data class WorldPayXmlPaymentService(
@field:Attribute(name = "version")
var version: String = "",
@field:Attribute(name = "merchantCode")
var merchantCode: String = "",
@field:Element(name = "reply", required = false)
var reply: WorldPayXmlReply? = null,
@field:Element(name = "inquiry", required = false)
var inquiry: WorldPayXmlInquiry? = null
)
解决方案
我将 Persister 作为参数添加到 SimpleXmlConverterFactory.create 方法中,如下所示。它查找根元素,然后在序列化其余部分之前输出 DOCTYPE。
val persister = object : Persister() {
@Throws(Exception::class)
override fun write(source: Any, out: Writer) {
(source as? WorldPayXmlPaymentService)?.let {
val docType = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE paymentService PUBLIC \"-//WorldPay//DTD WorldPay PaymentService v1//EN\" \"http://dtd.worldpay.com/paymentService_v1.dtd\">"
out.write(docType)
super.write(source, out)
}
}
}
val builder = Retrofit
.Builder()
.addConverterFactory(
SimpleXmlConverterFactory.create(persister)
)
.baseUrl(BuildConfig.WORLDPAY_BASE_URL)
.build()
.create(WorldPayApiService::class.java)
WorldPayXmlPaymentService 是我的根数据对象。
感谢@CommonsWare 的指导。
推荐阅读
- angular - 无法在 Angular 中加载 build/toastr.min.css
- ios - 在 PDFView (iOS) 上禁用缩放
- ios - 如何限制 gcd 队列缓冲区大小
- python-3.x - 在 Python 3 中使用 Pyperclip 不会以所需格式粘贴数据
- python - 如何访问列表字典中的每个元素?
- node.js - 使用嵌套查询(包括)进行子查询 Sequelize
- linq - 如何使用 linq 在列表对象中选择最大 StartDate 的一行
- cassandra - 使用昨天/明天将日期插入 Cassandra
- mongodb - 如何将存储在远程服务器中的 mongo 数据复制到我的本地 docker 容器中?
- jquery - 尝试为 .css() 向 Jquery 添加更多属性