Retrofit 如何优雅的请求这样的后台接口?

2018-08-13 19:19:32 +08:00
 maninfog

请求方式:post ;

请求体为至少包含 token 和 uuid 的 json。eg:{token:"",uuid:"",param1:"",param2:""}. 目前方式,采用继承。

// 基类 request
public class BaseRequest {
  String token;
  String uuid;

  public String toJson(){
    return new Gson().toJson(this);
  }
}

// 子类 
public class TestRequest extends BaseRequest {
  String param1;
  String param2;
}

下面是 retrofit 接口。

    @POST
    fun getXX(@Body requestJson: String)
    
    //使用的伪代码
    TestRequest testRequest = new TestRequest();
    testRequest.param1="";
    testRequest.param2="";
    String json = testRequest.tojson();
    // 网络请求
    getXX(json);

这种方式缺点很明显,不同的请求接口需要定义不同的请求类去继承,我想要的效果是这样的。

    @POST
    fun getXX(String param1,String param2)
    
    接口只需要这样写,然后借助一些注解或者 convert 之类的,在真正请求时,会将其转化成上面的格式。

还请大佬解惑!!

9907 次点击
所在节点    Android
30 条回复
maninfog
2018-08-13 21:03:29 +08:00
@pynix 的确 即使行的话 性能上也有所损耗 要去能在某个接口中拿到方法的参数以及注解就好了
xiangyuecn
2018-08-13 21:16:38 +08:00
杠也杠了,擦一下屁股。虽然没用过 Retrofit,但查了一下,他可以 post 字符串出去,看人家写的:


这样的话,现在优雅的层面完全就可以不在 Retrofit 这个层面上了,完全在如何优雅的生成一段 json 数据上。
依我暴力的习惯:

写一个静态类,类里面两个方法:
HashMap BuildPostMap()
String MapToJson(HashMap)

粗暴的使用:
1. BuildPostMap:生成一个 map,map 里面已包含所有必要参数数据
2. ........ 根据不同接口 put 参数到 map,至于参数从哪里来.....(这不重要)
3. MapToJson:map 转成 json,这么通用的功能,估计这个方法都可以省略
719465553
2018-08-13 21:21:54 +08:00
@POST
fun getXX(@Body request: Request)
pynix
2018-08-13 21:24:24 +08:00
@maninfog 如果后端是本公司的,应该可以尝试更正吧,认证信息一般放 header,body 放数据。。。。
maninfog
2018-08-13 21:27:23 +08:00
@xiangyuecn 还是感谢你 提供了这种暴力的思路……缺陷在于参数和接口有点分离 …我将继续探寻是否有更好的做法😄
kassadin
2018-08-14 03:35:52 +08:00
@maninfog #7 这个思路就行,用 @query, 然后参数都在 url 上,post body 为空。

手动在 interceptor 中把参数取出来存 map 转 json 并去掉,map 添加通用参数 token, uid, 然后 map 转 requestBody 就行了

需要注意的就是 query 会有同名 a=1&a=2,尽量规避同名参数就可以了。
maninfog
2018-08-14 08:41:15 +08:00
@kassadin Retrofit 好像 post 方法不支持 @Query,会报错,所以应该只能用到 @Field,用这个的话不知道拦截器中能获取到不,一会儿我去试试吧。
yescpu
2018-08-14 10:02:20 +08:00
Retrofit+OKHttp 可以很优雅的处理这个问题:

class CommonInterceptor implements Interceptor{
Map<String, String> mCommonParams;

public Response intercept(Chain chain) throws IOException {

if(get){
request = addCommonParamsToUrl(request);
}else if(post){
RequestBody requestBody = request.body();
if(formType){
addCommonparamsToForm(requestBody);
}else if(jsonType){
addCommonParamsToJson(requestBody);
}
...
if (requestBody != null) {
Request.Builder requestBuilder = request.newBuilder();
request = requestBuilder
.post(requestBody)
.build();
}
}
reture request;
}
}
kassadin
2018-08-14 14:34:46 +08:00
@maninfog @query 是拼接 url 的,肯定可以。 @Field 用的是 StringConverter,合不出来 json。 @Body 只支持一个参数,只解析一次,自定义 converter 也实现不了多个具名参数拼 json。
snowflake007
2018-08-14 21:25:32 +08:00
没太看懂,token uuid ,不用每个请求接口都定义吧,拦截器插入到 Header 不是很好。
https://www.jianshu.com/p/04ce0c91e3ee

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/479447

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX