文章目录

  • 准备工作
    • 代码
    • 遇到问题
    • 解决方案
      • 报错问题

准备工作

在上一篇博客 网络请求(三)——Retrofit的get和post请求的用法 中,每日一词的json格式比较简单,于是试了一下使用API的查词接口

我使用的API
http://dict-co.iciba.com/api/dictionary.php?w=good&type=json&key=0CD3A4C079D2D23C683BBFF96300E924

JSON结构

代码

一开始,事情进行的很顺利……

  • 新建用于接收服务器返回数据的类,新建接口
public interface GetRequest_Interface {//用get方式发送网络请求@GET("api/dictionary.php?w=go&type=json&key=0CD3A4C079D2D23C683BBFF96300E924")//接收网络请求数据的方法Call<Translation> getCall();@POST("api/dictionary.php?")Call<Translation> postCall(@Query("w") String word, @Query("type") String type, @Query("key") String key);
}
  • 创建Retrofit实例
  • System.out.println(translation.getSymbols().get(0).getParts().get(0).getMeans().get(0));
  • 这句中,先得到"Symbols",再get(0)获得数组第一个参数([ ]里的),得到"Parts",get(0)获取第一个参数,得到"Means",再获得第一个中文意思
private void request() {Retrofit retrofit = new Retrofit.Builder().baseUrl("http://dict-co.iciba.com/").addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析.build();GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);Call<Translation> call = request.getCall();call.enqueue(new Callback<Translation>() {@Overridepublic void onResponse(Call<Translation> call, Response<Translation> response) {if(response.isSuccessful()) {Translation translation = response.body();System.out.println(translation.getSymbols().get(0).getParts().get(0).getMeans().get(0));}}@Overridepublic void onFailure(Call<Translation> call, Throwable t) {System.out.println("failed");System.out.println(t.getMessage());}});}

遇到问题

  • 输出的也很好没什么问题
  • 但是,当我换个单词的时候……

    怎么会这样??
  • 看的报的问题是第一行,exchange的word_third,期望是数组但是却是字符串
  • 看了一下我写的类的结构,确实是数组没错,JSON格式里也是数组
  • 再在浏览器上看了一下api返回界面的JSON数据,感觉没什么问题……
  • 然后想到是不是由于有些单词没有第三人称复数的时候word_third的值不是数组而是字符串
    @POST("api/dictionary.php?")Call<ResponseBody> rawPostCall(@Query("w") String word, @Query("type") String type, @Query("key") String key);
