策略模式(註解版)實現 retrofit 的get和post請求的公共引數(二)
(想用純策略模式來完全解決 if else if switch case這種需求,是做不到的,或許策略模式根本不能這麼用,最近看到一個開源框架,作者使用策略模式+介面卡模式完美結合,前提是在使用之前要在Application中選擇自己的介面卡,如果兩個介面卡進行選一使用的時候,是不是也要進行if else if switch case的判斷了呢?)
即:
https://github.com/orhanobut/logger ,一個日誌列印框架
廢話不多說,下面升級一下我們的策略模式實現retrofit公共引數:
主要更改的是把ParamsContext類中的Switch case 去掉,換一種方式。
switch (request.method()) {
case GET:
iRequestParam = new GetRequestParams();
break;
case POST:
iRequestParam = new PostRequestParams();
break;
(不然新增一個新的策略,是不是又要加個case?)
為了不加case,我們來試試反射:
1、註解類:
//適用於類上面的註解
@Target(ElementType.TYPE)
//執行時註解
@Retention(RetentionPolicy.RUNTIME)
public @interface Method {
//返回String,預設GET
String value() default "GET";
}
2、具體實現類加上註解
什麼都不改,就類上面加個註解即可:@Method(“GET”)
@Method("GET")
public class GetRequestParams implements IRequestParam {
@Override
public Request getRequest(Request request, Context context) {
//新增公共引數
HttpUrl modifiedUrl = request.url().newBuilder()
.addQueryParameter(CLIENT, AppTools.getClient(context))
.addQueryParameter(VERSION, AppTools.getAppVersion(context))
.addQueryParameter(TOKEN, AppTools.getToken(context))
.build();
return request.newBuilder().url(modifiedUrl).build();
}
}
POST同上
@Method("POST")
public class PostRequestParams implements IRequestParam {
@Override
public Request getRequest(Request request, Context context) {
if (request.body() instanceof FormBody) {
FormBody.Builder bodyBuilder = new FormBody.Builder();
FormBody formBody = (FormBody) request.body();
for (int i = 0; i < formBody.size(); i++) {
bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
}
formBody = bodyBuilder.add(CLIENT, AppTools.getClient(context))
.addEncoded(VERSION, AppTools.getAppVersion(context))
.addEncoded(TOKEN, AppTools.getToken(context))
.build();
request = request.newBuilder().post(formBody).build();
}
return request;
}
}
好了,這些做完之後,就改修改關鍵地方了 ParamsContext,
一句話:拿到IRequestParam的所有實現類 返回即可
具體程式碼如下:
public class ParamsContext {
public static final String GET = "GET";
public static final String POST = "POST";
private Context context;
private Request request;
//--------------------------------註解相關-----------------------------------
private List<Class<? extends IRequestParam>> requestParamList;
public ParamsContext(Request request, Context context) {
this.context = context;
this.request = request;
init();
}
public Request getInRequest() {
//選擇策略進行處理
IRequestParam iRequestParam = chooseRequest(request.method());
return iRequestParam.getRequest(request, context);
}
//------------------------------反射獲取註解-----------------------------------
private void init() {
requestParamList = new ArrayList<>();
try {
String packageName = getClass().getPackage().getName();
Class<?> getRequestParams = Class.forName(packageName + ".GetRequestParams");
Class<?> postRequestParams = Class.forName(packageName + ".PostRequestParams");
List<Class<?>> classList = new ArrayList<>();
classList.add(getRequestParams);
classList.add(postRequestParams);
for (int i = 0; i < classList.size(); i++) {
Class<?> clazz = classList.get(i);
//判斷clazz是否是IRequestParam的實現類
if (IRequestParam.class.isAssignableFrom(clazz)) {
requestParamList.add((Class<? extends IRequestParam>) clazz);
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//根據返回的method產生相應的方法
public IRequestParam chooseRequest(String requestMethod) {
//在策略列表中查詢策略
for (Class<? extends IRequestParam> clazz : requestParamList) {
//獲取該策略的註解
Method method = clazz.getAnnotation(Method.class);
if (requestMethod.equals(method.value())) {
try {
return clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException("策略獲得失敗");
}
}
}
throw new RuntimeException("策略獲得失敗");
}
}
客戶端使用不變:
public Interceptor initQuery(final Context context) {
Interceptor addQueryParameterInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
request = new ParamsContext(request, context).getInRequest();
return chain.proceed(request);
}
};
return addQueryParameterInterceptor;
}
至此,修改就結束了,此時如果我想新增一個新的策略(update、delete等..),只需要加一個帶有註解的策略即可
原始碼:https://github.com/MrXiong/ZxRetrofit2.0
———————————————–分割線—————————————-
這裡有個問題,設計模式學習之策略模式 這篇文章裡面獲取包下面的類是通過getClass().getClassLoader().getResource獲取的,我這裡是通過 Class.forName方法獲取的,就是事先需要知道IRequestParam介面的實現類,那麼如果新增一個新策略,這個勢必也要新增一個。
那篇文章的獲取包下面所有類是這樣寫的:
private File[] getResources() {
try {
File file = new File(classLoader.getResource(CAL_PRICE_PACKAGE.replace(".", "/")).toURI());
return file.listFiles(new FileFilter() {
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".class")) {//我們只掃描class檔案
return true;
}
return false;
}
});
} catch (URISyntaxException e) {
throw new RuntimeException("未找到策略資源");
}
}
可是我在Android Sudio中使用怎麼獲取到的getResource始終是空的,後來我想不就是找.class檔案麼,Android Studio編譯後的.class檔案不就在/app/build/intermediates/classes 這裡麼,我就把路徑換了一下:
private File[] getResources() {
try {
String classPath = "../app/build/intermediates/classes/debug/com/zx/rxjava/policy";
URL resource = getClass().getClassLoader().getResource(classPath);
Logs.d(resource +"");
URI uri = resource.toURI();
File file = new File(classPath);
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
if (pathname.getName().endsWith(".class")) {//我們只掃描class檔案
return true;
}
return false;
}
});
return files;
} catch (Exception e) {
throw new RuntimeException("未找到策略資源");
}
}
可是仍然獲取不到值,各位大佬知道問題的請告知我哦,O(∩_∩)O謝謝
相關推薦
GET和POST請求的區別(面試和原理都得知道)
關於GET和POST是經常用到的兩種請求介面的方式 GET和POST是HTTP請求的兩種基本方法,要說它們的區別,接觸過WEB開發的人都能說出一二。 最直觀的區別就是GET把引數包含在URL中,POST通過request body傳遞引數
PHP中使用CURL實現模擬GET和POST請求,親測完美解決
//初始化 $curl = curl_init(); //設定抓取的url curl_setopt($curl, CURLOPT_URL, 'http://www.baidu.com'); //設定標頭檔案的資訊作為資料流輸出 curl_setopt($cur
Java實現傳送Get和Post請求
前言 已經有幾天沒有寫部落格了 , 原因是最近生活中有大量的事情, 儘管每天都在學習 , 但是卻沒有將知識點記錄在部落格中 , 感覺這樣非常不好 . 以後一定要堅持寫部落格 , 記錄自己
策略模式(註解版)實現 retrofit 的get和post請求的公共引數(二)
(想用純策略模式來完全解決 if else if switch case這種需求,是做不到的,或許策略模式根本不能這麼用,最近看到一個開源框架,作者使用策略模式+介面卡模式完美結合,前提是在使用之前要在Application中選擇自己的介面卡,如果兩個介面卡
策略模式實現 retrofit 的get和post請求的公共引數(一)
策略模式的作用,作用是替換if,elst if ,switch case,可是為什麼我就替換不了呢? 比如: 圖書價格,初級會員9折,高階會員打8折 通常實現: private double getPrice(int grade, doubl
php 實現http get和post(提交json資料)請求
介面,抓取資料經常用到 //$arr為提交的資料為json型別 預設 get function http_curl($url,$type='get',$res='json',$arr=''){ //1.初始化curl $ch = cu
angularJS 條件查詢 品優購條件查詢品牌(條件查詢和列表展示公用方法解決思路 及 post請求混合引數提交方式)
Brand.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"
用python傳送帶傳參的Get和Post請求(二)
上一篇文章使用了python的urllib來進行傳送帶傳參的Get和Post請求 後來請教了下組裡的前輩,發現有稍微更簡潔一點的寫法 是直接使用requests,下面附上程式碼 Get請求 # -*-coding:utf-8 -*- import request
Java使用HttpsURLConnection進行Get和Post請求(繞過證書驗證)
public String gethttpsconnbypost(String url,Map headMap){ StringBuilder result = new StringBuilder(); try { //建立地址物件 URL u=new URL(url); //獲取
nodejs學習筆記(五)——處理get和post請求
上一章介紹瞭如何在nodejs中構造httpserver以及在nodejs中如何構造httpclient來訪問httpserver,接下來說一下nodejs在http互動中是如何處理請求的。首先我們回顧一下上一章最後的例子: server程式碼(server把請求頭資訊處
Java程式碼發起HTTP GET和POST請求(URLConnection)
背景:在使用java語言寫介面自動化用例的時候,經常用到程式碼直接發起HTTP請求,從而得到響應內容,通過斷言響應內容,判斷介面返回是否正確。 方法:java實現HTTP請求主要有兩種方法,一是用JDK自帶類URLConnection、二是用第三方jar包ht
iOS開發網路篇—傳送GET和POST請求(使用NSURLSession)
1)該文主要介紹如何使用NSURLSession來發送GET請求和POST請求 2)本文將不再講解NSURLConnection的使用,如有需要了解NSURLConnection如何傳送請求。 詳細資訊,請參考:http://www.cnblogs.co
java封裝httpClient工具(支援http和https,包含get和post請求)
網上有關方法非常多,但相對較零散,有些只支援http或https中的一種,或者只有get或post中的一種。以下對httpclient工具做了比較全面的封裝,支援http和https,包含get和post請求。 maven匯入的jar包有: <dependency&g
原生Ajax(GET和POST請求)和jQueryAjax(Get和Post請求)詳解
// 原生Ajax Get Post請求 function ajGet(){ // 建立一個 XMLHttpRequest 物件。(這個東西有相容,需要做相容的可以去搜下) var xhr = new XMLHttpRequest(); // 開啟請求,三個引數,
PHP中使用CURL實現GET和POST請求
由於 protocol 對稱加密 即使 匯報 bst 接口 useragent 拷貝 一、什麽是CURL? cURL 是一個利用URL語法規定來傳輸文件和數據的工具,支持很多協議,如HTTP、FTP、TELNET等。最爽的是,PHP也支持 cURL 庫。使用php的cURL
CURL實現發送Get和Post請求(PHP)
結果 基本 釋放 初始 常用 header 理解 介紹 今天 1.cURL介紹 cURL 是一個利用URL語法規定來傳輸文件和數據的工具,支持很多協議,如HTTP、FTP、TELNET等。最爽的是,PHP也支持 cURL 庫。本文將介紹 cURL 的一些高級特性,以及
利用Java實現GET和POST請求
三個類 Java建立代理連線物件 Java傳送Post請求 Java傳送Get請求 程式碼 Java建立代理連線物件 /** * 1.返回代理物件 * @param proxyIp * @param
C++:C語言實現HTTP的GET和POST請求例程參考 C++:C語言實現HTTP的GET和POST請求
C++:C語言實現HTTP的GET和POST請求 閱讀目錄 HTTP請求和IP/TCP 實現GET請求 實現POST請求: 參考: 回到頂部
PHP中使用cURL實現Get和Post請求的方法
data print str close arr 設置 高級特性 post數據 decode cURL 是一個利用URL語法規定來傳輸文件和數據的工具,支持很多協議,如HTTP、FTP、TELNET等。最爽的是,PHP也支持 cURL 庫。本文將介紹 cURL 的一些高級特
用Java實現傳送http的get和post請求
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; imp