热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

公司后台程序员,返回了一种让我讨厌的Json

↓推荐关注↓前言JSON转Model,明明是个机械活,但是有的时候后台给的接口文档,就是转不出正确的模型,是一件让人非常窝火

↓推荐关注↓

前言

JSON转Model,明明是个机械活,但是有的时候后台给的接口文档,就是转不出正确的模型,是一件让人非常窝火的事情。

错无非两种,要么后台文档给的有错,要么自己写的有错。

在经受过多次跳坑与爬坑的经历后,我变秃了,也变强了。

今天说说我遇见最讨厌的一种JSON,就是JSON中嵌套JSON String

后台文档的不给力

事情一开始是这样的,后台给我文档,说请求响应的JSON长这个样子:

{"result":true,"body":{"ret_code":"0","ret_msg":"成功","serial_number":"20211002115646portal511788","timestamp":"2021-10-02 03:56:46","response_data":{"token":"0765499c-8643-4491-8c8e-50f92a2ea004","expiredMills":1633751806616}}
}

我心想,这有何难,工具一键生成代码,请求转换就好了嘛:

// MARK: - Token
struct Token: Codable {let result: Bool?let body: Body?
}// MARK: - Body
struct Body: Codable {let retCode: String?let retMsg: String?let serialNumber: String?let timestamp: String?let responseData: ResponseData?enum CodingKeys: String, CodingKey {case retCode = "ret_code"case retMsg = "ret_msg"case serialNumber = "serial_number"case timestamp = "timestamp"case responseData = "response_data"}
}// MARK: - ResponseData
struct ResponseData: Codable {let token: String?let expiredMills: Int?
}

由于项目比较老,还是用的Alamofire4,请求与转换:

func getToken() {Alamofire.request("请求网址", method: .post).responseData { response inswitch response.result {case .success(let data):guard let model = try? JSONDecoder().decode(Token.self, from: data) else {return}print(model)case .failure(_):break}}
}

然后就在.success中的guard let这里return了,我反复看了文档,然后又看了定义的Model,感觉没错啊,也走到success里了,data也有值啊,怎么回事呢?

所幸先把data转成Dictionary看看再说,顺带在postman里请求看看,JSON到底是啥:

{"result": true,"body": "{\"ret_code\":\"0\",\"ret_msg\":\"成功\",\"serial_number\":\"20211002115646portal511788\",\"timestamp\":\"2021-10-02 03:56:46\",\"response_data\":{\"token\":\"0765499c-8643-4491-8c8e-50f92a2ea004\",\"expiredMills\":1633751806616}}"
}

结果这个一个JSON中包裹JSON String。

JSON中包裹JSON String解析

这种JSON中包裹JSON String解析非常的麻烦:

  • 首先Model的结构要重新定义。

  • 要多写一些代码去做处理。

然后大概就变成了这样,这里贴出关键代码:

struct Token: Codable {let result: Bool?/// body变成了Stringlet body: String?}

转换多了几步:

guard let model = try? JSONDecoder().decode(Token.self, from: data) else {return
}guard let string = model.body else {return
}guard let stringData = string.data(using: .utf8) else {return
}guard let body = try? JSONDecoder().decode(Body.self, from: stringData) else {return
}

  • 首先转成Token模型。

  • 再拿Token实例中的body,这个body是个String。

  • 然后body转为stringData。

  • 最后stringData最后转成Body的Model。

你说累不累?

看着这个头大的转换,我就想有没有更简洁的方式。

注意,这里其实可以将多个guard写成一个guard,不断let即可,我没有这么写是为了方便调试。

Response全部转String,再转Data,最后转Model的尝试

我想到了Alamofire中有一个responseString方法,我想到了这样一个思路:

c51145ac0f79ba702ec35bf3be6098e8.png

于是我试了试:

struct Token: Codable {let result: Bool?/// body试着用Body去接收let body: Body?}

func getToken() {Alamofire.request("请求网址", method: .post).responseString( encoding: .utf8) { res inswitch res.result {case .success(let string):guard let stringData = string.data(using: .utf8) else {return}guard let model = try? JSONDecoder().decode(Token.self, from: stringData) else {return}print(model)case .failure(_):break}}
}

不过尝试的结果是让人失望了的,在这一步就return了:

guard let model = try? JSONDecoder().decode(Token.self, from: stringData) else {return
}

转换成为响应体中的String没有问题,String转Data也没有问题,但是Data转Model就出错了。

所以说这种JSON中包裹JSON String的返回真的很难办啊!

最好的方式其实是和后台沟通

既然自己App端干这JSON转Model的事情吃力不讨好,最快最简洁的方式就是和后台沟通,让他们把这个JSON String转成JSON再塞到这个母JSON中,可以采取的措施有以下几点:

  • 后台给出的文档与实际的返回有出入,要么改文档,要么改Response。可是一般程序猿不喜欢改文档。

  • 返回JSON String不合符Response返回的规范,也不安全。

  • 拉着Android端的同学一起去找后台,人多力量大。

  • 反馈到技术经理,让他去定夺。

  • 不要相信后台说后续优化,要么现在改,要么就不改,否则自己下次还是得删改代码。

总结

上面吧嗒吧嗒说了一大堆,怎么处理JSON啊,各种思路啊。

其实归结到最后,如果能和后台沟通好这件事情,自己可能处理起来就会轻松不少。程序猿有的时候只会站在自己的视角去解决问题,有的时候,跳出来,弄清楚原因找到根节,事情就会变得简单不少。

转自:掘金 season_zhu

https://juejin.cn/post/7022130994241077256

PS:如果觉得我的分享不错,欢迎大家随手点赞、在看。

 关注公众号:Java后端编程,回复下面关键字 

要Java学习完整路线,回复  路线 

缺Java入门视频,回复: 视频 

要Java面试经验,回复  面试 

缺Java项目,回复: 项目 

进Java粉丝群: 加群 

PS:如果觉得我的分享不错,欢迎大家随手点赞、在看。

(完)

加我"微信" 获取一份 最新Java面试题资料

15e14f2131254468589193cc9c2cae34.png

请备注:666,不然不通过~

最近好文

1、Kafka 3.0重磅发布,弃用 Java 8 的支持!

2、你只会用 ! = null 判空?嘿嘿!

3、这次,Swagger-ui遇到对手了!

4、上午写了一段代码,下午就被开除了...

5、抖音项目Semi Design涉嫌抄袭?技术团队发文致歉!

508c759d8dc56b109ec232d610a34e5e.png

最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:关注公众号并回复 java 领取,更多内容陆续奉上。

明天见(。・ω・。)ノ♡


推荐阅读
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 有没有一种方法可以在不继承UIAlertController的子类或不涉及UIAlertActions的情况下 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • IOS开发之短信发送与拨打电话的方法详解
    本文详细介绍了在IOS开发中实现短信发送和拨打电话的两种方式,一种是使用系统底层发送,虽然无法自定义短信内容和返回原应用,但是简单方便;另一种是使用第三方框架发送,需要导入MessageUI头文件,并遵守MFMessageComposeViewControllerDelegate协议,可以实现自定义短信内容和返回原应用的功能。 ... [详细]
author-avatar
印度神油两性a
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有