Fast_Responder 快捷響應(yīng)服務(wù)
v1.0.0
簡介
Fast_Responder是一個可以讓你快速創(chuàng)建Http請求應(yīng)答器(responder)的服務(wù)。應(yīng)答器可以接收配置的任意請求路徑的請求,并按照你的配置對請求參數(shù)進行判斷,以返回不同的結(jié)果。除了處理請求外,應(yīng)答器還可以對任意個請求地址按你配置的延遲時間,請求頭和參數(shù)發(fā)起Http請求。本質(zhì)上,fast_responder是一個動態(tài)mock服務(wù)。
你可以在這里獲取該項目的服務(wù)端和客戶端源碼(客戶端不是非必須的,但是建議使用)
- github: https://github.com/Silwings-git
- gitee: https://gitee.com/silwings
如有建議或疑問,歡迎給我發(fā)送郵件說明,感謝您的意見.
郵箱: silwings@163.com

適用場景
寫這個服務(wù)主要是為了應(yīng)對工作中遇到的一些特殊場景,比如:
- 對接第三方接口時,對方提供的接口沒有測試環(huán)境,或有調(diào)用次數(shù)限制。
- 如果三方接口有調(diào)用次數(shù)限制(如某簽約服務(wù)測試環(huán)境發(fā)起合同次數(shù)有限制),可以將需要調(diào)用的接口創(chuàng)建為一個應(yīng)答器,設(shè)置合理的返回值,就可以先調(diào)試流程代碼,確認流程沒問題后切換請求域名,調(diào)用實際接口,減少對三方接口的調(diào)用次數(shù)。
- 團隊合作時,所開發(fā)的功能需要依賴同事的接口,但同事還沒完成接口開發(fā)(前端-后端,后端-后端)。
- 這種情況下通常是自己mock一些數(shù)據(jù)進行調(diào)試,可以將這些mock數(shù)據(jù)創(chuàng)建到應(yīng)答器中,方便重復(fù)利用,同時避免mock代碼忘記刪除等意外情況。
- 要調(diào)用的接口是發(fā)起一個操作流程,操作完成后會對我方進行回調(diào)。但發(fā)起操作流程后,該流程難以完成,或耗時很長。
- 通過使用應(yīng)答器來響應(yīng)發(fā)起操作流程的接口,并主動對預(yù)定接口進行回調(diào),進而跳過該操作流程,使主流程和次流程拆分。
*該服務(wù)不適合數(shù)據(jù)交互需要加解密的場景
使用說明
安裝說明
運行該服務(wù)僅需要一個Mysql服務(wù),要求不低于8.0版本。
- 在數(shù)據(jù)庫執(zhí)行項目下src\sqls\init.sql文件
- 修改配置文件的數(shù)據(jù)庫配置
- 運行FastResponderApplication
配置示例
{
"name":"Demo config",
"httpMethod":"GET",
"keyUrl":"/demo/url",
"categoryName":"示例配置",
"delayTime":0,
"tasks":[
{
"conditions":[
"1 == 1",
"${age} >= 10",
"name =IsNotBlank="
],
"content":{
"body":{
"timestemp":"-TSNow(ms)-",
"name":"${name}",
"id":"-UUID()-"
},
"headers":{
"authToken":"8888888888"
},
"httpMethod":"POST",
"params":{
"keyA":[
"key_Av1",
"keyA_v2"
],
"keyB":[
"keyB_v1"
]
},
"requestUrl":"http://localhost:8088/hello/word"
},
"delayTime":2000,
"name":"My http task"
}
],
"results":[
{
"body":null,
"conditions":[
"${age} == 18"
],
"headers":{
"authToken":"-TSFNow(yyyy-MM-dd HH:mm:ss)-"
},
"msg":"Hello Word !",
"resultName":"My Result A"
},
{
"body":null,
"conditions":[
"${age} == 15"
],
"headers":{
},
"msg":null,
"resultName":"My Result B"
}
]
}
字段信息
| 主體 | 類型 | 描述 | 必填 |
|---|---|---|---|
| name | string | 應(yīng)答器名稱 | true |
| httpMethod | string | 應(yīng)答請求方式(大寫) | true |
| keyUrl | string | 應(yīng)答地址 | true |
| categoryName | string | 應(yīng)答器分類名稱 | false |
| delayTime | long | 應(yīng)答器響應(yīng)延遲時間(ms),默認0 | false |
| tasks | array | 應(yīng)答器的任務(wù)集 | false |
| |--name | string | 任務(wù)名稱 | true |
| |--delayTime | long | 延遲時間(ms),默認0 | false |
| |--conditions | array | 任務(wù)執(zhí)行條件 | false |
| |--content | obj | 任務(wù)內(nèi)容 | true |
| |--|--httpMethod | string | 請求方式(大寫) | true |
| |--|--requestUrl | string | 請求地址 | true |
| |--|--headers | map | 請求頭 | false |
| |--|--params | map | 請求參數(shù)(注意value為字符數(shù)組) | false |
| |--|--body | obj | 請求體 | false |
| results | array | 返回值列表 | false |
| |--resultName | string | 返回值名稱 | true |
| |--body | obj | 響應(yīng)體 | false |
| |--msg | string | 響應(yīng)內(nèi)容(只有body為null才返回msg) | false |
| |--conditions | array | 返回執(zhí)行條件 | false |
| |--headers | map | 響應(yīng)頭 | false |
字段簡述
- 應(yīng)答器配置主要由應(yīng)答器名稱,應(yīng)答地址,應(yīng)答請求方式,任務(wù)集,返回值集五個部分組成。
- 應(yīng)答地址和應(yīng)答請求方式的組合是唯一的。如果出現(xiàn)沖突會在保存時提示。
- 應(yīng)答地址必須以"/"開頭
- 應(yīng)答請求方式的取值范圍: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE(使用客戶端添加應(yīng)答器時可以不區(qū)分大小寫)。
- 應(yīng)答器響應(yīng)延遲時間(delayTime)為接收到請求后,最快應(yīng)該在多少ms外響應(yīng)(注意是外,不是內(nèi))。
- 應(yīng)答器任務(wù)集:可配置http請求任務(wù),task會按順序判斷條件,計算通過后創(chuàng)建task,在指定延遲后發(fā)起http請求。
- 返回值集: 可配置多個返回值,按照順序執(zhí)行,當某一個返回值條件滿足時立即返回。
Task說明
- 當應(yīng)答器中包含task時,在應(yīng)答器對接口進行響應(yīng)之前,會先遍歷task集,依次判斷執(zhí)行條件(conditions,如果conditions 是empty,默認為true 。conditions說明見下文),如果條件判斷為true,會創(chuàng)建task任務(wù),等待執(zhí)行。
- 所有task任務(wù)會被緩存在一個無界延遲隊列(DelayQueue)中,按照delayTime排序。如果配置的延遲時間相同,多個task可能同時執(zhí)行(多線程)。
- task任務(wù)目前提供三個自定義配置
- httptask.scheduler.thread-pool-size:設(shè)置執(zhí)行task任務(wù)的線程池的核心線程數(shù)。默認5
- httptask.resttemplate.connect-timeout:請求連接超時時間。默認20000(ms)
- httptask.resttemplate.read-timeout:請求讀取時間。默認20000(ms)
- task任務(wù)中配置的執(zhí)行條件(conditions),請求地址(requestUrl),請求頭(headers),參數(shù)(params),請求體(body)均適用
替換操作符,替換操作符可以對字符進行一些特定處理(見下文)。
Result說明
- 當應(yīng)答器包含result時,在請求處理的最后階段,會按順序遍歷result集,依次判斷執(zhí)行條件,如果判斷為true,會立即將當前result作為響應(yīng)進行返回。
- 可以配置兩種類型的返回值。一是返回一個簡單的字符串,二是返回一個對象,分別通過msg和body設(shè)置。但如果msg和body同時存在,會優(yōu)先以body返回。例外的是如果運算結(jié)果無法轉(zhuǎn)換為對象,會用無法轉(zhuǎn)換的數(shù)據(jù)替換msg中原本的值。
- result中配置的響應(yīng)條件(conditions),響應(yīng)頭(headers),響應(yīng)內(nèi)容(msg,body)均適用
替換操作符(見下文)。
condition說明
條件(condition)是用來確定task或result是否執(zhí)行的表達式(Expression)集,也就是一個集合為一個condition。配置格式為在集合中添加條件表達式。
- 集合中的每一個元素(表達式)之間的關(guān)系可以理解為Java中的
&&,當前一個表達式結(jié)果為false時,后面的表達式不計算,整個condition直接返回false。 - 如果條件集合為empty,該condition返回true。
- 表達式格式:參數(shù)A+空格+條件符號+空格+參數(shù)B。其中參數(shù)A和參數(shù)B為必填。如果條件符號只需要左條件(參數(shù)A),參數(shù)B可以不寫。條件表達式的三個元素之間的空格不可省略。
- 條件符號
- 等值條件
-
==
- 如果參數(shù)A和參數(shù)B相等返回true。
- 不區(qū)分數(shù)據(jù)類型,均按照字符串equals進行比較
- 全條件符號,可以是任意數(shù)值或字符
-
!=
- ==的取反
- 全條件符號,可以是任意數(shù)值或字符
-
==
- 數(shù)值條件
- >
- >=
- <
-
<=
- 區(qū)分數(shù)據(jù)類型,如果參數(shù)A和參數(shù)B均可以轉(zhuǎn)換為數(shù)值類型,會按照比較符號邏輯進行比較,參數(shù)A或參數(shù)B有不能轉(zhuǎn)換為數(shù)值的,直接返回false
- 全條件符號
- 空判條件
- =IsNull=
- =IsNotNull=
- =IsBlank=
-
=IsNotBlank=
- 這四種表達式運算邏輯參考org.apache.commons.lang3.StringUtils的對應(yīng)方法。
- 左條件符號,只需要參數(shù)A有值即可。
- 等值條件
- 注意事項!
- param參數(shù)比較特殊,因為其值是一個數(shù)組,所有在需要對url參數(shù)進行比對時,只有當param數(shù)組只有一個值時,才能正常生效。否則需要手動配置待比較的值為一個數(shù)組,并區(qū)分數(shù)組中是字符還是數(shù)值。
ReplaceOperator替換操作符
替換操作符可以對字符串進行特殊處理,如生成數(shù)據(jù),引用數(shù)據(jù),通過和condition組合可以進行動態(tài)邏輯判斷。
同一個字符串中可以添加多個替換操作符,但不允許嵌套。
- 操作符介紹
-
${}
查詢替換符,可以從請求信息參數(shù)(param,path param,body)中獲取指定字段的值來對符號所在位置進行替換。通過在{}之間添加文本來指定字段,支持簡單Json Path語法和標準Json Path語法,如果對標準Json Path不熟悉,可以使用簡單Json Path快速上手。
-
簡單Json Path語法(該語法為我自定義的簡單語法)
- 查找最外層key:直接填寫字段名
- 查找內(nèi)層key:填寫多個字段名,之間使用英文字符 . 分隔
- 查找數(shù)組指定角標:填寫字段名+[],[]內(nèi)填寫有效角標值。例:studentList[0],意為獲取studentList的0角標對象
- 查找替換示例1:
- 返回值msg:”你好,我叫
{student.age}歲“。
- 請求應(yīng)答器的請求的請求體:{"code":"200","student":{"name":"小明","age":20}}
- 得到的結(jié)果msg:”你好,我叫小明,今年20歲“
- 返回值msg:”你好,我叫
- 示例2:
- 返回值msg:”你好,我叫
{age}歲“。
- 請求應(yīng)答器的請求:http://localhost:8080/getStudent?name=小明&age=20
- 得到的結(jié)果msg:”你好,我叫小明,今年20歲“
- 如果指定的key對應(yīng)的值是一個對象,將得到一個對象或?qū)ο蟮膉son字符串
- 返回值msg:”你好,我叫
- 示例3:
- 返回值msg:”你好,我叫
{age}歲“。
- 配置的應(yīng)答地址: http://localhost:8080/getStudent/{name}/{age}
- 請求應(yīng)答器的請求:http://localhost:8080/getStudent/小明/20
- 得到的結(jié)果msg:”你好,我叫小明,今年20歲“
- 返回值msg:”你好,我叫
-
標準Json Path
標準Json Path指由Fast Json提供的Json Path語法規(guī)則,該語法可被JSONPath類解析。語法規(guī)則如下(想要了解更多信息請閱讀fast json相關(guān)文檔):
JSONPATH 描述 $ 根對象,例如$.name [num] 數(shù)組訪問,其中num是數(shù)字,可以是負數(shù)。例如$[0].leader.departments[-1].name [num0,num1,num2...] 數(shù)組多個元素訪問,其中num是數(shù)字,可以是負數(shù),返回數(shù)組中的多個元素。例如$[0,3,-2,5] [start:end] 數(shù)組范圍訪問,其中start和end是開始小表和結(jié)束下標,可以是負數(shù),返回數(shù)組中的多個元素。例如$[0:5] [start:end :step] 數(shù)組范圍訪問,其中start和end是開始小表和結(jié)束下標,可以是負數(shù);step是步長,返回數(shù)組中的多個元素。例如$[0:5:2] [?(key)] 對象屬性非空過濾,例如$.departs[?(name)] [key > 123] 數(shù)值類型對象屬性比較過濾,例如$.departs[id >= 123],比較操作符支持=,!=,>,>=,<,<= [key = '123'] 字符串類型對象屬性比較過濾,例如$.departs[name = '123'],比較操作符支持=,!=,>,>=,<,<= [key like 'aa%'] 字符串類型like過濾, 例如$.departs[name like 'sz*'],通配符只支持% 支持not like [key rlike 'regexpr'] 字符串類型正則匹配過濾, 例如departs[name like 'aa(.)*'], 正則語法為jdk的正則語法,支持not rlike [key in ('v0', 'v1')] IN過濾, 支持字符串和數(shù)值類型 例如: .departs[id not in (101,102)]
[key between 234 and 456] BETWEEN過濾, 支持數(shù)值類型,支持not between 例如: .departs[id not between 101 and 201]
length() 或者 size() 數(shù)組長度。例如$.values.size() 支持類型java.util.Map和java.util.Collection和數(shù)組 . 屬性訪問,例如$.name .. deepScan屬性訪問,例如$..name * 對象的所有屬性,例如$.leader.* ['key'] 屬性訪問。例如$['name'] ['key0','key1'] 多個屬性訪問。例如$['id','name'] -
簡單path和標準path在使用上的區(qū)別:
- 簡單版除了body,還支持從param,path param中查找,而標準版僅支持從請求體body中查找。
- 簡單版僅提供簡單的鍵值查詢,標準版提供的查詢更加多樣性。
-
簡單版和標準版共存,是否會導(dǎo)致取值錯誤?
- 設(shè)計上,簡單版和標準版僅有 從集合獲取指定一個角標處的值 的語法相同,所以也只有這里可能會發(fā)生簡單版和標準版沖突的情況。(這段語法設(shè)計為相同是為防止對使用者學(xué)習(xí)標準Json Path造成負面影響而有意為之)
- 如果簡單版和標準版均獲取到了值,將優(yōu)先獲取標準版的結(jié)果
-
-
-RDBoolean()-
- 隨機一個布爾值替換掉操作符
- 示例:
- 字符串: “這是一個隨機布爾值:-RDBoolean()-”
- 結(jié)果: “這是一個隨機布爾值:true”
-
-RDInt()-
- 隨機一個int數(shù)值替換掉操作符
- 可以在()中傳遞參數(shù)(下列10,-5,20均為示例值,可換其他值)。
- -RDInt()-:返回一個偽隨機int值。
- -RDInt(10)-:返回0(包含)到10(不包含)直接的位隨機數(shù)int值。
- -RDInt(-5,20)-:返回-5(包括)和20(不包括)之間的偽隨機int值。
-
-RDLong()-
- 隨機一個long數(shù)值替換掉操作符
- 可以在()中傳遞參數(shù)(下列10,-5,20均為示例值,可換其他值)。
- -RDLong()-:返回一個偽隨機long值。
- -RDLong(10)-:返回0(包括)和10(不包括)之間的偽隨機long值。
- -RDLong(-5,20)-:返回-5(包括)和20(不包括)之間的偽隨機long值。
-
-RDDouble()-
- 隨機一個double數(shù)值替換掉操作符
- 可以在()中傳遞參數(shù)(下列10.0,-5.0,1.0均為示例值,可換其他值)。
- -RDDouble()-:返回0(包括)和1(不包括)之間的偽隨機double值。
- -RDDouble(10.0)-:返回介于 0.0(包括)和10.0(不包括)之間的偽隨機double值。
- -RDDouble(-5.0,1.0)-:返回-5.0(包括)和1.0(不包括)之間的偽隨機double值。
-
-UUID()-
- 隨機一個uuid替換掉操作符
- 可以在()中傳遞限制長度(下列16,64均為示例值,可換其他值)。
- -UUID()-:返回一個uuid字符
- -UUID(16)-:使用substring函數(shù)將uuid裁剪到長度16
- -UUID(64)-:循環(huán)拼接生成的uuid,知道長度到達64
-
-TSNow()-
- 生成當前時間的時間戳替換掉操作符
- 可以在()中傳遞參數(shù),ms和s為固定值,只能二選一
- -TSNow()-:時間戳,單位ms
- -TSNow(ms)-:生成毫秒值時間戳
- -TSNow(s)-:生成秒值時間戳
-
-TSFNow()-
- 根據(jù)指定格式生成時間
- 可以在()中傳遞參數(shù)(下列yyyy-MM-dd HH:mm:ss為示例值,可切換其他正確時間格式)
- -TSFNow()-:同“-TSNow()-”
- -TSFNow(yyyy-MM-dd HH:mm:ss)-:將當前時間轉(zhuǎn)換為“yyyy-MM-dd HH:mm:ss”格式返回
-
客戶端操作與功能演示
強烈推薦使用Web客戶端對應(yīng)答器進行維護。你可以在我的倉庫中找到它。
使用配置示例中的應(yīng)答器進行演示。
-
創(chuàng)建并啟用應(yīng)答器
1642343289387.png





- 啟動用于回調(diào)的測試服務(wù),其中包含如下web接口

-
Postman測試
- 不觸發(fā)任務(wù)和返回值

- 觸發(fā)ResultA


- 觸發(fā)ResultB

- 觸發(fā)Task,ResultB


-
查看日志
實際使用過程中,經(jīng)常會需要確認task或項目執(zhí)行情況,如果只能通過控制臺查看會比較麻煩,F(xiàn)ast Responder客戶端提供了實時日志查看功能。默認日志等級INFO,可通過配置文件(logback.xml)調(diào)整。日志接口默認各接收最多同時10個連接,有新連接進入時,最早連接的連接將被斷開。- task日志,僅打印task執(zhí)行線程的日志


- 項目日志,打印項目的全部日志


tips:
- 進行過編輯后,會自動禁用,需要重新啟用。
- keyUrl和httpMethod的組合應(yīng)該是唯一的,但數(shù)據(jù)庫并沒有做限制,所有如果出現(xiàn)重復(fù)并同時啟用的情況,將按照數(shù)據(jù)庫默認排序獲取第一個結(jié)果。
感謝你的閱讀!
