Retrofit2

其他文章:https://blog.csdn.net/chenjie0932/article/details/79558050
https://blog.csdn.net/u011371324/article/details/80568891

https://blog.csdn.net/q469587851/article/details/79621447

新加:https://www.jianshu.com/p/c0bb7b098a58

先添加库,记得在清单加上网络权限    
// Okhttp库
    compile 'com.squareup.okhttp3:okhttp:3.1.2'
    // Retrofit库
    compile 'com.squareup.retrofit2:retrofit:2.0.2'

//关于数据解析器(Converter)
    compile 'com.squareup.retrofit2:converter-scalars:2.0.0'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
//打印日志
    compile 'com.squareup.okhttp3:logging-interceptor:3.1.2'

retrofit介绍,各种注解

package com.example.administrator.myretrofit.demo;

import java.util.Map;

import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.HTTP;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
import retrofit2.http.Path;
import retrofit2.http.Query;
import retrofit2.http.QueryMap;
import retrofit2.http.Streaming;
import retrofit2.http.Url;

/**
 * Created by Administrator on 2018/9/27.
 */

/*
Retrofit注解
Retrofit注解分为三大类,分别是HTTP请求方法注解(8种)、标记类注解(3种)和参数类注解(11种)。

• HTTP请求方法注解:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、HTTP

• 标记类注解:FormUrlEncoded、Multipart、Streaming

• 参数类注解:Headers、Header、Body、Field、FieldMap、Part、PartMap、Path、Query、QueryMap、Url

作者:低调的大雄
链接:https://www.jianshu.com/p/4d67fe493ebf
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

注1: Retrofit2 的baseUlr 必须以 /(斜线) 结束,不然会抛出一个IllegalArgumentException,所以如果你看到别的教程没有以 / 结束,那么多半是直接从Retrofit 1.X 照搬过来的。

*/
public interface GetRequest_Demo {

    //第一类:网络请求方法
    /*
    a. @GET、@POST、@PUT、@DELETE、@HEAD
       以上方法分别对应 HTTP中的网络请求方式
*/
    @GET("openapi.do?keyfrom=Yanzhikai&key=2032414398&type=data&doctype=json&version=1.1&q=car")
    Call<ResponseBody> getCall();

    /*
    b. @HTTP
    作用:替换@GET、@POST、@PUT、@DELETE、@HEAD注解的作用 及 更多功能拓展
    具体使用:通过属性method、path、hasBody进行设置
*/

    /**
     * method:网络请求的方法(区分大小写)     * path:网络请求地址路径     * hasBody:是否有请求体
     */
    @HTTP(method = "GET", path = "blog/{id}", hasBody = false)
    Call<ResponseBody> getCall(@Path("id") int id);    // {id} 表示是一个变量    // method 的值 retrofit 不会做处理,所以要自行保证准确


//    第二类:标记
    /*a. @FormUrlEncoded作用:表示发送form-encoded的数据每个键值对需要用@Filed来注解键名,随后的对象需要提供值。
    b. @Multipart作用:表示发送form-encoded的数据(适用于 有文件 上传的场景)每个键值对需要用@Part来注解键名,随后的对象需要提供值。
---------------------

本文来自 q469587851 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/q469587851/article/details/79621447?utm_source=copy */

    /**
     * 表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
     * * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
     */
    @POST("/form")
    @FormUrlEncoded
    Call<ResponseBody> testFormUrlEncoded1(
            @Field("username") String name, @Field("age") int age);

    /**
     * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
     * * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
     */
    @POST("/form")
    @Multipart
    Call<ResponseBody> testFileUpload1(
            @Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);

    //第三类:网络请求参数
    /*a. @Header & @Headers

作用:添加请求头 &添加不固定的请求头
具体使用如下:*/
// @Header
    @GET("user")
    Call<User> getUser(@Header("Authorization") String authorization, @Header("token") String token);

    // @Headers
    @Headers("Authorization: authorization")
    @GET("user")
    Call<User> getUser();

    //添加多个固定请求头
    @Headers({
            "key1:value1", "key2:value2"
    })
    @GET("user")
    Call<User> getUser2();

//    @GET
//    Call<User> weather(@HeaderMap Map<String, String> headers, @Url String url, @Query("cityname") String cityName);

// 以上的效果是一致的。
// 区别在于使用场景和使用方式
// 1. 使用场景:@Header用于添加不固定的请求头,@Headers用于添加固定的请求头
// 2. 使用方式:@Header作用于方法的参数;@Headers作用于方法

