任务 - HTTP 任务
HTTP 任务概述
HTTP任务属于Invoke调用型任务,所以支持重试、异常策略、前后置处理配置。HTTP任务实现类是HttpTask。
HttpTask 结构
@Getter
@Setter
public class HttpTask extends InvokeTask implements IRepeat {
String url; // 请求路径
String method = "GET"; // 请求方法
final Map<String, String> params = new LinkedHashMap<>(); // 请求参数
final Map<String, String> cookies = new LinkedHashMap<>(); // cookies
final Map<String, String> heads = new LinkedHashMap<>(); // 请求头
String body;// 请求体,目前仅支持字符串(不支持文件流)
int connectTimeout = 10; //连接超时(秒)默认10秒
int readTimeout = 10; //读取超时(秒)默认10秒
int writeTimeout = 10; //写入超时(秒)默认10秒
}属性说明
url:http完整路径可包含查询参数。method: 请求方法支持GET、POST、PUT、DELETEparams:请求参数body:请求体cookies: 请求体,目前仅支持字符串(不支持文件流)connectTimeout: 连接超时(秒)默认10秒readTimeout读取超时(秒)默认10秒writeTimeout写入超时(秒)默认10秒
请求参数格式说明
- 当
params与body同时存在时params直接拼入url的query部分,拼入前会进行urlencode转码。 - 如果
method为POST、PUT、PATCH支持请求体的方法并且Content-Type为空 ,params将按application/x-www-form-urlencoded格式进行传输 - 如果指定了 Content-Type为x-www-form-urlencoded或form-data则
params按对应格式进行传输 - 其它情况
params直接拼入url的query部分,拼入前会进行urlencode转码。
基本 HTTP GET 示例
t1 = HTTP {
method="get"
url="https://qqlykm.cn/api/plateNumber/index"
params["word"] = "湘A" // 参数
cookies["jwt_token"]="xxxxxx" // 添加cookie
connectTimeout=5 // 连接超时5秒
readTimeout=5 // 写入超时5秒
}在GET方法下 params中的参数 将在编码转义后追加到url中作为query参数处理,上例等同如下curl命令
curl -X GET \
-H "Cookie: jwt_token=xxxxxx" \
--connect-timeout 5 \
-m 5 \
"https://qqlykm.cn/api/plateNumber/index?word=湘A"HTTP POST 基础示例
t1 = HTTP {
method="POST"
url="https://httpbin.org/post"
heads["Content-Type"]="application/x-www-form-urlencoded" // 请求头
params["id"]= "999"
params["content"]= "content"
}如果是POST方法params会根据指定Content-Type 的类型进行封装处理,如果没有指定则按x-www-form-urlencoded格式处理。
上面http任务等同于以下curl命令
curl -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "name=luban&age=18" \
https://httpbin.org/postHTTP 混合示例
t1 = HTTP {
method="POST"
url="https://httpbin.org/post"
heads["Content-Type"]="application/json" // 请求头
params["id"]= "999"
params["content"]= "content"
body ="""
{"name":"xiaomi","age":19 }
"""
}上例params与body同时存在时params将直接拼入url的query部分,上例效果等同如下curl命令
curl -X POST \
-H "Content-Type: application/json" \
-d '{"name":"xiaomi","age":19}' \
"https://httpbin.org/post?id=999&content=content"JSON 参数传递
json是http请求中最为常用的格式,为简化json请求http任务中提供了一个快捷json 方法,其待征如下:
- 该方法接收一个Object型参数,该对象转成json字符串后保存到body属性中
- 如果参数为
String字符串,将对字符串json格式进行验证 - 如果参数为
GString拼接字符串,先转成字符串,同时对于被双引号包裹的插值会进行转义以处理,防止换行等特殊符号的格式错误。如果被双引号包裹的插值还有其它字符将不进行转义如:"hello ${name}"中的name不会进行json转义 - 如果参数为其它类型,将该对象直接转为字符串
- 如果参数为
- 如果未设置Content-Type,将设置其为 application/json; charset=utf-8
- 如果设置了Content-Type将验证其是不是json格式
json 方法使用示例
t1 = HTTP {
method="POST"
url="https://httpbin.org/post"
vars.describe="""hello
li"""
json """
{
"id": 999,
"value": "${vars.describe}"
}
"""
}- 自动添加Content-Type为 application/json; charset=utf-8
${vars.describe}插值部分将进行json转义
上例最终效果等同于如下curl命令:
curl -X POST https://httpbin.org/post \
-H 'Content-Type: application/json; charset=utf-8' \
-d '{"id":999,"value":"hello \\n li"}'json 转换对象
此外json 会自动将普通对象转成json 字符串
t1 = HTTP {
method="POST"
url="https://httpbin.org/post"
json( [id:999,value:input.value] )
}其效果等同于如下:
curl -X POST \
-H "Content-Type: application/json" \
-d '{ "id": 999, "value": "xxxx" }' \
https://httpbin.org/postjson 方法注意事项
- 当前指的
json是HttpTask中的一个方法只有在HTTP任务块中才能被调用 json是方法调用,不要写成赋值操作 如:json="{ }"- 如果被双引号包裹的插值还有其它字符将不进行转义如:
"hello ${name}"中的name不会进行json转义
XML 参数传递
在body 中指定xml 文本,注意在xml文本中插值时注意特殊字符问题,目前http任务未提供类似json方法的快捷操作。示例如下:
t1 = HTTP {
method="POST"
url="https://httpbin.org/post"
heads["Content-Type"]="application/xml" // 请求头
body= """
<root>
<id>999</id>
<value>${input.value}</value>
</root>
"""
}以此类推采用这种方式可传递任意类型文本,当前不支持基于字节数组的方式进行文件上传。
HTTP Auth 鉴权
目前支持basicAuth与bearerAuth 两种http 鉴权方法,示例如下:
//basicAuth 鉴权
t1 = HTTP {
url="https://httpbin.org/basic-auth/user/passwd"
basicAuth "user","passwd" // 基于用户密码的基础鉴权
}
//bearerAuth 鉴权
t2 = HTTP {
url="https://httpbin.org/headers"
bearerAuth "my-secret-token" // 基于bearer鉴权操作
}basicAuth 与bearerAuth 其本质是对 Authorization的请求头的处理,也可以直接添加请求头效果一样:
t2 = HTTP {
url="https://httpbin.org/headers"
heads["Authorization"]="Bearer my-secret-token" //Bearer Author请求头
}HTTP 失败判断
失败包括连接超时、状态码大于等于400引擎均会判定为失败。有些业务异常错误码体现在结果中,这种情况可以通过后置拦截器进一步判断,比如调用微信接口返回状态码是200,但返回内容如下:
{
"errcode":65320,
"errmsg":"match rule violates privacy"
}这时可通过添加后置拦截器doLast进一步判断结果中是否存在errcode字段,如果存在就抛出异常,示例如下:
t2 = HTTP {
url="https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=xxxx"
doLast {
if(!result.errcode){ // 如果存在errcode字段表示出错了。
throws new RuntimeException("微信调用出错:${result.errcode} ${result.errmsg}")
}
}
}HTTP 异常处理策略
当任务执行失败,且重试(如果有设置)之后依然失败 ,将执行异常处理策略,目前支持两种useIgnore 勿略、useAbort中断。
- 勿略:
useIgnore勿略错误流程继续,可为任务指定结果。 - 中断:
useAbort中断流程,并设置流程返回指定结果。
勿略错误
t2 = HTTP {
url="https://xxxx"
// 勿略错误,并为任务指定了一个默认结果
useIgnore {
[name:"luban"]
}
}中断错误
t2 = HTTP {
url="https://xxxx"
// 发生错误时,中断流程,并为整个流程指定结果
useAbort [errorMsg:"发生了错误"]
}HTTP 失败重试
指调用失败后重新发起调用,失败包括连接超时、状态码大于等于400、业务异常等任何错误均会触发重试。
t2 = HTTP {
url="https://xxxx"
// 失败重试3次,每次间隔3秒
retry 3,2000
}HTTP 结果封装
doLast 后置拦截也可用于结果封装,例如某接口返回数据结构复杂,只需提取其中部分内容
{
"success": true,
"city": "济南",
"data": {
"current_weather": "晴",
"current_temperature": 22,
"today_weather": "小雨",
"today_high_temperature": 26,
"today_low_temperature": 17,
"aqi": 64,
"quality_level": "良",
"wind_direction": "北风",
"wind_level": 3,
"forecast_list": [
{
"weather": "阴",
"date": "20230529",
"high_temperature": "26",
"low_temperature": "17",
"wind_direction": "东北风",
"wind_level": "34"
},
{
"weather": "小雨转阴",
"date": "20230530",
"high_temperature": "26",
"low_temperature": "17",
"wind_direction": "北风",
"wind_level": "2"
}
]
},
"update_time": "20230530 19:45:08",
"msg": "查询成功"
}就可以在doLast中重新封装:
t2 = HTTP {
url="https://xxxx"
doLast {
// 重新设置结果 ,只取天气列表字段
result = result.data.forecast_list
}
}