注解大全(实例代码结合RxJava)
实例全展示:建立一个接口服务,将所有注解进行实例展示(持续更新中^_^)
public interface ILoginApi {
//假设的服务器地址: http://192.168.11.112/api/
//-----------------------------------------------------------------------------
//@GET注解的使用
//简单的GET请求,无参数
@GET("get_login")
Observable<ResultModel> get_login();
//相当于常规的这样的写法 http://192.168.11.112/api/get_login
//带Query参数的GET请求,参数在URL的?之后
@GET("get_login")
Observable<ResultModel> get_login_query(@Query("username") String username);
//相当于常规的写法 http://192.168.11.112/api/get_login?username={具体的用户id值}
//带不确定个数的参数的GET请求,参数在URL的?之后
@GET("get_login")
Observable<ResultModel> get_login_query(@QueryMap Map<String,String> map);
//相当于常规的写法 http://192.168.11.112/api/get_login?username={具体的用户id只}&{密码}。。。后面还可以依次添加多个。。。
//带@Path参数的GET请求(URL带参数)
@GET("get_login/{username}")
Observable<ResultModel> get_login_path(@Path("username") String username);
//相当于常规的写法:http://192.168.11.112/api/get_login/{username}
//-----------------------------------------------------------------------------
//@Query注解的几种使用情况使用
@GET("login_query")
Observable<ResultModel> login_get_query(@Query("username") String username,@Query("password") String password);//测试参数为用户名和密码
//-----------------------------------------------------------------------------
//@Body注解的几种使用情况
@POST("login_body")
Observable<ResultModel> login_post_body(@Body LoginBean loginBean);//参数是实体类
@POST("login_body")
Observable<ResultModel> login_post_body(@Body RequestBody requestBody);
//为RequestBody赋值
//JSONObject requestData = new JSONObject();
//try {
// requestData.put("name","小李");
// requestData.put("sex","男");
//} catch (JSONException e) {
// e.printStackTrace();
//}
//RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"),requestData.toString());
//-----------------------------------------------------------------------------
//@Field注解
@FormUrlEncoded
@POST
Observable<ResultModel> login_post_field(@Field("username") String username,@Field("password") String password);
//-----------------------------------------------------------------------------
//@FieldMap注解的应用实例
@FormUrlEncoded
@POST("post_login_fieldmap")
Observable<ResultModel> post_login_fieldmap(@FieldMap Map<String,String> map);
//-----------------------------------------------------------------------------
//@FormUrlEncoded注解的应用实例
@FormUrlEncoded
@POST
Observable<ResultModel> post_login_formurlencoded(@Field("username") String username,@FieldMap Map<String,String> map);
//-----------------------------------------------------------------------------
//@Header 注解的应用实例
//动态添加一个Header参数
@GET("get_header")
Observable<ResultModel> get_header(@Header("Authorization") String authorization);
//@HeaderMap注解的应用实例
//动态添加多个Header参数
@GET("get_headermap")
Observable<ResultModel> get_headermap(@HeaderMap Map<String,String> headers);
//-----------------------------------------------------------------------------
//@Headerws注解的应用实例
//静态添加一个Header参数
@Headers("Authorization: authorization")//这里authorization就是上面方法里传进来变量的值
@GET("get_header")
Observable<ResultModel> get_header();
@FormUrlEncoded
@POST("post_headers")
@Headers("Content-Type:application/x-www-form-urlencoded; charset=utf-8")//解决POST到服务器数据中文乱码问题
Observable<ResultModel> post_headers(@Field("nickname") String nickname);//昵称
//-----------------------------------------------------------------------------
//静态添加多个Header参数
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("get_headers")
Observable<ResultModel> get_headers();
//还有一种是在代码里添加拦截器的方式,添加Header 参数,如下
// OkHttpClient.Builder client = new OkHttpClient.Builder();
// client.addInterceptor(new Interceptor() {
// @Override
// public Response intercept(Interceptor.Chain chain) throws IOException {
// Request original = chain.request();
// Request request = original.newBuilder()
// .header("User-Agent", "AppName")
// .header("Accept", "application/vnd.yourapi.v1.full+json")
// .method(original.method(), original.body())
// .build();
//
// return chain.proceed(request);
// }
// }
//
// OkHttpClient httpClient = client.build();
// Retrofit retrofit = new Retrofit.Builder()
// .baseUrl(Constant.BASE_URL)
// .addConverterFactory(GsonConverterFactory.create())
// .client(httpClient)
// .build();
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request original = chain.request();
Request request = original.newBuilder()
.addHeader("Cache-Control", "no-cache")
.addHeader("Cache-Control", "no-cache")
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
}
OkHttpClient client = httpClient.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
OkHtt请求头通过拦截器添加Header,两种方式的不同
.header(key, val):如果key相同,最后一个val会将前面的val值覆盖
.addHeader(key, val):如果key相同,最后一个val不会将前面的val值覆盖,而是新添加一个Header
//-----------------------------------------------------------------------------
//上传照片 文件
@Multipart
@PUT("user/photo")
Observable<ResultModel> uploadUserPhoto(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
@Multipart
@POST("upload")
Observable<ResultModel> upload(@Part("description") RequestBody description,@Part MultipartBody.Part file);
@Multipart
@POST("upload_file") //这里是自己post文件的地址
Observable<ResultModel> postGoodsReturnPostEntitys(@PartMap Map<String, RequestBody> map, @Part List<MultipartBody.Part> parts);
//-----------------------------------------------------------------------------
//@Path注解
@GET("department/{id}/users")
Observable<ResultModel> get_path(@Path("id") int departmentId);
//--> http://baseurl/department/departmentId/users
//等同于:
@GET
Observable<ResultModel> get_path(@Url String url);
//-----------------------------------------------------------------------------
@PUT注解
@Multipart
@PUT("user/photo")
Observable<ResultModel> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
//-----------------------------------------------------------------------------
@streaming注解
@Streaming
@GET
Observable<ResultModel> downloadFile(@Url String fileUrl); //下载大文件
}
一、方法注解(顾名思义就是针对方法的)
@GET注解
源码:
/** Make a GET request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface GET {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
是个啥东西:
是方法注解,
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
- 不能将@FromUrlEncoded注解和@GET注解一起使用法则抛出
java.lang.IllegalArgumentException:FormUrlEncoded can only be specified on HTTP methods with request body (e.g., @POST).
的异常 - 不能与@Field @FieldMap参数注解一起使用(没有进行过代码实例测试,但是因为知道@Field @FieldMap必须和@FormUrlEncoded一起使用,而@GET注解不能和@FormUrlEncoded一起使用,所以推断出前面的结论^_^)
-------------------------------------------------------------------------------------------------------------------------------------------------------
@POST注解
源码:
/** Make a POST request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface POST {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
是个啥东西:
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
- 如果请求为post实现,那么最好传递参数时使用@Field、@FieldMap和@FormUrlEncoded。因为@Query和或QueryMap都是将参数拼接在url后面的,而@Field或@FieldMap传递的参数时放在请求体的
-------------------------------------------------------------------------------------------------------------------------------------------------------
@PUT注解
源码:
/** Make a PUT request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface PUT {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
是个啥东西:
PUT方法用来创建一个URI已知的资源,或对已知资源进行完全替换,比如users/1,因此PUT方法一般会用来更新一个已知资源
网络请求接口的方法
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
-------------------------------------------------------------------------------------------------------------------------------------------------------
@DELETE注解
源码:
/** Make a DELETE request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface DELETE {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
是个啥东西:
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
因为默认delete请求是不能带body的 所以需要单独在用注解 @HTTP(method = "DELETE", path = "/路径", hasBody = true)设置为hasBody = true ,这样才能在@DELETE注解中用@Body注解
-------------------------------------------------------------------------------------------------------------------------------------------------------
@PATCH注解
源码:
/** Make a PATCH request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface PATCH {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
是个啥东西:
PATCH方法是新引入的,是对PUT方法的补充,用来对已知资源进行局部更新
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
-------------------------------------------------------------------------------------------------------------------------------------------------------
@HEAD注解
源码:
/** Make a HEAD request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface HEAD {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
是个啥东西:
是方法注解,与参数注解@Header不同,只请求页面的首部
用于发送一个HEAD请求
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
HEAD一般注解必须相对或绝对路径或全路径,如果不想在HEAD注解后添加请求路径,则可以在方法的第一个参数中用@Url注解添加请求路径
-------------------------------------------------------------------------------------------------------------------------------------------------------
@OPTIONS注解
源码:
/** Make an OPTIONS request. */
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface OPTIONS {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
是个啥东西:
允许客户端查看服务器的性能
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
- OPTIONS注解一般必须添加相对路径或绝对路径或者全路径,如果不想在OPTIONS注解后添加请求路径,则可以在方法的第一个参数中用@Url注解添加请求路径
-------------------------------------------------------------------------------------------------------------------------------------------------------
@HTTP 注解//可以替代其他任意一种注解方法?那干脆只保留这个一个注解好了,呵呵
源码:
/**
* Use a custom HTTP verb for a request.
* <pre><code>
* interface Service {
* @HTTP(method = "CUSTOM", path = "custom/endpoint/")
* Call<ResponseBody> customEndpoint();
* }
* </code></pre>
* This annotation can also used for sending {@code DELETE} with a request body:
* <pre><code>
* interface Service {
* @HTTP(method = "DELETE", path = "remove/", hasBody = true)
* Call<ResponseBody> deleteObject(@Body RequestBody object);
* }
* </code></pre>
*/
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface HTTP {
String method();
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String path() default "";
boolean hasBody() default false;
}
这个@http应该算作是所有注解的祖宗了,是其他注解的原始分解格式写法 呵呵@HTTP(method = "POST/GET/DELETE/..", path = "/这里写你的路径", hasBody = false/true)
所有其他的方法注解都可以写成这个格式 例如:
/**
* method 表示请求的方法,大小写无关
* path表示访问路径
* hasBody表示是否有请求体 true 表示使用方法体 false表示不使用方法体
*/
@HTTP(method = "POST", path = "/revoke", hasBody = false)//都是以@HTTP开头, method="GET 或POST或其他" path是访问路径 hasBody 设置为true则 使用@Body ,否则不能用@Body注解
例如:
@HTTP(method = "DELETE", path = "/路径", hasBody = true)
Observable<LoginModel> del(@Body LoginBean loginBean);//举个假设的例子,不是很贴切,讲究看
二、参数注解(顾名思义就是针对参数的)
-------------------------------------------------------------------------------------------------------------------------------------------------------
@Header注解
源码:
/**
* Replaces the header with the value of its target.
* <pre><code>
* @GET("/")
* Call<ResponseBody> foo(@Header("Accept-Language") String lang);
* </code></pre>
* Header parameters may be {@code null} which will omit them from the request. Passing a
* {@link java.util.List List} or array will result in a header for each non-{@code null} item.
* <p>
* <strong>Note:</strong> Headers do not overwrite each other. All headers with the same name will
* be included in the request.
*
* @see Headers
* @see HeaderMap
*/
@Documented
@Retention(RUNTIME)
@Target(PARAMETER)
public @interface Header {
String value();
}
是个啥东西:
http请求是网络请求的应用层协议,他包括以下3部分:
请求行(请求地址,请求方式,协议版本) + 请求头(header)+ 请求体(post请求才有)
请求头参数介绍:
Accept:text/html 告诉服务器能够发送哪些媒体类型,如Accept:text/json等
Accept-Charset:告诉服务器能够发送哪些字符集
Accept-Encoding:gzip,deflate,sdch 告诉服务器能够发送的哪些编码方式
Accept-Language:zh-CN,zh;q=0.8" ---> 告诉服务器客户端支持的语言:中文
Connection:keey-alive
Cookie: 用来存放Cookie的信息
Host: 用来存放请求服务器的主机名和端口号
Referer:
content-type : application/json;charset=utf-8 ---> 告诉服务器我们传递的什么类型的数据实体
Date: Tue, 15 Nov 2010 08:12:31 GMT ---> 告诉服务器请求的日期时间
User-Agent: Mozilla/5.0 (Linux; X11) ---> 告诉服务器是用的mozilla浏览器和linux系统??
Authorization: QWxhZGRpbjpvcGVuIHNlc2FtZQ== ---> 告诉服务器授权证书,安全处理??
是参数注解
header处理,不能被互相覆盖,用于修饰参数,在参数中的@Header可以作为@Headers的增项使用
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
-------------------------------------------------------------------------------------------------------------------------------------------------------
@Headers注解
源码:
/**
* Adds headers literally supplied in the {@code value}.
* <pre><code>
* @Headers("Cache-Control: max-age=640000")
* @GET("/")
* ...
*
* @Headers({
* "X-Foo: Bar",
* "X-Ping: Pong"
* })
* @GET("/")
* ...
* </code></pre>
* <strong>Note:</strong> Headers do not overwrite each other. All headers with the same name will
* be included in the request.
*
* @see Header
* @see HeaderMap
*/
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Headers {
String[] value();
}
是个啥东西:
是参数注解
@Headers 用于修饰方法,用于设置多个Header值
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
-------------------------------------------------------------------------------------------------------------------------------------------------------
@Url注解
源码:
/**
* URL resolved against the {@linkplain Retrofit#baseUrl() base URL}.
* <pre><code>
* @GET
* Call<ResponseBody> list(@Url String url);
* </code></pre>
* <p>
* See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* the value will be resolved against a base URL to create the full endpoint URL.
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Url {
}
是个啥东西:
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
使用全路径复写baseURL,适用于非同一baseURL的场景
若需要重新定义接口地址,可以使用@Url,将地址以参数的形式传入即可
@GET//在GET注解中使用Url注解
Observable<ResponseBody> getUrl(@Url String url);
-------------------------------------------------------------------------------------------------------------------------------------------------------
@Body注解
源码:Body.java
/**
* Use this annotation on a service method param when you want to directly control the request body
* of a POST/PUT request (instead of sending in as request parameters or form-style request
* body). The object will be serialized using the {@link Retrofit Retrofit} instance
* {@link Converter Converter} and the result will be set directly as the
* request body.
* <p>
* Body parameters may not be {@code null}.
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Body {
}
是个啥东西:Body相当于多个@Field或@Query. 修饰实体类 使用这个注解可以把参数放到请求体(实体类)中,适用于 POST/PUT请求
在哪里使用:针对接口中定义的方法的参数(这个参数是一个实体类)来使用
什么时候使用:参数很多的时候可以使用@Body,这样非常方便
怎么使用:
//在接口服务中的定义的方法中针对参数进行使用
@GET("login")
Observable<LoginModel> login(@Body LoginBean loginBean);
注意事项:
- 使用该注解定义的参数不可为null
- @Body标签不能同时和@FormUrlEncoded、@Multipart标签同时使用
- GET请求不能使用@Body注解,否则会报错
- 相当于多个@Field,以对象的形式提交
-------------------------------------------------------------------------------------------------------------------------------------------------------
@Path注解
源码:
/**
* Named replacement in a URL path segment. Values are converted to string using
* {@link String#valueOf(Object)} and URL encoded.
* <p>
* Simple example:
* <pre><code>
* @GET("/image/{id}")
* Call<ResponseBody> example(@Path("id") int id);
* </code></pre>
* Calling with {@code foo.example(1)} yields {@code /image/1}.
* <p>
* Values are URL encoded by default. Disable with {@code encoded=true}.
* <pre><code>
* @GET("/user/{name}")
* Call<ResponseBody> encoded(@Path("name") String name);
*
* @GET("/user/{name}")
* Call<ResponseBody> notEncoded(@Path(value="name", encoded=true) String name);
* </code></pre>
* Calling {@code foo.encoded("John+Doe")} yields {@code /user/John%2BDoe} whereas
* {@code foo.notEncoded("John+Doe")} yields {@code /user/John+Doe}.
* <p>
* Path parameters may not be {@code null}.
*/
@Documented
@Retention(RUNTIME)
@Target(PARAMETER)
public @interface Path {
String value();
/**
* Specifies whether the argument value to the annotated method parameter is already URL encoded.
*/
boolean encoded() default false;
}
是个啥东西:
Path是网址中的参数,例如:trades/{userId}
使用@Path时,path对应的路径不能包含”/”,否则会将其转化为%2F。在遇到想动态的拼接多节url时,还是使用@Url吧
URL占位符,用于替换和动态更新,相应的参数必须使用相同的字符串被@Path进行注释
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
@Field注解
源码:
/**
* Named pair for a form-encoded request.
* <p>
* Values are converted to strings using {@link String#valueOf(Object)} and then form URL encoded.
* {@code null} values are ignored. Passing a {@link java.util.List List} or array will result in a
* field pair for each non-{@code null} item.
* <p>
* Simple Example:
* <pre><code>
* @FormUrlEncoded
* @POST("/")
* Call<ResponseBody> example(
* @Field("name") String name,
* @Field("occupation") String occupation);
* </code></pre>
* Calling with {@code foo.example("Bob Smith", "President")} yields a request body of
* {@code name=Bob+Smith&occupation=President}.
* <p>
* Array/Varargs Example:
* <pre><code>
* @FormUrlEncoded
* @POST("/list")
* Call<ResponseBody> example(@Field("name") String... names);
* </code></pre>
* Calling with {@code foo.example("Bob Smith", "Jane Doe")} yields a request body of
* {@code name=Bob+Smith&name=Jane+Doe}.
*
* @see FormUrlEncoded
* @see FieldMap
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Field {
String value();
/** Specifies whether the {@linkplain #value() name} and value are already URL encoded. */
boolean encoded() default false;
}
是个啥东西:
作用于方法的参数,用于POST请求 ,用于发送一个表单请求
用于Post方式传递参数,需要在请求接口方法上添加@FormUrlEncoded
,即以表单的方式传递参数
在哪里使用:
什么时候使用:
怎么使用:
@FormUrlEncoded
@POST("login")
Observable<LoginModel> login(@Field("username") String username,@Field("password") String password);
}
注意事项:
- @Field注解必须和@FromUrlEncoded注解一起使用否则抛出
java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)
的异常 - @Field和@FieldMap可以结合在一起使用
@FieldMap注解
源码:
/**
* Named key/value pairs for a form-encoded request.
* <p>
* Simple Example:
* <pre><code>
* @FormUrlEncoded
* @POST("/things")
* Call<ResponseBody> things(@FieldMap Map<String, String> fields);
* </code></pre>
* Calling with {@code foo.things(ImmutableMap.of("foo", "bar", "kit", "kat")} yields a request
* body of {@code foo=bar&kit=kat}.
* <p>
* A {@code null} value for the map, as a key, or as a value is not allowed.
*
* @see FormUrlEncoded
* @see Field
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface FieldMap {
/** Specifies whether the names and values are already URL encoded. */
boolean encoded() default false;
}
是个啥东西:
以map形式提交多个Field,在Retrofit2.0版本之后出现?
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
- 以map形式提交多个Field(Retrofit2.0之后添加)
- 要与@FormUrlEncoded一起使用,否则抛异常
java.lang.IllegalArgumentException: @Field parameters can only be used with form encoding. (parameter #1)
的错误异常 - 传递的参数是放在请求体内(注意@QueryMap参数是拼接在Url后面的)
@Part注解
源码:
/**
* Denotes a single part of a multi-part request.
* <p>
* The parameter type on which this annotation exists will be processed in one of three ways:
* <ul>
* <li>If the type is {@link okhttp3.MultipartBody.Part} the contents will be used directly. Omit
* the name from the annotation (i.e., {@code @Part MultipartBody.Part part}).</li>
* <li>If the type is {@link okhttp3.RequestBody RequestBody} the value will be used
* directly with its content type. Supply the part name in the annotation (e.g.,
* {@code @Part("foo") RequestBody foo}).</li>
* <li>Other object types will be converted to an appropriate representation by using
* {@linkplain Converter a converter}. Supply the part name in the annotation (e.g.,
* {@code @Part("foo") Image photo}).</li>
* </ul>
* <p>
* Values may be {@code null} which will omit them from the request body.
* <p>
* <pre><code>
* @Multipart
* @POST("/")
* Call<ResponseBody> example(
* @Part("description") String description,
* @Part(value = "image", encoding = "8-bit") RequestBody image);
* </code></pre>
* <p>
* Part parameters may not be {@code null}.
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Part {
/**
* The name of the part. Required for all parameter types except
* {@link okhttp3.MultipartBody.Part}.
*/
String value() default "";
/** The {@code Content-Transfer-Encoding} of this part. */
String encoding() default "binary";
}
是个啥东西:
作用于方法的参数,用于定义Multipart请求的每个part
用于POST文件上传
其中@Part MultipartBody.Part代表文件,@Part("key") RequestBody代表参数
如果需要上传多个文件,就声明多个 Part 参数,或者试试 PartMap
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
使用该注解定义的参数,参数值可以为空,为空时则忽略
@PartMap注解
源码:
/**
* Denotes name and value parts of a multi-part request.
* <p>
* Values of the map on which this annotation exists will be processed in one of two ways:
* <ul>
* <li>If the type is {@link okhttp3.RequestBody RequestBody} the value will be used
* directly with its content type.</li>
* <li>Other object types will be converted to an appropriate representation by using
* {@linkplain Converter a converter}.</li>
* </ul>
* <p>
* <pre><code>
* @Multipart
* @POST("/upload")
* Call<ResponseBody> upload(
* @Part("file") RequestBody file,
* @PartMap Map<String, RequestBody> params);
* </code></pre>
* <p>
* A {@code null} value for the map, as a key, or as a value is not allowed.
*
* @see Multipart
* @see Part
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface PartMap {
/** The {@code Content-Transfer-Encoding} of the parts. */
String encoding() default "binary";
}
是个啥东西:
如果需要上传多个文件,就声明多个 Part 参数,或者试试 PartMap
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
@Query注解
源码:
/**
* Query parameter appended to the URL.
* <p>
* Values are converted to strings using {@link String#valueOf(Object)} and then URL encoded.
* {@code null} values are ignored. Passing a {@link java.util.List List} or array will result in a
* query parameter for each non-{@code null} item.
* <p>
* Simple Example:
* <pre><code>
* @GET("/list")
* Call<ResponseBody> list(@Query("page") int page);
* </code></pre>
* Calling with {@code foo.list(1)} yields {@code /list?page=1}.
* <p>
* Example with {@code null}:
* <pre><code>
* @GET("/list")
* Call<ResponseBody> list(@Query("category") String category);
* </code></pre>
* Calling with {@code foo.list(null)} yields {@code /list}.
* <p>
* Array/Varargs Example:
* <pre><code>
* @GET("/list")
* Call<ResponseBody> list(@Query("category") String... categories);
* </code></pre>
* Calling with {@code foo.list("bar", "baz")} yields
* {@code /list?category=bar&category=baz}.
* <p>
* Parameter names and values are URL encoded by default. Specify {@link #encoded() encoded=true}
* to change this behavior.
* <pre><code>
* @GET("/search")
* Call<ResponseBody> list(@Query(value="foo", encoded=true) String foo);
* </code></pre>
* Calling with {@code foo.list("foo+bar"))} yields {@code /search?foo=foo+bar}.
*
* @see QueryMap
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface Query {
/** The query parameter name. */
String value();
/**
* Specifies whether the parameter {@linkplain #value() name} and value are already URL encoded.
*/
boolean encoded() default false;
}
是个啥东西:
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
- 等同于@GET(“login?username=userNameValue”),即将
@Query
的key-value
添加到url后面组成get方式的参数 - 是将参数拼接在URL的后面(而@Field传递的参数是放在请求体内的)
@QueryMap注解
源码:
/**
* Query parameter keys and values appended to the URL.
* <p>
* Both keys and values are converted to strings using {@link String#valueOf(Object)}.
* <p>
* Simple Example:
* <pre><code>
* @GET("/search")
* Call<ResponseBody> list(@QueryMap Map<String, String> filters);
* </code></pre>
* Calling with {@code foo.list(ImmutableMap.of("foo", "bar", "kit", "kat"))} yields
* {@code /search?foo=bar&kit=kat}.
* <p>
* Map keys and values representing parameter values are URL encoded by default. Specify
* {@link #encoded() encoded=true} to change this behavior.
* <pre><code>
* @GET("/search")
* Call<ResponseBody> list(@QueryMap(encoded=true) Map<String, String> filters);
* </code></pre>
* Calling with {@code foo.list(ImmutableMap.of("foo", "foo+bar"))} yields
* {@code /search?foo=foo+bar}.
* <p>
* A {@code null} value for the map, as a key, or as a value is not allowed.
*
* @see Query
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface QueryMap {
/** Specifies whether parameter names and values are already URL encoded. */
boolean encoded() default false;
}
是个啥东西:
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
- QueryMap 是不能注解实体类的
- 等同于@GET(“login?username=userNameValue”),即将
@Query
的key-value
添加到url后面组成get方式的参数 - 是将参数拼接在Url的后面(@FieldMap是放在请求体内的)
三、标记
@Streaming注解
源码:
/**
* Treat the response body on methods returning {@link okhttp3.Response Response} as is,
* i.e. without converting {@link okhttp3.Response#body() body()} to {@code byte[]}.
*/
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Streaming {
}
是个啥东西:
响应体的数据用流的形式返回
在哪里使用:
什么时候使用:
用于下载大文件的时候使用
怎么使用:
注意事项:
用于下载大文件
未使用该注解,默认会把数据全部载入内存,之后通过流获取数据也是读取内存中数据,所以返回数据较大时,需要使用该注解
@FormUrlEncoded注解
标志是表单数据
源码:
/**
* Denotes that the request body will use form URL encoding. Fields should be declared as
* parameters and annotated with {@link Field @Field}.
* <p>
* Requests made with this annotation will have {@code application/x-www-form-urlencoded} MIME
* type. Field names and values will be UTF-8 encoded before being URI-encoded in accordance to
* <a href="http://tools.ietf.org/html/rfc3986">RFC-3986</a>.
*/
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface FormUrlEncoded {
}
是个啥东西:
用于修饰@Field和@FieldMap注解
- 以form表单方式上传
- @Field
- @FieldMap 使用类似@QueryMap
使用该注解,表示请求正文将使用表单网址编码,
使用FormUrlEncoded注解的请求将具”application / x-www-form-urlencoded” MIME类型。字段名称和值将先进行UTF-8进行编码,再根据RFC-3986进行URI编码
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
- 表明是一个表单格式的请求(Content-Type:application/x-www-form-urlencoded)
- java.lang.IllegalArgumentException: Form-encoded method must contain at least one @Field 至少要有一个@Field注解?
@HeaderMap注解
源码:
/**
* Adds headers specified in the {@link Map}.
* <p>
* Values are converted to strings using {@link String#valueOf(Object)}.
* <p>
* Simple Example:
* <pre>
* @GET("/search")
* void list(@HeaderMap Map<String, String> headers);
*
* ...
*
* // The following call yields /search with headers
* // Accept: text/plain and Accept-Charset: utf-8
* foo.list(ImmutableMap.of("Accept", "text/plain", "Accept-Charset", "utf-8"));
* </pre>
*
* @see Header
* @see Headers
*/
@Documented
@Target(PARAMETER)
@Retention(RUNTIME)
public @interface HeaderMap {
}
是个啥东西:
用来动态添加多个请求头
在哪里使用:
在参数中使用
什么时候使用:
怎么使用:
注意事项:
@MultiPart注解
用于文件 图片的上传
源码:
/**
* Denotes that the request body is multi-part. Parts should be declared as parameters and
* annotated with {@link Part @Part}.
*/
@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface Multipart {
}
是个啥东西:
需要添加@Multipart表示支持文件上传的表单,Content-Type: multipart/form-data
当函数有@Multipart
注解的时候,将会发送multipart
数据,Parts都使用@Part
注解进行声明
Multipart parts要使用Retrofit的众多转换器之一或者实现RequestBody
来处理自己的序列化
在哪里使用:
什么时候使用:
怎么使用:
注意事项:
涉及到的文件
实体类
public class LoginBean {
String username;
String password;
LoginBean(String user_name, String pass_word) {
this.username = user_name;
this.password = pass_word;
}
}
结果模型
public class ResultModel {
public int code;
public String message;
}
常用的编码方式
form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。
1.x-www-form-urlencoded
当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url。
2.multipart/form-data
当action为post时候,浏览器把form数据封装到http body中,然后发送到server。 如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)
application/json和application/x-www-form-urlencoded都是表单数据发送时的编码类型。
EncType:
enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。
默认地,表单数据会编码为 "application/x-www-form-urlencoded"。就是说,在发送到服务器之前,所有字符都会进行编码。
博采众长,为众所用
日日持续更新中,敬请各位查缺补漏
O(∩_∩)O哈哈~