美文网首页Rx系列Phalcon我的安卓学习
安卓进阶第四篇之使用Retrofit进行Http、Https网络

安卓进阶第四篇之使用Retrofit进行Http、Https网络

作者: 起个牛逼的昵称 | 来源:发表于2016-08-25 17:48 被阅读6752次

    最近看到很多文章说Retrofit接下来要火,自己也赶紧去看了一下,毕竟要跟着潮流走嘛是不是。网上看了很多文章,对Retrofit进行http请求都是没问题的,不过对于进行https请求,发现很多都用不了,有的也比较复杂,看的晕头转向,下面是我自己整理的Retrofit的使用方法,希望对大家能有所帮助。

    1.配置gradle

    //注解包
    compile 'com.jakewharton:butterknife:7.0.0'
    //Retrofit2所需要的包//这里需要值得注意的是导入的retrofit2包的版本必须要一致,否则就会报错compile 'com.squareup.retrofit2:retrofit:2.0.0'
    //ConverterFactory的Gson依赖包
    compile 'com.squareup.retrofit2:converter-gson:2.0.0'
    

    2.先使用http进行网络请求,这里我使用的是百度API的手机号码归属地查询的接口(点这里

    • 初始化Retrofit
    private static final String BASE_URL = "http://apis.baidu.com";
    private static final String API_KEY = "b90f262a4f321bb6755157bf1915b4f8";
    //1.创建Retrofit对象
    Retrofit retrofit = new Retrofit.Builder()       
    .addConverterFactory(GsonConverterFactory.create())//增加返回值为Gson的支持(以实体类返回)        
    .baseUrl(BASE_URL)//主机地址       
     .build();
    
    • 根据返回的json数据格式使用GsonFormat一键生成JavaBean(这个大家应该都会,AS常用的工具),最终结果如下:
    public class PhoneResult {   
    /**     
    * errNum : 0    
    * retMsg : success    
    * retData : {"phone":"15210011578","prefix":"1521001","supplier":"移动","province":"北京","city":"北京","suit":"152卡"}
    */    
    
    private int errNum;    
    private String retMsg;    
    private RetDataEntity retData;    
    public void setErrNum(int errNum) {        
    this.errNum = errNum;   
     }    
    public void setRetMsg(String retMsg) {     
    this.retMsg = retMsg;    
    }    
    public void setRetData(RetDataEntity retData) {       
    this.retData = retData;    
    }    
    public int getErrNum() {        
    return errNum;    
    }    
    public String getRetMsg() {        
    return retMsg;    
    }    
    public RetDataEntity getRetData() {        
    return retData;    
    }    
    public static class RetDataEntity {        
    /**         
    * phone : 15210011578         
    * prefix : 1521001         
    * supplier : 移动         
    * province : 北京         
    * city : 北京         
    * suit : 152卡         
    */        
    private String phone;        
    private String prefix;        
    private String supplier;        
    private String province;        
    private String city;        
    private String suit;        
    public void setPhone(String phone) {            
    this.phone = phone;        
    }        
    public void setPrefix(String prefix) {            
    this.prefix = prefix;        
    }        
    public void setSupplier(String supplier) {            
    this.supplier = supplier;        
    }        
    public void setProvince(String province) {            
    this.province = province;        
    }        
    public void setCity(String city) {            
    this.city = city;        
    }
    public void setSuit(String suit) {            
    this.suit = suit;        
    }        
    public String getPhone() {            
    return phone;        
    }        
    public String getPrefix() {            
    return prefix;        
    }        
    public String getSupplier() {            
    return supplier;        
    }        
    public String getProvince() {            
    return province;        
    }        
    public String getCity() {            
    return city;        
    }        
    public String getSuit() {
                return suit;        
    }    
    }
    }
    
    
    • 定义请求的API
    public interface PhoneService {    
    @GET("/apistore/mobilenumber/mobilenumber")   //是方法Url
    //@Query**(“phone”)来设定body的parameters.
    Call<PhoneResult> getResult(@Header("apikey") String apikey, @Query("phone") String phone);    
    }
    
    • 调用API
    //这里采用的是Java的动态代理模式
    PhoneService service = retrofit.create(PhoneService.class);
    //传入我们请求的键值对的值,mPhoneEt是我们输入的手机号
    Call<PhoneResult> call = service.getResult(API_KEY, mPhoneEt.getText().toString());
    
    • 发送请求
    call.enqueue(new Callback<PhoneResult>() {    
    @Override    
    public void onResponse(Call<PhoneResult> call, Response<PhoneResult> response) {        
    //处理结果       
    if (response.isSuccessful()) {            
    PhoneResult result = response.body();            
    if (result != null) {                
    if (result.getRetMsg() != null) {                    
    mAddressTv.setText(result.getRetMsg());//设置显示到texiview上                
    } else {                    
    PhoneResult.RetDataEntity entity = result.getRetData();
    mAddressTv.setText(entity.getProvince());               
     }           
     }       
     }    
    }    
    @Override    
    public void onFailure(Call<PhoneResult> call, Throwable t) {  
          }
    });
    
    • 看下结果


      最终结果

    3.使用https进行网络请求

    • 将证书拷贝到raw目录下
    https请求服务器需要的证书
    • 都知道Retrofit的网络请求是使用okhttp,所以我们只需要给
      OkHttpClient.Builder().sslSocketFactory(sslSocketFactory),那么SSLSocketFactory怎么得到呢,哈哈,不要急,方法已经写好:
    public class SslContextFactory {    
    private static final String CLIENT_TRUST_PASSWORD = "changeit";//信任证书密码,该证书默认密码是changeit    
    private static final String CLIENT_AGREEMENT = "TLS";//使用协议    
    private static final String CLIENT_TRUST_MANAGER = "X509";   
    private static final String CLIENT_TRUST_KEYSTORE = "BKS";    
    SSLContext sslContext = null;    
    public SSLContext getSslSocket() {        
    try {            
    //取得SSL的SSLContext实例            
    sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);            
    //取得TrustManagerFactory的X509密钥管理器实例            
    TrustManagerFactory trustManager = TrustManagerFactory.getInstance(CLIENT_TRUST_MANAGER);            
    //取得BKS密库实例            
    KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);            
    InputStream is = MyApplication.getInstance().getResources().openRawResource(R.raw.suplcerts);            
    try {                
    tks.load(is, CLIENT_TRUST_PASSWORD.toCharArray());            
    } finally {                
    is.close();            
    }            
    //初始化密钥管理器            
    trustManager.init(tks);            
    //初始化SSLContext            
    sslContext.init(null, trustManager.getTrustManagers(), null);        
    } catch (Exception e) {           
     Log.e("SslContextFactory", e.getMessage());       
     }        
    return sslContext;    }}
    
    • 给OkHttpClient.Builder().sslSocketFactory(sslSocketFactory)
    SSLSocketFactory sslSocketFactory = new SslContextFactory().getSslSocket().getSocketFactory();
    OkHttpClient.Builder okHttpClient = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory);
    
    • 创建Retrofit对象
    Retrofit retrofit = new Retrofit.Builder()        
    .addConverterFactory(GsonConverterFactory.create())//增加返回值为Gson的支持(以实体类返回)        
    .baseUrl("https://skyish-test.yunext.com")//主机地址        
    .client(okHttpClient.build())       /注意这里要给retrofit 设置okhttpclient
     .build();
    
    • 后面的创建请求的API跟调用API跟上面的使用http请求是一样的,可以自己找个接口试试,亲测,没有问题,这里我就不贴代码了。

    先简单说到这里,赶紧用起来吧,骚年

    欢迎留言讨论,喜欢就点一下赞

    相关文章

      网友评论

      • 追梦小乐:java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.请问一下,这个要怎么解决呢?
        追梦小乐:@隐龙 后来用来信任证书的方式,之前的问题排查后发现是后台niginx部署出现了问题
        隐龙:同样遇到这个问题,请问解决了嘛:pray:
        喝绿茶的考拉:我也是一样的问题,请问你解决了没有?
      • MiraclesHed:我想问问那个 信任证书密码 是用来干嘛的?
      • today_work:博主,,如何做post一个json的https请求,我用这个可以实现https的get请求,但是postjson数据就是报错。提示说must end in “/”结尾。。改了之后,还是报错。
      • 周晓川:你好,能把使用https发送网络请求的demo发我一份吗?1021237228@qq.com 谢谢
      • SeaOnline:博主我这样写了之后报错java.io.EOFException: \n not found: size=0 content=…
        起个牛逼的昵称: @SeaOnline 你的证书不对吧
        起个牛逼的昵称: @SeaOnline 你的证书不对的吧
      • 754cb2ce212a:SSLContext is not initialized. 为什么一直报这个错误
        乌蒙9527:@起个牛逼的昵称 证书用 Portecle 转的
        乌蒙9527:@起个牛逼的昵称 我也报这个错: SSLContext is not initialized.
        起个牛逼的昵称:@琳子_简书 你的证书没问题的吧
      • 焦27:楼主在么,我用https的按照你的方法,现在报错了,说ssl什么没有安装,想请教下,另外我raw下面放的是cer文件,这样可以么
        起个牛逼的昵称: @AresFuture 百度一下,可以解决的,上班路上,理解一下
        AresFuture:怎么将pkcs12文件转化为bks文件?
        起个牛逼的昵称: @wsyzj 转成bks文件
      • UniqueMrZhang:你好,可以提供一下demo吗?
        UniqueMrZhang:@起个牛逼的昵称 不用了 ,谢谢 我已经解决了
        起个牛逼的昵称: @UniqueMrZhang 可以的,邮箱发我
        Kxt:@UniqueMrZhang 拒绝做伸手党,网上很多博客讲的这些。http://gank.io/post/56e80c2c677659311bed9841

      本文标题:安卓进阶第四篇之使用Retrofit进行Http、Https网络

      本文链接:https://www.haomeiwen.com/subject/eekasttx.html