okhttp3的使用

使用OkHttp3进行简单的API调用

OKHttp是一个当前主流的网络请求的开源框架,
1.get方法(同步)
引入依赖:

      <dependency>
 <groupId>com.squareup.okhttp3</groupId>
 <artifactId>okhttp</artifactId>
 <version>4.1.0</version>
</dependency>

get提交数据:
大致分3大步
1.实例化OkHttpClient。
2.执行调用。
i. 在执行调用之前,需要实例化一个Request 对象,作用是定义请求的各种参数,然后构建调用对象Call;
ii.最后执行调用,如果调用失败可能抛异常,所以必须抓取异常。
iii.开始执行调用。call.execute()就是执行调用的代码。
3. call. execute()返回的其实是一个执行的结果对象,调用对象的方法即可获取返回的字符串内容: call.execute(). body() .string();
扩展: 如果获得返回的二进制字节数组,则调用call.execute(). body().bytes(),如果想拿到返回的inputStream,则调call.execute(). body().byteStream().有inputStream就可以通过IO的方式写文件。
在这里插入图片描述
在这里插入图片描述具体实现:


import java.io.IOException;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;



public class GetPage {

  /**
   * 根据输入的url,读取页面内容并返回
   */
  public String getContent(String url) {
    // okHttpClient 实例
    OkHttpClient okHttpClient = new OkHttpClient();
    // 定义request组装请求头
    Request request = new Request.Builder().url(url).build();
    // 使用client去请求
    Call call = okHttpClient.newCall(request);
    // 返回结果字符串
    String result = null;
    
    try {
      // 获得返回结果
      result = call.execute().body().string();
      //这里的call也经常写成response,其中response为Response response = okHttpClient.newCall(request).execute();
    } catch (IOException e) {
      // 抓取异常
      System.out.println("request " + url + " error . ");
      e.printStackTrace();
    }
    return result;
  }

  public static void main(String[] args) {
    
    
    GetPage getPage = new GetPage();
    String url = "https://www.fastmock.site/mock/3d95acf3f26358ef032d8a23bfdead99/api/musicRankings";
    String content = getPage.getContent(url);
  
  
    System.out.println("API调用结果");
    System.out.println(content);
  }
}

2.post方法(同步)

post提交表单数据
大致步骤上只和get方法的new Request对象的时候有差别,get提交数据是把数据放在了url中,而post则不同。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
具体实现:
引入依赖:

 <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>4.1.0</version>
      </dependency>

提交表单数据:

import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import okhttp3.FormBody;
import okhttp3.FormBody.Builder;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class FormPoster {

  public String postContent(String url, Map<String, String> formData) {
    // okHttpClient 实例
    OkHttpClient okHttpClient = new OkHttpClient();

    //post方式提交的数据
    Builder builder = new FormBody.Builder();
    // 放入表单数据
    for(String key:formData.keySet()){
      builder.add(key,formData.get(key));
    }
    // 构建 FormBody 对象
     FormBody formBody =  builder.build();
    // 指定 post 方式提交FormBody
    Request request = new Request.Builder().url(url).post(formBody).build();
    // 使用client去请求
    Call call = okHttpClient.newCall(request);
    // 返回结果字符串
    String result = null;
    try {
      // 获得返回结果
      result = call.execute().body().string();
    } catch (IOException e) {
      // 抓取异常
      System.out.println("request " + url + " error . ");
      e.printStackTrace();
    }
    return result;
  }

  public static void main(String[] args) {
    String url = "http://tcc.taobao.com/cc/json/mobile_tel_segment.htm";
    Map<String, String> formData = new HashMap();
    formData.put("tel","13283714686");

    FormPoster poster = new FormPoster();
    String content = poster.postContent(url, formData);
  
    System.out.println("API调用结果");
    System.out.println(content);
  }
}

post提交JSON数据
大致分3个步骤:
1.将数据转换成JSON 格式的字符串,调用JSON.toJSONString()方法即可。
2.创建RequestBody 实例,注意需要指定提交的类型是application/json; charset=utf-8 。
3.构建Request 实例对象时,调用.post(requestBody)即表示使用JSON的方式提交数据。
在这里插入图片描述
具体实现:
先引入新的依赖:

  <!-- JSON 操作库 -->
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
      </dependency>

提交JSON数据操作:

import com.alibaba.fastjson.JSON;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

public class JsonPoster {

  // 定义提交数据的类型
  public static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");