    /*b. @Body

作用:以 Post方式 传递 自定义数据类型 给服务器
特别注意:如果提交的是一个Map,那么作用相当于 @Field
不过Map要经过 FormBody.Builder 类处理成为符合 Okhttp 格式的表单,如:*/
//    FormBody.Builder builder = new FormBody.Builder();
//    builder.add("key","value");


/*c. @Field & @FieldMap

作用:发送 Post请求 时提交请求的表单字段
具体使用:与 @FormUrlEncoded 注解配合使用*/

    /**
     * 表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
     * <code>Field("username")</code> 表示将后面的 <code>String name</code> 中name的取值作为 username 的值
     */
    @POST("/form")
    @FormUrlEncoded
    Call<ResponseBody> testFormUrlEncoded2(
            @Field("username") String name, @Field("age") int age);

    /**
     * Map的key作为表单的键
     */
    @POST("/form")
    @FormUrlEncoded
    Call<ResponseBody> testFormUrlEncoded2(
            @FieldMap Map<String, Object> map);

 /*d. @Part & @PartMap

作用:发送 Post请求 时提交请求的表单字段
与@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于 有文件上传 的场景*/


    /**
     * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
     * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
     */
    @POST("/form")
    @Multipart
    Call<ResponseBody> testFileUpload2(
            @Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);

    /**
     * PartMap 注解支持一个Map作为参数,支持 {@link RequestBody } 类型,
     * 如果有其它的类型,会被{@link retrofit2.Converter}转换,如后面会介绍的 使用{@link com.google.gson.Gson} 的
     * {@link retrofit2.converter.gson.GsonRequestBodyConverter}
     * 所以{@link MultipartBody.Part} 就不适用了,所以文件只能用<b> @Part MultipartBody.Part </b>
     */
    @POST("/form")
    @Multipart
    Call<ResponseBody> testFileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);

    @POST("/form")
    @Multipart
    Call<ResponseBody> testFileUpload13(@PartMap Map<String, RequestBody> args);

/*e. @Query和@QueryMap

作用:用于 @GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)
如:url = http://www.println.net/?cate=android,其中,Query = cate*/

    @GET("/")
    Call<String> cate(@Query("cate") String cate);

    //http://japi.juhe.cn/qqevaluate/qq?key=96efc220a4196fafdfade0c9d1e897ac&qq=295424589
    @GET("/qqevaluate/qq")
    Call<String> getQQData(@Query("key") String appkey, @Query("qq") String qq);

    //在注解中指定路径,定义相对应的参数的集合
    @GET("qqevaluate/qq")
    Call<String> getQQDataMap(@QueryMap Map<String, String> map);

// 其使用方式同 @Field与@FieldMap,这里不作过多描述

/*f. @Path

作用:URL地址的缺省值
具体使用:*/


    @GET("users/{user}/repos")
    Call<ResponseBody> getBlog(@Path("user") String user);
    // 访问的API是:https://api.github.com/users/{user}/repos
    // 在发起请求时, {user} 会被替换为方法的第一个参数 user(被@Path注解作用)

    /*g. @Url

作用:直接传入一个请求的 URL变量 用于URL设置
具体使用:*/

    @GET
    Call<ResponseBody> testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll);
    // 当有URL注解时,@GET传入的URL就可以省略
    // 当GET、POST...HTTP等方法中没有设置Url时,则必须使用 {@link Url}提供

    //PDF文件Retrofit下载@Streaming 是注解大文件的,小文件可以忽略不加注释,但是大文件一定需要注释,不然会出现OOM。
    @Streaming
    @GET
    Call<ResponseBody> retrofitDownloadFile(@Url String fileUrl);

/*@FormUrlEncoded注解表示from表单*/
    /*通过query的方式,其实是把参数拼在URl的后面,使用body是放在请求体*/
    @POST("/form")
    Call<ResponseBody> testFileUpload2(
            @Query("name") String name, @Query("age") String age);
    @POST("/form")
    Call<ResponseBody> testFileUpload2(
            @QueryMap Map<String, String> map);

    //放在请求体   https://blog.csdn.net/wzl_show/article/details/76169501
    @POST("/form")
    Call<ResponseBody> testFileUpload3(
            @Body Map<String, String> map );
    @POST("/form")
    Call<ResponseBody> testFileUpload3(
            @Body User user );
    @POST("/form")
    Call<ResponseBody> testFileUpload3(
            @Body String user );
}

 在MainActivity进行创建

