Retrofit 2.1 入门

Retrofit 2.1入门

几种网络框架的比较
1、volley
一个简单的http异步请求库,但不支持同步,不能post大数据(上传文件时有问题);
2、android-async-http
和volley一样,是异步的请求库,只不过volley使用的是httpUrlConnection,而它使用的是HttpClient。这个库已经不再适合Android;
3、okhttp
基于httpUrlConnection,支持同步和异步,但需要自己再封装下;
4、retrofit;
对 okhttp再次封装,在项目中可以直接使用。
在项目中引用retrofit,分为几个部分
- module对象
- Converter的实现类
- Service类(定义网址中不固定的部分)
- OkHttpClient和Retrofit

//1.创建Retrofit对象

//2.创建访问API的请求

//3.发送请求

//4.处理结果

1、配置

compile ‘com.squareup.okhttp3:okhttp-urlconnection:3.4.0-RC1‘
compile ‘com.google.code.gson:gson:2.7‘
compile ‘com.squareup.retrofit2:retrofit:2.1.0‘
compile ‘com.squareup.retrofit2:converter-gson:2.1.0‘

GET方式

public interface SimpleGET {
    @GET("/") //表明是GET方式. "/"会拼接在setEndpoint(url)中url(主机地址)的后面.
    Call<ResponseBody> getResponse();
    //可以简单的理解为网络访问完把Response转换为一个对象.这里没有转换,还是Response.
}