  /**
   * 向指定的 url 提交数据,以 json 的方式
   */
  public String postContent(String url, Map<String, String> datas) {
    // okHttpClient 实例
    OkHttpClient okHttpClient = new OkHttpClient();

    // 数据对象转换成 json 格式字符串
    String param = JSON.toJSONString(datas);
    //post方式提交的数据
    RequestBody requestBody = RequestBody.create(JSON_TYPE, param);
    Request request = new Request.Builder().url(url).post(requestBody).build();

    // 使用client去请求
    Call call = okHttpClient.newCall(request);
    // 返回结果字符串
    String result = null;
    try {
      // 获得返回结果
      result = call.execute().body().string();
    } catch (IOException e) {
      // 抓取异常
      System.out.println("request " + url + " error . ");
      e.printStackTrace();
    }
    return result;
  }

  public static void main(String[] args) {
    String url = "https://www.fastmock.site/mock/3d95acf3f26358ef032d8a23bfdead99/api/posts";
    Map<String, String> datas = new HashMap();
    datas.put("name", "迪丽不热吧");
    datas.put("secondName", "奥摩");

    JsonPoster poster = new JsonPoster();
    String content = poster.postContent(url, datas); 

    System.out.println("API调用结果");
    System.out.println(content);
  }
}

headers

1User-Agent:表示用户端的访问类型,是谷歌浏览器还是火狐还是手机,有时候一个url在浏览器里可以访问,但是在Java程序里就访问不到这里就是User-Agent起的作用。User-Agent官方文档戳这里
2.Referer:在网站中有的图片使用了防盗链,在java程序里访问会被重定向到别的地址,只能他们自己的服务器才能访问该图片,如果不使用Referer用response.request().url().toString()
打印出最终响应的url是重定向过的,和原始代码里请求的url不一致,加了Refer之后会保证访问请求是在该服务器内的,即可最终访问到原始url。
3.Host表示当前请求的域名。虽然这个域名已经存在于URL中,但遇到复杂的场景,例如使用代理服器、或者URL中不写域名而是写|IP 地址进行请求等,设置Host 就非常有用了。Host一定不会带协议头(http/https),且一定是个域名。
代码举例:

    // okHttpClient 实例
    OkHttpClient okHttpClient = new OkHttpClient();
    // 定义一个request
    Request request = new Request.Builder()
        .url(url)
        .addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1")
        .addHeader("Referer","http://photo.yupoo.com/")
        .addHeader("Host","photo.yupoo.com")
        .build();

Web中为什么要设置Session和Cookie

一年一度的国庆小长假到来了,东方世纪欢乐园借此机会准备在举办夜晚欢乐派对,对一直支持游乐园的铁杆粉丝发出邀请。公司白领小贺本就计划好假期带女朋友一起来玩,所以一听到这个消息十分开心,当即给此次活动报了名。小胖是这家游乐园的工作人员,负责此次活动游客的进入进出,每来一个人都需要他在花名册里核对名单,查询该游客是否报名了此次活动。
活动开始了,小贺和女友如期而至,走到游乐园门口的时候报了自己的名字,等待小胖从花名册里查询,大概过了2分钟,小胖扶了扶眼镜告诉他说终于找到了,可以进去,小贺心里默念:游乐园看着挺豪华为什么里面工作人员的工作效率这么低,幸好自己是提前来的,不然遇到高峰期恐怕要等工作人员查好久才能进去。不过一点不足无伤大雅,游乐园里面的服务特别优质,大家该吃吃该喝喝该玩玩,每个人都很开心。活动进行到一半,有人提出要上厕所的要求,可是游乐园里没有厕所,只能出园再进来,但是进来的时候又要请求小胖去查找很长的花名册,这不管对游客还是对工作人员小胖无疑都是个很不爽的槽点。随着排队等待的人越来越多,小贺看不下去了,决定走向前去为小胖支招:大家出园的时候给每个人手腕系个一次性标记绳,要想解开这个绳结除非剪断它,这样你看到绳结就可以认为之前查询到有他的名字,不必再次查询了。小胖一听,直拍大腿,跳了起来,我丢,这主意好啊,省去了二次查询的麻烦,还特别省时间,真是太方便了。于是当即实施这种辨别方式,赢得了广大游客的好评,当晚的派对活动最终圆满结束。
通过上面的小故事,不知道大家有没有领悟到cookie机制在web中使用的好处呢?上面故事里的花名册就对对应数据库,一次性标记绳就是cookie,小胖就是某个应用的登陆页面,小贺就是用户,想要去请求登陆。cookie优点就是当用户二次登陆网站的时候不必进行登陆操作去数据库查询该用户的信息是否正确,而是通过cookie确定数据库里有该用户,可以直接进入网站主页,省去了冗余查询操作。
那么既然有了cookie足够证明用户身份,为什么还要有Session呢?其实Session存在于服务器端,主要储存用户的一些详细信息(比如头像,性别,年龄,手机号),安全性比cookie高,并且cookie的大小最多不能超过4k,而session理论上并没有限制
Cookie和Session的执行流程:

