美文网首页workAndroid 入门进阶Android网络请求
【Android】Retrofit网络请求参数注解,@Path、

【Android】Retrofit网络请求参数注解,@Path、

作者: 带心情去旅行 | 来源:发表于2016-04-22 16:11 被阅读36502次

    对Retrofit已经使用了一点时间了,是时候归纳一下各种网络请求的service了。

    下面分为GET、POST、DELETE还有PUT的请求,说明@Path、@Query、@QueryMap、@Body、@Field的用法。

    初始化Retrofit
    String BASE_URL = "http://102.10.10.132/api/";
    Retrofit retrofit = new Retrofit.Builder() 
            .baseUrl(BASE_URL)
            .build();
    

    GET

    样式1(一个简单的get请求)

    http://102.10.10.132/api/News

        @GET("News")
        Call<NewsBean> getItem();
    

    样式2(URL中有参数)

    http://102.10.10.132/api/News/1
    http://102.10.10.132/api/News/{资讯id}

        @GET("News/{newsId}")
        Call<NewsBean> getItem(@Path("newsId") String newsId);
    


    http://102.10.10.132/api/News/1/类型1
    http://102.10.10.132/api/News/{资讯id}/{类型}

        @GET("News/{newsId}/{type}")
        Call<NewsBean> getItem(@Path("newsId") String newsId, @Path("type") String type);
    

    样式3(参数在URL问号之后)

    http://102.10.10.132/api/News?newsId=1
    http://102.10.10.132/api/News?newsId={资讯id}

        @GET("News")
        Call<NewsBean> getItem(@Query("newsId") String newsId);
    


    http://102.10.10.132/api/News?newsId=1&type=类型1
    http://102.10.10.132/api/News?newsId={资讯id}&type={类型}

        @GET("News")
        Call<NewsBean> getItem(@Query("newsId") String newsId, @Query("type") String type);
    

    样式4(多个参数在URL问号之后,且个数不确定)

    http://102.10.10.132/api/News?newsId=1&type=类型1...
    http://102.10.10.132/api/News?newsId={资讯id}&type={类型}...

        @GET("News")
        Call<NewsBean> getItem(@QueryMap Map<String, String> map);
    

    也可以

        @GET("News")
        Call<NewsBean> getItem(
                  @Query("newsId") String newsId,
                  @QueryMap Map<String, String> map);
    

    POST

    样式1(需要补全URL,post的数据只有一条reason)

    http://102.10.10.132/api/Comments/1
    http://102.10.10.132/api/Comments/{newsId}

        @FormUrlEncoded
        @POST("Comments/{newsId}")
        Call<Comment> reportComment(
            @Path("newsId") String commentId,
            @Field("reason") String reason);
    

    样式2(需要补全URL,问号后加入access_token,post的数据只有一条reason)

    http://102.10.10.132/api/Comments/1?access_token=1234123
    http://102.10.10.132/api/Comments/{newsId}?access_token={access_token}

        @FormUrlEncoded
        @POST("Comments/{newsId}")
        Call<Comment> reportComment(
            @Path("newsId") String commentId,
            @Query("access_token") String access_token,
            @Field("reason") String reason);
    

    样式3(需要补全URL,问号后加入access_token,post一个body(对象))

    http://102.10.10.132/api/Comments/1?access_token=1234123
    http://102.10.10.132/api/Comments/{newsId}?access_token={access_token}

        @POST("Comments/{newsId}")
        Call<Comment> reportComment(
            @Path("newsId") String commentId,
            @Query("access_token") String access_token,
            @Body CommentBean bean);
    

    DELETE

    样式1(需要补全URL)

    http://102.10.10.132/api/Comments/1
    http://102.10.10.132/api/Comments/{commentId}

        @DELETE("Comments/{commentId}")
        Call<ResponseBody> deleteNewsCommentFromAccount(
            @Path("commentId") String commentId);
    

    样式2(需要补全URL,问号后加入access_token)

    http://102.10.10.132/api/Comments/1?access_token=1234123
    http://102.10.10.132/api/Comments/{commentId}?access_token={access_token}

        @DELETE("Comments/{commentId}")
        Call<ResponseBody> deleteNewsCommentFromAccount(
            @Path("commentId") String commentId,
            @Query("access_token") String access_token);
    

    样式3(带有body)

    http://102.10.10.132/api/Comments

    @HTTP(method = "DELETE",path = "Comments",hasBody = true)
    Call<ResponseBody> deleteCommont(
                @Body CommentBody body
        );
    

    CommentBody:需要提交的内容,与Post中的Body相同

    PUT(这个请求很少用到,例子就写一个)

    http://102.10.10.132/api/Accounts/1
    http://102.10.10.132/api/Accounts/{accountId}

        @PUT("Accounts/{accountId}")
        Call<ExtrasBean> updateExtras(
            @Path("accountId") String accountId,
            @Query("access_token") String access_token,
            @Body ExtrasBean bean);
    

    总结

    @Path:所有在网址中的参数(URL的问号前面),如:
    http://102.10.10.132/api/Accounts/{accountId}
    @Query:URL问号后面的参数,如:
    http://102.10.10.132/api/Comments?access_token={access_token}
    @QueryMap:相当于多个@Query
    @Field:用于POST请求,提交单个数据
    @Body:相当于多个@Field,以对象的形式提交
    Tips

    • Tips1
      使用@Field时记得添加@FormUrlEncoded
    • Tips2
      若需要重新定义接口地址,可以使用@Url,将地址以参数的形式传入即可。如
        @GET
        Call<List<Activity>> getActivityList(
                @Url String url,
                @QueryMap Map<String, String> map);
    
        Call<List<Activity>> call = service.getActivityList(
                    "http://115.159.198.162:3001/api/ActivitySubjects", map);
    

    相关文章

      网友评论

      • 262918395d83:为什么又的post带了@FormUrlEncoded,有的又没带,@FormUrlEncoded有什么用呢
        带心情去旅行:@麦冬_e965 @FormUrlEncoded用于修饰Field注解和FieldMap注解,将会自动将请求参数的类型调整为application/x-www-form-urlencoded
      • c3e73e0cbeb9:请问文件上传怎么实现的,谢谢大神
      • dongbingliu:总结很到位「易于理解」
        @Path:所有在网址中的参数(URL的问号前面),如:
        http://102.10.10.132/api/Accounts/{accountId}
        @Query:URL问号后面的参数,如:
        http://102.10.10.132/api/Comments?access_token={access_token}
        @QueryMap:相当于多个@Query
        @Field:用于POST请求,提交单个数据
        @Body:相当于多个@Field,以对象的形式提交
      • 百度不清:POST 样式三会报错,不知道楼主有没有遇到
        java.lang.IllegalArgumentException: URL query string "receiveId={receiveId}" must not have replace block. For dynamic query parameters use @Query.

        写法:
        @post("Samples/BatchSamplesCheckIn?receiveId={receiveId}")
        Observable<JsonResult<String>> doInBound(@Query("receiveId") String receiveId, @body List<String> ids);
        百度不清:找到问题了,是拦截日志输出的时候,进行了一个强制转换引起的错误。
      • 一根愤怒的黄瓜:请问我传json格式的字符串 现在传不上去一直报400 我看了一下 [{}] 括号的问题 请问有啥解决办法
      • 那些年的任何事99:@Query 可以理解为问号后面的键值对吗。而@Path 是问号前面的
        带心情去旅行:@那些年的任何事99 可以这么理解
      • 一只懂音乐的码虫:@get
        Call<List<Activity>> getActivityList(
        @URL String url,
        @QueryMap Map<String, String> map);这样会崩溃,报错:
        java.lang.IllegalArgumentException: @URL cannot be used with @get URL (parameter #1)
        带心情去旅行:@zlice 欠了括号
      • 4cec823f1b8a:非常感谢,帮到我了
      • b89dae9e30b0:你好,我请求的写法是这样,但提交的参数会乱码怎么办?
        @Headers("Content-Type:application/x-www-form-urlencoded")
        @FormUrlEncoded
        @post("rest/2.0/face/v2/faceset/user/add")//人脸注册
        Call<addFace> onLoadNetworkAddFaceData(@Query("access_token") String access_token, @field("uid") String phone, @field("user_info") String name, @field("group_id") String group_id, @field("action_type") String action_type, @field("image") String image);
        b89dae9e30b0:即post的样式2,请求的是百度的人脸注册api
      • GloryObject:Tips 里面可以加一条,使用 @body 时,不要加 @FormUrlEncoded
      • 下位子:真不错
      • fb5fbf432e63:答主我就喜欢你这种简单粗暴的文章 看那些入门的文章一直没搞明白有参数的url怎么封装, 看完我自己就可以写了!
      • 1e4ad5bc6ea5:写的很好,简单清晰。
      • Alex_Code:very good
      • UP7CR:文章转在了公众号AndroidEng,如有打搅,会撤下,多谢多谢~
      • 奔跑的佩恩:大神,能带我飞么
      • aeee4e772699:单独的field 上传 最后和 body 类型应该是不一样的把
        带心情去旅行:@Shoon 有的,不过相比之下麻烦些
        aeee4e772699:@带心情去旅行 除了body以json形式 还有其他方式可以以json形式传吗
        带心情去旅行:是的,field是以表单的形式上传,而body是以json的形式上传的
      • 吧主:这篇文章,我给你在公众号原创发布可以吗?公众号:杨守乐
        吧主: @带心情去旅行 好的,谢谢你😊
        带心情去旅行:@吧主 可以的
      • 12e36795b1ea:@body:相当于多个@Field,以对象的形式提交,那么@FiledMap 与@Body区别呢?
        带心情去旅行:@厉害了我的歌哥 可以用body,不需要传的,使用null就可以了
        12e36795b1ea:@带心情去旅行 那在不同条件下,我需要动态的添加字段,那还是要用@FieldMap,对吧
        带心情去旅行:@厉害了我的歌哥 body可以直接使用一个对象里面的属性,不需要一个个写
      • d4b5c0788e11:非常感谢博主分享,最近正在学习
      • KunMinX:多谢!正好需要例子来理解
        带心情去旅行:@简洁笔记 不谢,不谢
      • 0xCAFEBABE51:@Delete("Comments/{commentId}")
        Call<ResponseBody> deleteNewsCommentFromAccount(
        @path("accountId") String accountId);

        这地方的Path注解是不是应该是commentId呢
        带心情去旅行:@CH_DHY 是的,我疏忽了
        CH_DHY:@带心情去旅行 Delete的样式2应该也有相同的问题
        带心情去旅行:@laizuling 感谢指出,已更新
      • Tang1024:z总结的很好,点个赞 :+1:
      • yangjianan:最近在学Retrofit,看完这篇文章瞬间清晰了。
      • shunxir:太感谢了,正不造什么时候用query 什么时候用path呢😊
        带心情去旅行: @shunxir 不客气哈,我一开始也是被这个搞得一头雾水。后来知道怎么用后就记录下来了,希望能帮到被这些用法困扰的人
      • aa1e65ef05ce:之前还一直疑惑path和query有什么不同
        带心情去旅行:@Tobi1025 所以@query一定在问号后面
        带心情去旅行:@Tobi1025 顺着@Query的解析,找啊找,找啊找。你会在okhttp3.HttpUrl 的1200多行找到这样一段代码:
        if (encodedQueryNamesAndValues != null) {
        result.append('?');
        namesAndValuesToQueryString(result, encodedQueryNamesAndValues);
        }
        ------
        encodedQueryNamesAndValues:将那些@Query中的内容转化后的结果
        ------
        这下你知道为什么是?后面了吧!!!
        Tobi1025:path是对应于url里直接写value的,如:http://www.test/news/1;
        query是对应于url里面有key-value对的,如:http://www.test/news/id=1;

      本文标题:【Android】Retrofit网络请求参数注解,@Path、

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