1. 背景与场景分析
1.1 需求描述
在 Android Retrofit 的网络请求场景中,常常需要将包含 HTML 标签的文本作为 JSON 字符串一并发送到服务器,保证前后端的数据约定正确,并且保持 HTML 内容的完整性。
本节聚焦的问题是:Android Retrofit 中如何发送包含 HTML 标签的 JSON 字符串请求? 这类请求的关键在于将 HTML 标签作为普通字符串字段放入 JSON 体中,而不是作为原生 HTML 请求的一部分。
1.2 兼容性与安全性
兼容性方面,主流的 JSON 序列化工具(如 Gson、Moshi)均能正确对包含 HTML 的字符串进行转义与序列化,因此通常不需要额外的改动。
安全性方面,需要关注服务端对输入 HTML 的清洗与 XSS 防护,避免将未经过滤的 HTML 直接渲染到页面上,同时确保 JSON 传输通道的安全性,例如使用 https、并对敏感字段进行最小暴露。
2. 实现思路与架构
2.1 数据模型设计
将包含 HTML 的文本作为普通字符串字段存放在数据模型中,字段命名应与服务器端约定一致,以便正确序列化与反序列化。
在客户端,无需对 HTML 本身进行额外编码处理,序列化库会对特殊字符进行必要转义,确保 JSON 语法正确。
3. 完整实现:发送包含 HTML 标签的 JSON 字符串
3.1 步骤1:定义数据模型 HtmlPayload
第一步定义一个简单的数据模型,其中 content 字段承载包含 HTML 标签的字符串,与服务器约定的字段名保持一致。
import com.google.gson.annotations.SerializedNamedata class HtmlPayload(@SerializedName("content")val content: String
)
在实际项目中,如果使用 Moshi 替代 Gson,可以用 @JsonClass(generateAdapter = true) 注解以及相应的 Moshi 适配器。
3.2 步骤2:定义 Retrofit 服务 ApiService
第二步定义一个 Retrofit 服务接口,使用 @Body 将 HtmlPayload 作为 JSON 体发送,请求方法通常为 POST,并返回服务器端固定的响应结构。
import retrofit2.Response
import retrofit2.http.Body
import retrofit2.http.POSTdata class ApiResponse(val code: Int,val message: String?
)interface ApiService {@POST("submitHtml")suspend fun submitHtml(@Body payload: HtmlPayload): Response
}
3.3 步骤3:完整 Retrofit 构建与发送请求
第三步给出一个完整的示例,包含 Retrofit 的构建、创建服务、以及发送包含 HTML 的 JSON 字符串请求的执行流程,演示了协程调用方式与响应处理。
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.create// Gradle 依赖示例(省略其他依赖)
val retrofit = Retrofit.Builder().baseUrl("https://api.example.com/").addConverterFactory(GsonConverterFactory.create()).build()val api = retrofit.create(ApiService::class.java)suspend fun postHtmlContent() {val payload = HtmlPayload(content = "Hello <strong>World</strong>
")val response = api.submitHtml(payload)if (response.isSuccessful) {val body = response.body()// 处理成功逻辑println("Success: ${body?.code} - ${body?.message}")} else {// 处理错误逻辑println("Error: ${response.code()} - ${response.errorBody()?.string()}")}
}
如果你的项目未使用协程,也可以使用 Call 风格,示例中的核心要点不变:确保将 HtmlPayload 作为请求体,服务端期望的 JSON 结构为 { "content": "" }。
3.4 依赖与配置提示
为了让以上代码顺利工作,需要在模块级的 Gradle 构建中引入协议转换器,GsonConverterFactory 与 Retrofit 的核心库不可缺失。
// Gradle 依赖示例
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.8.6'
4. 注意事项与最佳实践
4.1 HTML 的转义与 JSON 编码
在客户端发送过程中,JSON 序列化库会对特殊字符进行转义,如 <、>、" 等,确保最终传输的 JSON 合法性。
如果服务器端严格要求对 HTML 文本进行额外处理,可以在前端进行预处理,例如对敏感标签进行转义或替换,以避免意外的渲染问题。
4.2 服务器端安全与渲染
服务器端应对接收到的 HTML 内容进行清洗和校验,避免潜在的 XSS 攻击造成的业务风险;同时若将内容回显到页面,请使用安全的渲染策略。
对于跨站请求伪造与跨域请求,请遵循后端的鉴权与访问控制策略,确保只有经过授权的客户端能够提交该类数据。
4.3 编码规范与跨平台兼容
保持 字段命名、请求路径与媒体类型的一致性,以减少因版本差异带来的兼容性问题;如需在 iOS、Web 等端复用接口,请确保 API 设计的稳定性。
在测试阶段,可以通过描述性日志或返回结构体中的状态码来快速定位问题,避免将调试信息暴露给最终用户。
4.4 调试与日志
开启 Retrofit 与 OkHttp 的日志拦截,帮助快速定位请求体、响应体及头信息的格式问题;对于包含 HTML 的字段,特别关注 JSON 的序列化输出是否包含正确的转义。
5. 调试与测试
5.1 本地调试与断点调试
在本地调试时,可以将一个包含 HTML 的 payload 打印到日志,确保最终发送的 JSON 字符串中确实包含 HTML 内容,而非被意外转义或截断。
另外,通过断点观察 Retrofit 请求体对象的内容,有助于确认序列化结果是否符合服务器端期望。

5.2 MockWebServer 的测试示例
使用 MockWebServer 可以在不接入实际后端的情况下对请求与响应进行端到端测试,确保客户端的请求体结构与服务器端期望一致。
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import kotlinx.coroutines.runBlocking// 测试代码示例
val server = MockWebServer()
server.enqueue(MockResponse().setBody("""{"code":0,"message":"ok"}""").setHeader("Content-Type","application/json"))val retrofit = Retrofit.Builder().baseUrl(server.url("/")).addConverterFactory(GsonConverterFactory.create()).build()val api = retrofit.create(ApiService::class.java)runBlocking {val payload = HtmlPayload(content = "Test
")val response = api.submitHtml(payload)println("Test response: ${response.code()} - ${response.body()?.code}")
}
server.shutdown()
通过上述步骤,可以验证 在 Android Retrofit 中发送包含 HTML 标签的 JSON 字符串请求的完整流程是否正确,且能在本地进行快速迭代测试。