private void post() {Retrofit retrofit = new Retrofit.Builder().baseUrl("http://dict-co.iciba.com/").addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析.build();GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);request.rawPostCall("good", "json", "0CD3A4C079D2D23C683BBFF96300E924").enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {try {String jsonString = response.body().string();JSONObject jsonObject = new JSONObject(jsonString);JSONObject exchange = jsonObject.getJSONObject("exchange"); //获取exchange下的数据,是JSON格式,所以JSONObjectObject word_third = exchange.get("word_third"); //是未知格式,用Objectif (word_third instanceof String) { //instanceof:左边对象是否是右边的实例String word = (String) word_third;Toast.makeText(Main2Activity.this, word, Toast.LENGTH_SHORT).show();} else if (word_third instanceof List) {List<String> words = (List<String>) word_third;if (words==null) {words = Collections.emptyList();    //返回空的list}Toast.makeText(Main2Activity.this, Arrays.toString(words.toArray(new String[words.size()])), Toast.LENGTH_SHORT).show();    //}} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {}});}}
  • 打上断点debug


  • 将获取到的数据格式化后与浏览器中直接看到的返回数据相比对,发现区别就在于,如果word_third有值的情况下,他是一个数组,没有值的话,是一个字符串……
  • 接着往下走
    word_third值为空,其实是正确的

解决方案

  • 那么就找到了原因,解决办法有两个:

  • 一个是用JSONObject来解析,比较麻烦

  • 或者自定义GSON,看了一下源码觉得比较难。

  • 还是用了JSONObject,自定义GSON等着以后来解决!

private void post() {Retrofit retrofit = new Retrofit.Builder().baseUrl("http://dict-co.iciba.com/").addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析.build();GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);request.rawPostCall("good", "json", "0CD3A4C079D2D23C683BBFF96300E924").enqueue(new Callback<ResponseBody>() {@Overridepublic void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {try {String jsonString = response.body().string();JSONObject jsonObject = new JSONObject(jsonString);String word_name;word_name = jsonObject.getString("word_name");mTv.append(word_name);JSONArray symbols = jsonObject.getJSONArray("symbols");JSONObject symobj = symbols.getJSONObject(0);JSONArray parts = symobj.getJSONArray("parts");List<String> partlist = new ArrayList<>();List<String> meanlist = new ArrayList<>();for (int i = 0; i < parts.length(); i++) {JSONObject partmeans = parts.getJSONObject(i);String part = partmeans.getString("part");partlist.add(part);mTv.append("\n" + partlist.get(i));JSONArray means = partmeans.getJSONArray("means");for (int j = 0; j < means.length(); j++) {String mean = means.getString(j);meanlist.add(mean);if (j == means.length()-1) {mTv.append(meanlist.get(j));}else {mTv.append(meanlist.get(j) + ",");}}}} catch (Exception e) {e.printStackTrace();}}@Overridepublic void onFailure(Call<ResponseBody> call, Throwable t) {}});}

报错问题

org.json.JSONException: No value for parts
没有parts这个值

发现是我结构看错了

网络请求(四)Retrofit实战——金山词霸查词API遇到的问题相关推荐

  1. 鸿蒙开发实战系列之三:网络请求(原生+ Retrofit)

    鸿蒙开发实战系列之一:鸿蒙开发实战系列之一:圆角 鸿蒙开发实战系列之二:鸿蒙开发实战系列之二:事件总线EventBus/RxBus 前言 过了一个漫长的中秋+国庆假期,大家伙的鸿蒙内功修炼的怎么样了? ...

  2. Flutter 项目实战 Dio网络请求 四

    /  HTTP  |   HTTPS  / HTTP是一个客户端(用户)和 服务端(网站)之间请求和应答的标准,通常使用TCP协议.客户端发起一个HTTP请求到服务器上指定端口(默认端口为80).客户 ...

  3. Android 网络请求库Retrofit简单使用

    载请标明出处: http://blog.csdn.net/u011974987/article/details/50895633: 什么是 Retrofit ? Retrofit 是一套 RESTfu ...

  4. java中使用okhttpsoap,Android okHttp网络请求之Retrofit+Okhttp+RxJava组合

    Retrofit介绍: Retrofit和okHttp师出同门,也是Square的开源库,它是一个类型安全的网络请求库,Retrofit简化了网络请求流程,基于OkHtttp做了封装,解耦的更彻底:比 ...

  5. html 网络请求 json数据,写一个json格式API,http请求接收json数据

    目前比较流行的公开API 大多都是返回json格式字符串.如何创建自己的基于http请求返回json数据的api? 如下: 返回JSON字符串的API 相关包:fastjson-1.2.2.jar 方 ...

  6. flutter 项目实战二 网络请求

    本项目借用 逛丢 网站的部分数据,仅作为 flutter 开发学习之用. 逛丢官方网址:https://guangdiu.com/ flutter windows开发环境设置 flutter 项目实战 ...

  7. 小程序 ajax 加载,小程序实战-小程序网络请求异步加载

    最初看到小程序的网络请求的时候,尤其是演示示例中,userInfoReadyCallback这个函数更是一头雾水.其实并不怎么理解.一直很费解.网上各路大侠都有解释,但是就是,不知道是怎么个顺序,而我 ...

  8. Android RxJava操作符的学习---变换操作符---网络请求嵌套回调

    变换操作符的主要开发需求场景 = 嵌套回调(Callback hell) 下面,我将采用一个实际应用场景实例来讲解嵌套回调(Callback hell) 1. 需求场景 1.1 背景 需要进行嵌套网络 ...

  9. Android okHttp网络请求之缓存控制Cache-Control

    前言: 前面的学习基本上已经可以完成开发需求了,但是在项目中有时会遇到对请求做个缓存,当没网络的时候优先加载本地缓存,基于这个需求我们来学习一直okHttp的Cache-Control. okHttp ...

最新文章

  1. 面试AI Lab能力测评
  2. jQuery reset
  3. 怎样通过vb设置透视表多项选择_数据透视表有多强大?
  4. C#之IComparable用法,实现ListT.sort()排序
  5. java libpcap,Linux下编译安装libpcap
  6. 2015.5.28 面试题1:赋值运算符函数
  7. python机器视觉教材_基于Python的机器视觉实验教学平台设计
  8. 揭秘 XR 开发难题,让虚拟现实不仅仅停留在好奇
  9. 解决Eclipse 鼠标悬停提示框是黑色的
  10. 如何在程序中安装指定apk文件
  11. 弹幕有硬伤,转变主流成妄想
  12. 游戏启动流程的逆向分析与多开的实现
  13. 工程思维把每件事都当作一个项目来做
  14. 网络流行语“不作不死”英文入选美国词典
  15. 加速编码的17款最棒的CSS工具
  16. python案例2-简易网吧系统
  17. 2021计算机一级新增知识点,2021年全国计算机等级考试改革有哪些内容
  18. SAP 公司间销售配置原理和步骤
  19. kingcms php 漏洞,kingcms任意php文件删除(可截断时升级为任意文件删除 )
  20. 使用Python解析MNIST数据集(IDX格式文件)

热门文章

  1. tello通信_鸿蒙HarmonyOS and 大疆Tello 无人机 BUILD SUCCESS
  2. 伊藤清|概率论大师的“哲学”指引
  3. 从官网下载mysql 如何配置_从官网下载最新版Mysql并配置使用
  4. web前端期末大作业 :HTML+CSS+JavaScript+Bootstrap实现响应式网站潮酷音乐网站
  5. 新基建下的新机会,任泽平为何看好百度、华为和阿里?
  6. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(4)- Flashloader初体验(blhost)...
  7. 常用缓存淘汰策略FIFO、LFU、LRU
  8. github一直发邮件,如何屏蔽
  9. 住房公积金专办员题库(含答案)
  10. 读书笔记-《版面设计的原理》