1.创建请求基类方便处理返回结果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Retorfit 网络请求基类 public class BaseResponse<T> { public int status; public String msg; public T body; public boolean isSuccess(){ return status == 200; } @Override public String toString() { final StringBuilder sb = new StringBuilder("{"); sb.append("\"body\":") .append(body); sb.append('}'); return sb.toString(); } }
2.请求方法 URL请求
1 2 @GET Observable<WeatherApiBean> sevenDaysWeather(@Url String url);
GET 请求
1 2 3 4 @GET("api/v1.0/version") Observable<BaseResponse<Version>> getTerminalVersion(@Header("token") String token , @Query("type") int type);
POST请求
1 2 3 @FormUrlEncoded @POST("api/v1.0/terminal/login") Observable<BaseResponse<Map<String, Object>>> login(@Field("deviceType") String deviceType);
注意 @FormUrlEncoded不可和@Body连用
DELETE 请求
1 2 3 4 @Headers("Content-Type:application/x-www-form-urlencoded") @HTTP(method = "DELETE", path = "api/v1.0/terminal/bindingAllElder", hasBody = true) Observable<Map<String, Object>> bindingAllElder(@Header("token") String token , @Query("sn") String sn);
3.配置证书及拦截器及证书 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //将证书放到raw目录下 public static int[] certificates = new int[]{R.raw.zhengshu}; OkHttpClient.Builder builder = new OkHttpClient.Builder(); //连接超时时间 builder.connectTimeout(DEFAULT_TIME_OUT, TimeUnit.SECONDS); //写操作 超时时间 builder.writeTimeout(DEFAULT_READ_TIME_OUT, TimeUnit.SECONDS); //读操作超时时间 builder.readTimeout(DEFAULT_READ_TIME_OUT, TimeUnit.SECONDS); //配置https证书 builder.sslSocketFactory(SslSocketFactory.getSSLSocketFactory(certificates)); //配置https证书 builder.hostnameVerifier(SslSocketFactory.getHostnameVerifier()); //自定义公共拦截器 HttpCommonInterceptor commonInterceptor = new HttpCommonInterceptor.Builder() //添加token // .addHeaderParams("token", MyApplication.getInstance().getToken()) .addHeaderParams("Content-Type", "application/json;charset=UTF-8") .build(); builder.addInterceptor(commonInterceptor);
项目域名备案期间,后台使用https+ip方式,并给出https证书.pem文件,要在retorfit框架加入证书。
证书类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 public class SslSocketFactory { private static Context mContext; public static javax.net.ssl.SSLSocketFactory getSSLSocketFactory(int[] certificates) { mContext = MyApplication.getContext(); if (mContext == null) { throw new NullPointerException("context == null"); } CertificateFactory certificateFactory; SSLContext sslContext = null; try { certificateFactory = CertificateFactory.getInstance("X.509"); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); for (int i = 0; i < certificates.length; i++) { InputStream certificate = mContext.getResources() .openRawResource(certificates[i]); keyStore.setCertificateEntry(String.valueOf(i) , certificateFactory.generateCertificate(certificate)); if (certificate != null) { certificate.close(); } } sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(keyStore); sslContext.init(null, trustManagerFactory.getTrustManagers() , new SecureRandom()); } catch (Exception e) { e.printStackTrace(); } return sslContext.getSocketFactory(); } /** * 添加https支持 */ public static HostnameVerifier getHostnameVerifier() { HostnameVerifier hostnameVerifier = new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }; return hostnameVerifier; } }
注意:添加证书后会导致其他服务器的https无法访问,与后台沟通暂无解决方法,幸运的是其他https链接只使用一个,单独对这个链接使用未加证书的okhttp方法。备案成功后,即可去除证书,恢复原有访问方法。
4.请求参数复杂问题 当请求参数为json字符串时 如 ?params = “{“identity”:”123”,”name”:”网二”}”;时出现请求错误,原因”{“,”}”等符号和中文会在请求中被转换格式。 解决方法: (1)GET请求发送json参数包含{}和中文可以使用对参数转码成utf-8,url拼接地址的形式,使用url作为参数:@Url String url
1 2 String params="{"identity":"123","name":"网二"}" url=URL+"?params:"+ URLEncoder.encode(params, "utf-8");//拼接url
(2)POST请求加入下面即可: 1 @Headers("Content-Type:application/x-www-form-urlencoded; charset=utf-8")
5.链式请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 /*链式请求*/ loader.deviceRegister("sn", "username", "password") .map(new Function<Map<String, Object>, Observable<Map<String, Object>>>() { @Override public Observable<Map<String, Object>> apply(@NonNull Map<String, Object> map) throws Exception { JSONObject object = new JSONObject(map); String token = object.getString("token"); return loader.getOrgId(token); } }) .observeOn(Schedulers.newThread()) .subscribe(new Consumer<Observable<Map<String, Object>>>() { @Override public void accept(@NonNull Observable<Map<String, Object>> o) throws Exception { JSONObject object = new JSONObject(o.blockingFirst()); String getOrgId = object.getString("orgId"); } }, new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { Log.e(TAG, "deviceRegister:" + throwable.getMessage()); } });
代码参考Retorfit