关于为Retrofit统一添加post请求的默认参数的方法和retrofitpost请求的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Ajax中Get请求与Post请求的区别、Ajax中
关于为Retrofit统一添加post请求的默认参数的方法和retrofit post请求的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Ajax中Get请求与Post请求的区别、Ajax中Get请求和Post请求的区别、AJAX请求 $.ajaxSetup方法的使用:设置AJAX请求的默认参数选项,当程序中需要发起多个AJAX请求时,则不用再为每一个请求配置请求的参数、Android OkHttp + Retrofit 取消请求的方法等相关知识的信息别忘了在本站进行查找喔。
本文目录一览:- 为Retrofit统一添加post请求的默认参数的方法(retrofit post请求)
- Ajax中Get请求与Post请求的区别
- Ajax中Get请求和Post请求的区别
- AJAX请求 $.ajaxSetup方法的使用:设置AJAX请求的默认参数选项,当程序中需要发起多个AJAX请求时,则不用再为每一个请求配置请求的参数
- Android OkHttp + Retrofit 取消请求的方法
为Retrofit统一添加post请求的默认参数的方法(retrofit post请求)
最近在学习使用Retrofit,并尝试将之引入到现有的项目中来。大家都知道,在Http请求中我们使用 Content-Type 来指定不同格式的请求信息:
APP_FORM_URLENCODED("application/x-www-form-urlencoded"),APP_JSON("application/json"),APP_OCTET_STREAM("application/octet-stream"),MULTIPART_FORM_DATA("multipart/form-data"),TEXT_HTML("text/html"),TEXT_PLAIN("text/plain"),
实际项目中通常最后的请求参数都包含默认的一些参数(Token,Api版本、App版本等)和普通的请求参数。网上有很多关于第一种 Content-Type 添加默认参数的方法。而在我现有项目上,除文件上传外绝大多数请求都走了 post + application/json 的方式。这里暂不讨论两者的优缺点,而是谈下 Content-Type 为 application/json 时,如何添加默认参数。
传统方式:
我们先来回忆下两种方式
public interface Apis { @POST("user/login") Observable<Entity<User>> login(@Body RequestBody body);//构造一个RequestBody对象 @POST("user/login") Observable<Entity<User>> login(@Body LoginInfo loginInfo);//构造一个实体对象 }
第二种方法,你需要为每一个请求的对象创建一个不同的Model,太麻烦了,这里选择第一种直接构造RequestBody对象:
Retrofit mRetrofit = new Retrofit.Builder() .baseUrl(HttpConfig.BASE_URL) .addConverterFactory(GsonConverterFactory.create())//添加gson转换器 .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//添加rxjava转换器 .client(new OkHttpClient.Builder().build()) .build(); Apis mAPIFunction = mRetrofit.create(Apis.class); Map<String,Object> params = new LinkedHashMap<>(); params.put("name","吴彦祖"); params.put("request","123456"); RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),JsonHelper.toJSONString(params)); mAPIFunction.login(RequestBody.create(requestBody))
执行后通过抓包查看,请求体如下:
而我希望的结果是这样的:
当然我们可以每次构造 RequestBody,在传入的参数中加入默认参数:
public static RequestBody getRequestBody(HashMap<String,Object> hashMap) { Map<String,Object> params = new LinkedHashMap<>(); params.put("auth",getBaseParams()); params.put("request",hashMap); return RequestBody.create(MediaType.parse("application/json; charset=utf-8"),JsonHelper.toJSONString(params)); }
这样完全没问题,但不够优雅,所以接下来我们来讨论我所想到的一种方式
拦截器方式:
哈哈,相信熟悉OkHttp的同学已经想到这种方式了,是的很多网上关于第一种 Content-Type 添加默认参数也是这么做的(原文链接):
@Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); if (request.method().equals("POST")) { if (request.body() instanceof FormBody) { FormBody.Builder bodyBuilder = new FormBody.Builder(); FormBody formBody = (FormBody) request.body(); //把原来的参数添加到新的构造器,(因为没找到直接添加,所以就new新的) for (int i = 0; i < formBody.size(); i++) { bodyBuilder.addEncoded(formBody.encodedname(i),formBody.encodedValue(i)); } formBody = bodyBuilder .addEncoded("clienttype","1") .addEncoded("imei","imei") .addEncoded("version","VersionName") .addEncoded("timestamp",String.valueOf(System.currentTimeMillis())) .build(); request = request.newBuilder().post(formBody).build(); } return chain.proceed(request); }
在上面,我们拿到了request对象,然后拿到了requestBody对象,然后 判断是不是FormBody类型,如果是的话,将里面的键值对取出,并添加默认参数的键值对并构造出一个新的formBody对象,最后将原来用request对象构造出新的一个request对象,将新的formBody对象穿进去,拦截器返回。formBody对象是 Content-Type 为 application/x-www-form-urlencoded 时,Retrofit为我们生成的对象,它是RequestBody的子类;而 Content-Type 为 application/json 时,生成的就是 RequestBody (准确的说是匿名子类)。所以我们只要继承重写 RequestBody ,记录请求内容,再将它在拦截器里取出加入并处理就行了。
public class PostJsonBody extends RequestBody { private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); private static final Charset charset = Util.UTF_8; private String content; public PostJsonBody(@NonNull String content) { this.content = content; } public String getContent() { return content; } @Nullable @Override public MediaType contentType() { return JSON; } @Override public void writeto(@NonNull BufferedSink sink) throws IOException { byte[] bytes = content.getBytes(charset); if (bytes == null) throw new NullPointerException("content == null"); Util.checkOffsetAndCount(bytes.length,bytes.length); sink.write(bytes,bytes.length); } public static RequestBody create(@NonNull String content) { return new PostJsonBody(content); } }
拦截器里面取出原始json数据,并添加新的默认参数:
@Override public Response intercept(@NonNull Chain chain) throws IOException { Request originalRequest = chain.request(); Request.Builder builder = originalRequest.newBuilder(); if (originalRequest.method().equals("POST")) { RequestBody requestBody = originalRequest.body(); if (requestBody instanceof PostJsonBody) { String content = ((PostJsonBody) requestBody).getContent(); HashMap<String,Object> hashMap = JsonHelper.fromJson(content,HashMap.class); builder.post(RequestBodyFactory.getRequestBody(hashMap)); } } return chain.proceed(builder.build()); }
这样在外面我们只要改动一行代码就可以实现全局添加默认参数:
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"),JsonHelper.toJSONString(params));
替换为:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
您可能感兴趣的文章:
- 详解Retrofit 动态参数(非固定参数、非必须参数)(Get、Post请求)
- Retrofit2.0 实现图文(参数+图片)上传方法总结
- Retrofit2.0 公共参数(固定参数)
Ajax中Get请求与Post请求的区别
Ajax中Get请求与Post请求的区别
写在前面的话
我们在使用Ajax时,当我们向服务器发送数据时,我们可以采用Get方式请求服务器,也可以使用Post方式请求服务器.那么,我们什么时候该采用Get方式,什么时候该采用Post方式呢?
Get请求和Post请求的区别
1.使用Get请求时,参数在URL中显示,而使用Post方式,则不会显示出来
2.使用Get请求发送数据量小,Post请求发送数据量大
例子
页面的HTML代码:
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <style type="text/css"> * { margin:8px; } </style> </head> <body> <label for="txt_username"> 姓名:</label> <input type="text" id="txt_username" /> <br /> <label for="txt_age"> 年龄:</label> <input type="text" id="txt_age" /> <br /> <input type="button" value="GET" id="btn_get" onclick="btn_get_click();" /> <input type="button" value="POST" id="btn_post" onclick="btn_post_click();" /> <div id="result"> </div> </body> </html>
区别:
Ajax中Get请求和Post请求的区别
1.使用Get请求时,参数在URL中显示,而使用Post方式,则不会显示出来,故post方法更安全(同第四条)。
2、 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。两种方式的参数都可以用Request来获得。
3、get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,因服务器的不同而异.
4、get安全性非常低,post安全性较高。
注:
get方法:URL包含了检索请求信息所需的所有信息,可将其加入书签以便将来重新调用。传送的数据会在地址栏中显示,
是字符流传输,且传送数据量有限制,有中文乱码问题。
post方法:将数据打包发送,可加密数据,安全性高,传输数据量没有限制,不能被加入书签。
AJAX请求 $.ajaxSetup方法的使用:设置AJAX请求的默认参数选项,当程序中需要发起多个AJAX请求时,则不用再为每一个请求配置请求的参数
定义和用法
ajaxSetup() 方法为将来的 AJAX 请求设置默认值。
语法
$.ajaxSetup({name:value,name:value,... })
该参数为带有一个或多个名称/值对的 AJAX 请求规定设置。下面的表格中列出了可能的名称/值:名称 值/描述async 布尔值,表示请求是否异步处理。默认是 true。beforeSend(xhr) 发送请求前运行的函数。cache 布尔值,表示浏览器是否缓存被请求页面。默认是 true。complete(xhr,status) 请求完成时运行的函数(在请求成功或失败之后均调用,即在 success 和 error 函数之后)。contentType 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。context 为所有 AJAX 相关的回调函数规定 "this" 值。data 规定要发送到服务器的数据。dataFilter(data,type) 用于处理 XMLHttpRequest 原始响应数据的函数。dataType 预期的服务器响应的数据类型。error(xhr,status,error) 如果请求失败要运行的函数。global 布尔值,规定是否为请求触发全局 AJAX 事件处理程序。默认是 true。ifModified 布尔值,规定是否仅在最后一次请求以来响应发生改变时才请求成功。默认是 false。jsonp 在一个 jsonp 中重写回调函数的字符串。jsonpCallback 在一个 jsonp 中规定回调函数的名称。password 规定在 HTTP 访问认证请求中使用的密码。processData 布尔值,规定通过请求发送的数据是否转换为查询字符串。默认是 true。scriptCharset 规定请求的字符集。success(result,xhr) 当请求成功时运行的函数。timeout 设置本地的请求超时时间(以毫秒计)。Traditional 布尔值,规定是否使用参数序列化的传统样式。type 规定请求的类型(GET 或 POST)。url 规定发送请求的 URL。默认是当前页面。username 规定在 HTTP 访问认证请求中使用的用户名。xhr 用于创建 XMLHttpRequest 对象的函数。
Android OkHttp + Retrofit 取消请求的方法
Android 2020
本文链接
前言
在某一个界面,用户发起了一个网络请求,因为某种原因用户在网络请求完成前离开了当前界面,比较好的做法是取消这个网络请求。对于OkHttp来说,具体是调用Call
的cancel
方法。
如何找到这一个网络请求并取消掉它呢?
操作大致分为3步。第一步,在建立请求时,给请求(request)添加标记;第二步,根据标记,找到请求;最后,取消这个请求。
OkHttp中的tag
要取消一个请求,OkHttp中可以使用cancel方法,参考。
OkHttp的request对象有tag。可以根据tag来标示请求。参考Stack Overflow。
//Set tags for your requests when you build them:
Request request = new Request.Builder().
url(url).tag("requestKey").build();
//When you want to cancel:
//A) go through the queued calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().queuedCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
//B) go through the running calls and cancel if the tag matches:
for (Call call : mHttpClient.dispatcher().runningCalls()) {
if (call.request().tag().equals("requestKey"))
call.cancel();
}
Retrofit中并没有显示地提供取消请求的接口。2018年时Retrofit仍未提供直接访问call对象的方法
那么如何找到目标网络请求呢?
Retrofit加入自定义header
给每个与页面(Activity,Fragment)相关的request加入自定义header,参考。
给OkHttpClient添加拦截器。标记出页面的生存状态。如果页面销毁了,则取消对应的request。
以GithubOnAndroid项目为例,https://github.com/RustFisher/GithubOnAndroid
添加标记
持有一个ConcurrentHashMap<String,Boolean>来标记页面存活状态。
private static ConcurrentHashMap<String,Boolean> actLiveMap = new ConcurrentHashMap<>(); // 标记Activity是否存活
public static void markPageAlive(String actName) {
actLiveMap.put(actName,true);
}
public static void markPageDestroy(String actName) {
actLiveMap.put(actName,false);
}
Activity中登记界面状态
给当前Activity起名字。每个Activity的标记名必须唯一。
private static final String MY_ACT_NAME = "xxx1Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NetworkCenter.markPageAlive(MY_ACT_NAME);
// ...
}
@Override
protected void onDestroy() {
super.onDestroy();
NetworkCenter.markPageDestroy(MY_ACT_NAME);
// ...
}
OkHttpClient添加拦截器
给OkHttpClient添加拦截器,在拦截器中检查页面的存活情况。
检查后,把这个自定义header移除掉。
public static final String HEADER_ACT_NAME = "Activity-Name"; // 标记Activity界面名字
private Interceptor lifeInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String actName = request.header(HEADER_ACT_NAME);
if (!TextUtils.isEmpty(actName)) {
Log.d(TAG,"lifeInterceptor: actName: " + actName);
Boolean actLive = actLiveMap.get(actName);
if (actLive == null || !actLive) {
chain.call().cancel();
Log.d(TAG,"lifeInterceptor: 取消请求,actName: " + actName);
} else {
Log.d(TAG,"lifeInterceptor: 发起请求,actName: " + actName);
}
}
Request newRequest = request.newBuilder().removeHeader(HEADER_ACT_NAME).build();
return chain.proceed(newRequest);
}
};
OkHttpClient = new OkHttpClient.Builder()
.readTimeout(10,TimeUnit.SECONDS)
.connectTimeout(10,TimeUnit.SECONDS)
.addInterceptor(lifeInterceptor) // 添加拦截器
.build();
call.cancel()后,不会再走Retrofit的subscribe方法。
添加header
@GET("users/{owner}/repos")
Observable<List<UserRepo>> userRepo(
@Header(NetworkCenter.HEADER_ACT_NAME) @Nullable String actName,@Path("owner") String owner,@Query("sort") String sortType);
关于为Retrofit统一添加post请求的默认参数的方法和retrofit post请求的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于Ajax中Get请求与Post请求的区别、Ajax中Get请求和Post请求的区别、AJAX请求 $.ajaxSetup方法的使用:设置AJAX请求的默认参数选项,当程序中需要发起多个AJAX请求时,则不用再为每一个请求配置请求的参数、Android OkHttp + Retrofit 取消请求的方法的相关信息,请在本站寻找。
本文标签: