我用这边需要对上传到服务器的参数做修改。所以给OKHttp家了一个拦截器。但是在判断requestbody类型的时候遇到了问题,判断是否为FormBody的时候一直返回false,求问怎么解决。
请求:
/**
* post请求方式
*/
@FormUrlEncoded //post请求必须要申明该注解
@POST("login") //方法名
Observable<BaseReponse<LoginRequest>> login(@Field("username") String userName, @Field("password") String password);//请求参数
拦截器:
public class RequestInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
if (request.method().equals("POST")) {
RequestBody requestBody = request.body();
Loger.i(getClass().getName(), request.body().getClass().getName());//这里打印出来是ContentTypeOverridingRequestBody
if (requestBody instanceof FormBody) { //这里判断永远是false
FormBody formBody = (FormBody) requestBody;
LinkedHashMap<String, Object> hashMap = new LinkedHashMap<>();
for (int i = 0; i < formBody.size(); i++) {
hashMap.put(formBody.encodedName(i), formBody.encodedValue(i));
}
builder.post(getRequestBody(hashMap));
}
}
Log.v(getClass().getName(), "request:" + request.toString());
Log.v(getClass().getName(), "request headers:" + request.headers().toString());
return chain.proceed(builder.build());
}
public static RequestBody getRequestBody(HashMap<String,Object> hashMap){
Gson gson = new Gson();
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=UTF-8"),gson.toJson(hashMap));
return requestBody;
}
}
拦截器调用:
//初始化Okhttp,绑定拦截器事件
OkHttpClient client = new OkHttpClient.Builder().
connectTimeout(30, TimeUnit.SECONDS). //设置请求超时时间
readTimeout(30, TimeUnit.SECONDS). //设置读取数据超时时间
writeTimeout(30, TimeUnit.SECONDS) //设置写入数据超时时间
.addInterceptor(new RequestInterceptor()) //绑定header拦截器
.addNetworkInterceptor(InterceptorUtil.LogInterceptor() )
.addInterceptor(InterceptorUtil.LogInterceptor()) //绑定日志拦截器
.build();
Retrofit retrofit = new Retrofit.Builder().
addConverterFactory(GsonConverterFactory.create()). //设置gson转换器,将返回的json数据转为实体
addCallAdapterFactory(RxJava2CallAdapterFactory.create()). //设置CallAdapter
baseUrl(ApiHttpClient.getDefaultApiUrl()).
client(client) //设置客户端okhttp相关参数
.build();
debug的截图:
哥们,解决没有,我也遇到这个问题了
val buffer = Buffer()//声明一个buffer
val requestBody = request.body
requestBody?.writeTo(buffer)//使用requestBody的writeTo函数把内容写到buffer中
val contentType = requestBody?.contentType()
val charset: Charset = contentType?.charset(StandardCharsets.UTF_8) ?: StandardCharsets.UTF_8 //这里主要是获取字符串编码
val requestContent = buffer.readString(charset)//从buffer中获取requestBody里面的内容,返回一个String
Timber.d("request.body--->${requestContent}")
究竟想做啥修改?
1. ContentTypeOverridingRequestBody 只是一个代理,尝试用反射获取里面 RequestBody delegate; 的真实类型。
2. 如果你只是想添加header :"application/json; charset=UTF-8", 不用这么麻烦, 下图即可
Request request = chain.request()
.newBuilder()
.addHeader("Content-Type", "application/json")
3.也可以每个请求方法前加注解配置header。
4.也可以直接在普通拦截器里使用方法2.这样默认都是这个header。如果需要别的header,后面会自动覆盖的。