cookie执行流程

首先用户访问应用的时候,来到服务器。服务器设置一个cookie,在做响应的时候会通过set-cookie响应头将cookie带给浏览器。然后回到浏览器,浏览器会将此数据保存起来,接下来再次去访问服务器的时候,浏览器会根据cookie的path属性将这些数据带回去,来到服务器,服务器有对应的api获取这些值,有了值(一次性手腕绳)就知道用户是谁了。

session执行流程

客户浏览器发起一个请求到服务器,服务器先检查你是否携带了一个叫做JSESSIONID的cookie。
如果有携带,会将此cookie的值取出来(比如abc123),然后从服务器的session池中找到ID为aaa123的session(用户详细信息)返回给调用者。
如果没有携带这个JSESSIONID的cookie,那么服务器将会自动创建一个session对象并且生成一个随机字符串(比如abc123)作为此session的ID保存到session池中。在服务器为客户端浏览器作响应的时候自动创建一个键为“JSESSIONID” 值为“abc123”的cookie对象让浏览器储存起来以便下次再访问的时候带过来。

对JSON的理解

JSON字符串:只是一种特殊的字符串,没有换行格式,是前后端交互常采用的通信格式

 “ { "firstName": "Bill", "lastName": "Gates"}”

JSON对象:用大括号包围的具体格式的对象

  {
            "firstName": "Bill",
            "lastName": "Gates"
        }

JSON数组:本质上就是数组,每一个数组元素是json对象,用[]包围起来

[
        {
            "firstName": "Bill",
            "lastName": "Gates"
        },
        {
            "firstName": "George",
            "lastName": "Bush"
        }
    ]

json的运用:
前端收到json字符串,可以转化成json对象,进行取值操作。直接操作json字符串麻烦。

前端发送json数据时,首先拼接json对象,然后把发送的json对象转化为json字符串的形式发送。

后台收到json字符串,转化成json对象,进行取值操作。

同样,后台发送json数据,首先拼接json对象,然后把发送的json对象转化为json字符串的形式发送。

JSON、JSONObject、JAVAObject之间的相互转换
直接上代码,说明:这里输出转换成功类型的特有方法是为了类型已经成功转换,Ip类只有以个属性ip。