public static void simpleGET(){
    String url="http://tieba.baidu.com";
    Retrofit retrofit=new Retrofit.Builder()
            .baseUrl(url)
            .build();
    SimpleGET create=retrofit.create(SimpleGET.class);
    final  Call<ResponseBody> call=create.getResponse();
    try {
       /*错误 的调用
        Response response=create.getResponse().execute();
        System.out.print(response.body().toString());*/
        Response<ResponseBody> bodyResponse = call.execute();
        String body = bodyResponse.body().string();//获取返回体的字符串
        System.out.print(body);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

POST方式

public interface SimplePOST {
    @POST("/androdi")
    Call<ResponseBody> getResponse();
}

PATH 路径
path是可以动态替换的.
static class Contributor {

//一个pojo类(Plain Ordinary Java Object)简单的Java对象-->相比javaBean更简单. GsonConverter默认的转换器

  String login;

  int contributions;

}

interface GitHub {

  @GET("/repos/{owner}/{repo}/contributors")

  Call<List<Contributor>> contributors(@Path("owner") String owner, 
@Path("repo") String repo);

} 

public static void path_GitHub(){
    String url="https://api.github.com";
    Retrofit retrofit=new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    GitHub create=retrofit.create(GitHub.class);
    /**
     * 访问这个地址返回的是一个JsonArray,JsonArray的每一个元素都有login
     * 和contributions这2个key和其对应的value.提取出来封装进POJO对象中.
     */
    Call<List<Contributor>> call=create.contributors("square", "retrofit");
    try {
        Response<List<Contributor>> response=call.execute();
        List<Contributor>list=response.body();
        for (Contributor c:list) {
            System.out.println(c.toString());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

自定义的Converter(StringConverter)
Response可以获得输入流,我们可以把它转换成任何想要的格式.

自定义的StringConverter转换器

public class StringConverter implements Converter<ResponseBody,String>{
    static final StringConverter.Factory FACTORY=new StringConverter.Factory(){
        @Override
        public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[]  annotations, Retrofit retrofit) {
            /*if (type==StringConverter.class)return  new StringConverter();
            else return null;*/
            return  new StringConverter();
        }
    };
    @Override
    public String convert(ResponseBody value) throws IOException {
        //values.string 把服务器上请求的数据,转换成string格式
//        String str=convertStream2String(value.byteStream());
        return value.string();
    }
    private String convertStream2String(InputStream in) throws IOException {
        //inputStream转换为String 要进行gbk或者utf-8转码,否则乱码
        BufferedReader reader = new BufferedReader(new InputStreamReader(in, "GBK"));
//        BufferedReader reader=new BufferedReader(new InputStreamReader(in));
        StringBuilder sb=new StringBuilder();
        String line=null;
        while((line=reader.readLine())!=null){
            sb.append(line);
            sb.append("\n");
            }
        return sb.toString();
    }
}

public interface StringClient {
    //方法的返回值是String,需要StringConverter转换器Converter把Response转换为String.
    @GET("/")
    Call<String> getString();
}

public static void Get_String(){
    String url="http://tieba.baidu.com";
    Retrofit retrofit=new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(StringConverter.FACTORY)
            .build();
    final StringClient strClient=retrofit.create(StringClient.class);
    Call<String>call=strClient.getString();
    try {
        Response<String> str=call.execute();
        System.out.print(str.body());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Query注解
public interface QueryGET {
    @GET("/sheet")
    Call<String> getString(@Query("name") String name,
                           @Query("age")int age,
                           @QueryMap(encoded=true)
                           Map<String, String> filters
                           );
}

public static void QueryGET(){
    String url="http://tieba.baidu.com";
    Map<String, String> map=new HashMap<>();
    map.put("gender","male");
    map.put("address","sz");
    Retrofit retrofit=new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(StringConverter.FACTORY)
            .build();
    QueryGET queryGET=retrofit.create(QueryGET.class);
    Call<String> call=queryGET.getString("laiqurufeng", 22, map);
    try {
        Response<String>body=call.execute();
        System.out.print(body.body());
    } catch (IOException e) {
        e.printStackTrace();
    }
}

query 访问的参数会添加到路径(path)的后面.

实际访问的url是 http://tieba.baidu.com/sheet?name=laiqurufeng&age=22&gender=male&address=sz  (模拟的访问)

encoded =true表示对url的query进行url编码,同理还有encodeValues. 这2个的值默认都是true的

如果上面的代码换成 map.put("性别","男") ,然后更改@QueryMap(encoded =false )

那么实际访问的url变成了 http://tieba.baidu.com/sheet?name=laiqurufeng&age=22&性别=%E7%94%B7&address=sz (可以看到key没有进行url编码,value进行了url编码).

Header注解

header分为key和value都固定,静态Header注解方法 和 动态Header注解方法

注意header不会相互覆盖.

静态Header

interface FixedHeader{

@Headers({    //静态Header

"Accept: application/vnd.github.v3.full+json",

"User-Agent: Retrofit-Sample-App"

})

@GET("/")

Call<ResponseBody> getResponse();

}

动态Header

interface DynamicHeader{

@Headers("Cache-Control: max-age=640000")       //动态Header

@GET("/")

Call<ResponseBody> getResponse(

@Header("header1")String header1,

@Header("header2")String header2);

//动态Header,其value值可以在调用这个方法时动态传入.

}

例子:

public class PhoneResult {
    /**
     * errNum : 0
     * retMsg : success
     * retData : {"phone":"15210011578","prefix":"1521001","supplier":"移动","province":"北京","city":"北京","suit":"152卡"}
     */
    public int errNum;
    public String retMsg;
    /**
     * phone : 15210011578
     * prefix : 1521001
     * supplier : 移动
     * province : 北京
     * city : 北京
     * suit : 152卡
     */
    public RetDataEntity retData;
    public static class RetDataEntity {
        public String phone;
        public String prefix;
        public String supplier;
        public String province;
        public String city;
        public String suit;

@Override
        public String toString() {
            return "RetDataEntity{" +
                    "phone=‘" + phone + ‘\‘‘ +
                    ", prefix=‘" + prefix + ‘\‘‘ +
                    ", supplier=‘" + supplier + ‘\‘‘ +
                    ", province=‘" + province + ‘\‘‘ +
                    ", city=‘" + city + ‘\‘‘ +
                    ", suit=‘" + suit + ‘\‘‘ +
                    ‘}‘;
        }
    }
}

Service:

动态Header

public interface PhoneService {
    @GET("/apistore/mobilenumber/mobilenumber")
    Call<PhoneResult> getResult(
            @Header("apikey")String apikey,
            @Query("phone")String phone
    );
}

静态Header

public interface PhoneServiceDynamic {
    @Headers("apikey:8e13586b86e4b7f3758ba3bd6c9c9135")
    @GET("/apistore/mobilenumber/mobilenumber")
    Call<PhoneResult> getResult(
            @Query("phone")String phone
    );
}

调用

public static void phone_Query(String phone){
    final String BASE_URL="http://apis.baidu.com";
    final String API_KEY="8e13586b86e4b7f3758ba3bd6c9c9135";
    //1.创建Retrofit对象
    Retrofit retrofit=new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    //2.创建访问API的请求
    PhoneService service=retrofit.create(PhoneService.class);
    Call<PhoneResult>call=service.getResult(API_KEY,phone);
    //3.发送请求
    try {
        Response<PhoneResult>response=call.execute();
        //4.处理结果
        if (response.isSuccessful()) {
            PhoneResult result=response.body();
            if (result!=null) {
                PhoneResult.RetDataEntity entity = result.getRetData();
                System.out.print(entity.toString());
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    /*异步调用

call.enqueue(new Callback<PhoneResult>() {
        @Override
        public void onResponse(Call<PhoneResult> call, Response<PhoneResult> response) {
            //4.处理结果
            if (response.isSuccessful()) {
                PhoneResult result=response.body();
                if (result!=null) {
                    PhoneResult.RetDataEntity entity = result.getRetData();
                    System.out.print(entity.toString());
                }
            }
        }
        @Override
        public void onFailure(Call<PhoneResult> call, Throwable t) {
        }
    });*/
}

上传文件

public interface UploadServer {
    @Headers({//静态Header
            "User-Agent: androidphone"
            })
    @Multipart
    @POST("/service.php?mod=avatar&type=big")
        // upload is a post field
        // without filename it didn‘t work! I use a constant name because server doesn‘t save file on original name
        //@Part("filename=\"1\" ") RequestBody
        //以表单的形式上传图片
    Call<JsonObject> uploadImageM(@Part("file\";filename=\"1") RequestBody file);
//    Call<ResponseBody> uploadImage(@Part("file\"; filename=\"image.png\"") RequestBody file);
    /**
     * 以二进制流的形式上传 图片
     * @param file
     * @return
     */
    @Headers({//静态Header
            "User-Agent:androidphone"
    })
    @POST("/service.php?mod=avatar&type=big")
    Call<ResponseBody> uploadImage(@Body RequestBody file);
}

调用

public static void upload(String fpath) { // path to file like /mnt/sdcard/myfile.txt
    String baseurl="http://dev.123go.net.cn";
    File file = new File(fpath);
    // please check you mime type, i‘m uploading only images
    RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
    /*RequestBody rbody=new MultipartBody.Builder()
            .addPart(requestBody).build();
    RequestBody requestFile =
            RequestBody.create(MediaType.parse("image/jpg"), file);
    MultipartBody.Part body =
            MultipartBody.Part.createFormData("image", file.getName(), requestFile);
    */
    Retrofit retrofit=new Retrofit.Builder()
            .baseUrl(baseurl)
            .addConverterFactory(GsonConverterFactory.create())
            .client(getOkhttpClient())
            .build();
    // 添加描述
    /*String descriptionString = "hello, 这是文件描述";
    RequestBody description =
            RequestBody.create(
                    MediaType.parse("multipart/form-data"), descriptionString);*/
    UploadServer server=retrofit.create(UploadServer.class);
    Call<ResponseBody> call = server.uploadImage(requestBody);
    call.enqueue(new Callback<ResponseBody>() {

@Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            ResponseBody jsonObject=response.body();
            System.out.print(jsonObject.toString());
        }
        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
        }
    });
}

private static OkHttpClient getOkhttpClient(){
        final String cookie="your cookie";
        OkHttpClient httpClient = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public okhttp3.Response intercept(Chain chain) throws IOException {
                        Request request = chain.request()
                                .newBuilder()
//                                .addHeader("Content-Type", " application/x-www-form-urlencoded; charset=UTF-8")
//                                .addHeader("Accept-Encoding", "gzip, deflate")
//                                .addHeader("Connection", "keep-alive")
//                                .addHeader("Accept", "***")
                                .addHeader("Cookie", cookie)
                                .build();
                        return chain.proceed(request);
                    }
                })
                .build();

return httpClient;
    }

来自为知笔记(Wiz)

时间: 2024-08-28 03:07:49

Retrofit 2.1 入门的相关文章

Retrofit网络框架入门使用

1.简介 retrofit其实就是对okhttp做了进一步一层封装优化.我们只需要通过简单的配置就能使用retrofit来进行网络请求了. Retrofit能够直接返回Bean对象,例如如果我们进行一个网络接口的请求,返回来一串json字符串.那么这个时候一般我们都要拿到这个json字符串后进行解析得到对应的Bean对象,Retrofit只要依赖一下Gson的转换库然后进行简单的配置就能够直接拿到Bean对象了,不需要我们自己去解析. 接触过OKHttp的人会发现,Retrofit和OKHttp

Retrofit 入门学习

Retrofit 入门学习官方RetrofitAPI 官方的一个例子 public interface GitHubService { @GET("users/{user}/repos") Call<List<Repo>> listRepos(@Path("user") String user); } 这些注解都有一个参数 value,用来配置其路径,比如示例中的 users/{user}/repos, 我们还注意到在构造 Retrofit

MVP模式入门(结合Rxjava,Retrofit)

本文MVP的sample实现效果: github地址:https://github.com/xurui1995/MvpSample 老规矩,在说对MVP模式的理解之前还是要再谈谈MVC模式,了解了MVC的缺点.我们才知道为什么要用MVP. 关于MVC的图解,我在网上找到了一些图.如下:    MVC模式在开发web或者管理系统中应用很多,我们的View与人交互,人点击鼠标或者输入一些东西时,View会发送相应的指令给Controller,Controller 接到指令,再去调用Model的方法去

Android开发 retrofit入门讲解

前言 retrofit基于okhttp封装的网络请求框架,网络请求的工作本质上是 OkHttp 完成,而 retrofit 仅负责网络请求接口的封装.如果你不了解OKhttp建议你还是先了解它在来学习使用retrofit,传送门:Android 开发 框架系列 OkHttp使用详解 Retrofit优势,就是简洁易用,解耦,扩展性强,可搭配多种Json解析框架(例如Gson),另外还支持RxJava.但是,这篇博客不讲解RxJava配合使用的部分,与RxJava的配合使用将在另外一篇博客中讲解.

Rxjava + Retrofit 你需要掌握的几个经典技巧

本文出处 :Tamic 文/ http://blog.csdn.net/sk719887916/article/details/52132106 Rxjava +Rterofit 需要掌握的几个技巧 RXjava入门和详解请移步 比较有名的<RxJAVA详解>,这里继续前篇一些列的介绍一些容易忽略的技巧. Retrofit+RxJava结合系列请阅读: Retrofit 2.0 超能实践,完美支持Https传输 Retrofit2.0 完美同步Cookie实现免登录 Retrofit 2.0

RxJava入门系列四,Android中的响应式编程

RxJava入门系列四,Android中的响应式编程 在入门系列1,2,3中,我基本介绍了RxJava是如何使用的.但是作为一名Android开发人员,你怎么让RxJava能为你所用呢?这篇博客我将针对Android开发来介绍一下RxJava的使用场景. RxAndroid RxAndroid是为Android打造的RxJava扩展.通过RxAndroid可以让你的Android开发变得更轻松. 首先,RxAndroid中提供了AndroidSchedulers,你可以用它来切换Android线

Retrofit 简介 wiki 文档

简介 Type-safe HTTP client for Android and Java by Square, Inc. GitHub主页:https://github.com/square/retrofit/ WIKI    官网&简易教程 JAR包 依赖与混淆 Retrofit requires at minimum Java 7 or Android 2.3. Snapshots of the development version are available in Sonatype's

Android 网络开源库之-retrofit的解析详解

前言 当前的网络开源库有许多,如volley,okhttp,retrofit等,这三个库当前是比较火的,其中,okhttp和retrofit由square团队开发.关于这三个库的区别,请移步stackoverflow或者知乎查看.开发过程中选择什么样的开源库需要更具我们APP来做出选择.我们选出stackoverflow中的一段话来看下. 上面说,需要与web service通信的时候,我们使用retrofit.百度百科 web service介绍,那么我们见天就来了解下retrofit.

【知识整理】这可能是最好的RxJava 2.x 入门教程(五)

这可能是最好的RxJava 2.x入门教程系列专栏 文章链接: 这可能是最好的RxJava 2.x 入门教程(一) 这可能是最好的RxJava 2.x 入门教程(二) 这可能是最好的RxJava 2.x 入门教程(三) 这可能是最好的RxJava 2.x 入门教程(四) 这可能是最好的RxJava 2.x 入门教程(五) GitHub 代码同步更新:https://github.com/nanchen2251/RxJava2Examples 为了满足大家的饥渴难耐,GitHub将同步更新代码,主