//创建Retrofit对象
         retrofit = new Retrofit.Builder()
                .baseUrl("http://www.baidu.com/")
                .addConverterFactory(ScalarsConverterFactory.create())  //设置内容格式,这种对应的数据返回值是String类型
                .build();



    }

    private void bb () {
        // 具体使用
        GetRequest_Demo service = retrofit.create(GetRequest_Demo.class);
        // @FormUrlEncoded
        Call<ResponseBody> call1 = service.testFormUrlEncoded1("Carson", 24);
        //  @Multipart
        MediaType textType = MediaType.parse("text/plain");
        RequestBody name = RequestBody.create(textType, "Carson");
        RequestBody age = RequestBody.create(textType, "24");
        RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容");
        MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);

        Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);


        // @Field
        Call<ResponseBody> call2 = service.testFormUrlEncoded2("Carson", 24);

        // @FieldMap
        // 实现的效果与上面相同,但要传入Map
        Map<String, Object> map = new HashMap<>();
        map.put("username", "Carson");
        map.put("age", 24);
        Call<ResponseBody> call0 = service.testFormUrlEncoded2(map);


        // @Part
        Call<ResponseBody> call4 = service.testFileUpload2(name, age, filePart);
//        ResponseBodyPrinter.printResponseBody(call4);

        // @PartMap
        // 实现和上面同样的效果
        Map<String, RequestBody> fileUpload2Args = new HashMap<>();
        fileUpload2Args.put("name", name);
        fileUpload2Args.put("age", age);
        //这里并不会被当成文件,因为没有文件名(包含在Content-Disposition请求头中),但上面的 filePart 有
        //fileUpload2Args.put("file", file);
        Call<ResponseBody> call5 = service.testFileUpload2(fileUpload2Args, filePart); //单独处理文件
//        ResponseBodyPrinter.printResponseBody(call5);
    }

还可以增加拦截器,设置请求头,打印日志等

  //日志
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        //统一在url后面添加参数
        AppendUrlParamInterceptor appendUrlParamInterceptor = new AppendUrlParamInterceptor();
        //统一增加请求头
        AppendHeaderParamInterceptor header = new AppendHeaderParamInterceptor();

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(httpLoggingInterceptor)
                .addInterceptor(appendUrlParamInterceptor)
                .addInterceptor(header)
                .build();


        //步骤4:创建Retrofit对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://fy.iciba.com/") // 设置 网络请求 Url
                .client(okHttpClient)
                .addConverterFactory(GsonConverterFactory.create()) //设置使用Gson解析(记得加入依赖)
                .build();
AppendHeaderParamInterceptor.java

public class AppendHeaderParamInterceptor implements Interceptor {
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();//拿到发送的请求
        Headers headers =  request.headers().newBuilder().add("token","mytoken").build();
        Request newRequest = request.newBuilder().headers(headers).build();
        return chain.proceed(newRequest);
    }
}
AppendUrlParamInterceptor.java
/**
 * Created by Administrator on 2018/9/27.
 *
 * 拦截器,拿到请求,并在请求uil上增加参数
 */

public class AppendUrlParamInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();//拿到发送的请求
        HttpUrl httpUrl =  request.url().newBuilder().addQueryParameter("version","1.0")
                .addQueryParameter("channel","360")
                .addQueryParameter("versionCode","10")
                .addQueryParameter("deviceId","abasersgdhdjjfs5688")
                .build();

        //重要一步 使用新的url构建一个Request发送给后台
        Request newRequest = request.newBuilder().url(httpUrl).build();
        return chain.proceed(newRequest);
    }
}


//        本文来自 zhoushenxian 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/coderinchina/article/details/78669503?utm_source=copy
HandleNoNetInterceptor.java  判断网络

public class HandleNoNetInterceptor implements Interceptor {
    private Context content;
    public HandleNoNetInterceptor(Context content) {
        this.content = content;
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
//        if(NetUtils.isNetworkAvalible(content)){
//            return chain.proceed(chain.request());
//        }else{
            Handler handler = new Handler(Looper.getMainLooper());
            handler.post(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(content,"网络异常,请检查你的网络",Toast.LENGTH_LONG).show();
                }
            });
            throw new RuntimeException("网络异常了~~~~~");
//        }
    }
}
a. 关于数据解析器(Converter)Retrofit支持多种数据解析方式使用时需要在Gradle添加依赖数据解析器Gradle依赖
Gsoncom.squareup.retrofit2:converter-gson:2.0.2
Jacksoncom.squareup.retrofit2:converter-jackson:2.0.2
Simple XMLcom.squareup.retrofit2:converter-simplexml:2.0.2
Protobufcom.squareup.retrofit2:converter-protobuf:2.0.2
Moshicom.squareup.retrofit2:converter-moshi:2.0.2
Wirecom.squareup.retrofit2:converter-wire:2.0.2
Scalarscom.squareup.retrofit2:converter-scalars:2.0.2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值