public static void main( String[] args )
    {
        String jsonStr = "{\"ip\":\"61.158.152.209\"}";
        //将json字符串强转为map
        Map map= (Map)JSONObject.parse(jsonStr);
        //将map强转为json字符串
        String jsonStr1 = JSON.toJSONString(map);
        //json强转为JsonObject
        JSONObject jsonObject = JSON.parseObject(jsonStr1);
        //json字符串强转为JavaObject类  先把JSON强转为JsonObject
        Ip ip = JSON.toJavaObject(JSON.parseObject(jsonStr1),Ip.class);
        //JAVAObject强转为JSON字符串
        String jsonStr2 = JSON.toJSONString(ip);
        //JAVAObject强转为Map 先把Objiect转换为JSonString
        Map map1 = JSON.parseObject(JSON.toJSONString(ip));
        //map强转为JavaObject  先把map转为JSON字符串然后转换为JSONOBject再转换为JavaObject
        Ip ip1 = JSON.toJavaObject(JSON.parseObject(JSON.toJSONString(map1)),Ip.class);






        //这是json字符串强转为map的输出:61.158.152.209
        System.out.println("这是json字符串强转为map的输出:" + map.get("ip"));
        //这是map强转为json字符串的输出:{"ip":"61.158.152.209"}
        System.out.println("这是map强转为json字符串的输出:" + jsonStr1);
        //这是Json字符串强转为JavaObject的输出:61.158.152.209
        System.out.println("这是Json字符串强转为JavaObject的输出:" + ip.getIp());
        //这是JAVAObject强转为JSON字符串:{"ip":"61.158.152.209"}
        System.out.println("这是JAVAObject强转为JSON字符串:" + jsonStr2);
        //这是JAVAObject强转为Map的输出:61.158.152.209
        System.out.println("这是JAVAObject强转为Map的输出:" + map1.get("ip"));
        //这是map强转为JavaObject的输出:61.158.152.209
        System.out.println("这是map强转为JavaObject的输出:" + ip1.getIp());

    }
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在Android ListView中使用API数据,您需要执行以下步骤: 1. 创建一个布局文件,其中包含ListView组件。 2. 创建一个自定义适配器,该适配器将在ListView中显示API数据。您可以使用BaseAdapter或ArrayAdapter来创建适配器。 3. 在您的代码中调用API并将返回的数据解析为您需要的格式。您可以使用HttpURLConnection或OkHttp等库来调用API。 4. 将解析的数据传递给您的自定义适配器,以便它可以在ListView中显示数据。 下面是一个简单的示例代码,演示如何在ListView中使用API数据: ```java public class MainActivity extends AppCompatActivity { private ListView mListView; private MyAdapter mAdapter; private List<String> mDataList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mListView = findViewById(R.id.list_view); mAdapter = new MyAdapter(); mListView.setAdapter(mAdapter); //调用API并解析数据 fetchDataFromApi(); } private void fetchDataFromApi() { //使用OkHttp库调用API OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://your-api-url.com/data") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { //处理请求失败的情况 } @Override public void onResponse(Call call, Response response) throws IOException { String responseData = response.body().string(); //解析数据 try { JSONArray jsonArray = new JSONArray(responseData); for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); String data = jsonObject.getString("data"); mDataList.add(data); } //将数据传递给适配器 runOnUiThread(new Runnable() { @Override public void run() { mAdapter.setData(mDataList); } }); } catch (JSONException e) { e.printStackTrace(); } } }); } private class MyAdapter extends BaseAdapter { private List<String> mData; public void setData(List<String> data) { mData = data; notifyDataSetChanged(); } @Override public int getCount() { return mData == null ? 0 : mData.size(); } @Override public Object getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.list_item, parent, false); } TextView textView = convertView.findViewById(R.id.text_view); textView.setText(mData.get(position)); return convertView; } } } ``` 在上面的示例代码中,我们使用OkHttp库调用API并将返回的数据解析为JSON格式。然后,我们将解析的数据传递给自定义适配器,并在ListView中显示数据。请注意,在这个示例代码中,我们在UI线程中更新适配器的数据,以确保ListView正确地显示数据。 ### 回答2: 在Android中,使用API数据给ListView提供数据是一个常见的需求。下面是一种基本的方法来使用API数据填充ListView: 1. 首先,你需要创建一个布局文件来定义ListView。例如,你可以在XML文件中使用ListView控件,并为其设置一个唯一的ID: ``` <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 接下来,在你的Activity或Fragment类中,你需要获取对ListView的引用。你可以使用findViewById方法根据ID找到ListView控件: ``` ListView listView = findViewById(R.id.listview); ``` 3. 然后,你需要创建一个自定义适配器(Adapter)类来处理数据的显示。你可以继承BaseAdapter类,并实现其中的方法来填充列表项的数据。 4. 在适配器中,你可以使用网络请求库(例如OkHttp或Retrofit)来调用API并获取数据。你可以在合适的时机执行网络请求,例如在Activity的onCreate方法或Fragment的onCreateView方法中。获取到数据后,将其存储到适配器的数据集合中。 5. 在ListView绑定适配器之前,你需要先为ListView设置一个适配器对象: ``` listView.setAdapter(adapter); ``` 6. 最后,你需要通知适配器数据已经改变,并刷新ListView的显示。你可以在获取到API数据后,调用适配器的notifyDataSetChanged方法: ``` adapter.notifyDataSetChanged(); ``` 这样,当ListView的数据集合发生变化时,它会自动重新加载数据并更新显示。 以上是一个基本的方法来使用API数据填充Android的ListView。根据具体的需求,你可能还需要考虑分页加载、下拉刷新、点击事件等。希望对你有所帮助! ### 回答3: Android中的ListView是一种用于展示数据列表的常用控件,可以很方便地与API数据进行交互。 首先,需要通过网络请求获取API数据。可以使用Android提供的HttpURLConnection或HttpClient等类实现网络请求,例如使用HttpURLConnection发送GET或POST请求获取API数据。 接下来,解析API数据。一般来说,API数据常使用JSON或XML格式,我们可以使用相应的类库(如Gson或XmlPullParser)来解析数据。将解析后的数据存储在一个适合的数据结构中,如ArrayList或LinkedList。 然后,创建一个自定义的Adapter来为ListView提供数据。Adapter是ListView的一个重要组成部分,它负责将数据以合适的方式绑定到ListView上。可以继承BaseAdapter类,并覆写其中的方法,例如getCount(返回数据项数量)、getItem(返回指定位置的数据项)、getView(创建或重新利用一个列表项视图)等方法。 最后,在Activity或Fragment中,实例化ListView,并将Adapter设置给它。通过调用ListView的setAdapter方法,将数据与列表视图进行关联。 在此基础上,我们还可以添加一些功能,比如根据用户操作动态刷新数据、添加点击事件处理、实现分页加载等。 综上所述,Android的ListView可以方便地与API数据进行交互。通过网络请求获取数据,解析数据,创建Adapter并将其与ListView关联,我们就可以在应用中展示API数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值