okhttp3.x+retrofit2.x post请求加密 (单一类型参数 使用@Field)json
public class XApi { private static final int READ_TIME_OUT = 10; private static final int CONNECT_TIME_OUT = 20; private static XApi instance = null; private XApi() { } public static XApi getInstance() { if (instance == null) { synchronized (XApi.class) { if (instance == null) { return new XApi(); } } } return instance; } public Retrofit getRetrofit(String baseUrl) { OkHttpClient okHttpClient = new OkHttpClient.Builder() .readTimeout(READ_TIME_OUT, TimeUnit.SECONDS) .connectTimeout(CONNECT_TIME_OUT, TimeUnit.SECONDS) .addInterceptor(new UrlInterceptor() //这种方式加密是使用loginField的时进行的拦截 .addInterceptor(new LogInterceptor()) .build(); Retrofit retrofit = new Retrofit.Builder() .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) // .addConverterFactory(MyConverterFactory.create()) //loginBody()打开这个 .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .baseUrl(baseUrl) .build(); return retrofit; } }
public class UrlInterceptor implements Interceptor { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); //做用:将post中的请求参数取出加密,而且替换原来的请求参数;ps:从新添加的参数是Query形式,并未添加到encode中 //将加密后的data直接使用addEnable请求不成功,可能和后台的请求类型有关系 HashMap<String, Object> map = new HashMap<>(); //使用@Field添加参数 if ("POST".equals(request.method()) && request.body() instanceof FormBody) {//post请求有参数时 FormBody formBody = (FormBody) request.body(); FormBody.Builder bodyBuilder = new FormBody.Builder();//新建一个请求Body if (formBody.size() > 0) { for (int i = 0; i < formBody.size(); i++) {//将post请求的参数依次取出再加密 map.put(formBody.encodedName(i), formBody.encodedValue(i)); } } request = request.newBuilder() .post(bodyBuilder.build())//请求新的请求参数 .url(request.url() .newBuilder() .addQueryParameter("data", RSAUtils.encrypt(map)) //data是须要的字段 .build()) .build(); } return chain.proceed(request); } }
public class Api { private static ApiService apiService; public static ApiService getApiService() { synchronized (Api.class) { if (apiService == null) { apiService = XApi.getInstance().getRetrofit(BASE_URL).create(ApiService.class); } } return apiService; } } public interface ApiService {//使用loginField()这种方法是为了在请求数据调用的时候代码更简洁,耦合性较低 //登陆 @POST(LOGIN_URL) @FormUrlEncoded Observable<LoginModel> loginField(@Field("phone") String phone, @Field("password") String password); @POST(LOGIN_URL) Observable<LoginModel> loginBody(@Body HashMap<String,String> body); } 如下是使用loginBody()方法请求,因为@Field的字段注解方式不会调用convert方法,因此才会在设置OkHttpClient的时候添加自定义Interceptor, 使用Converter: //请求 public class MyRequestConverter<T> implements Converter<T, RequestBody> { private final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); private Gson gson; private TypeAdapter<T> adapter; public MyRequestConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public RequestBody convert(T value) throws IOException { value类型和传入参数有关系 Log.i("hhhh", "request中传递的json数据:" + value.toString()); //在此处作加密请求 String postBody = gson.toJson(encrypt(value.toString())); Log.i("hhhh", "转化后的数据:" + postBody); return RequestBody.create(MEDIA_TYPE, postBody); } } //响应 public class MyResponseConverter<T> implements Converter<ResponseBody, T> { private final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8"); private Gson gson; private TypeAdapter<T> adapter; public MyResponseConverter(Gson gson, TypeAdapter<T> adapter) { this.gson = gson; this.adapter = adapter; } @Override public T convert(ResponseBody value) throws IOException { //此处为返回数据解密,我这里没作解密 JsonReader jsonReader = gson.newJsonReader(value.charStream()); try { return adapter.read(jsonReader); } finally { value.close(); } } } //ConverterFactory,这个是用GsonConverterFactory修改为本身定义的类 public final class MyConverterFactory<T> extends Converter.Factory { public static MyConverterFactory create() { return create(new Gson()); } @SuppressWarnings("ConstantConditions") // Guarding public API nullability. public static MyConverterFactory create(Gson gson) { if (gson == null) throw new NullPointerException("gson == null"); return new MyConverterFactory(gson); } private final Gson gson; private MyConverterFactory(Gson gson) { this.gson = gson; } @Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return new MyResponseConverter<>(gson, adapter); } @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type)); return new MyRequestConverter<>(gson, adapter); } }`