Skip to content

任务 - 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、DELETE
  • params:请求参数
  • body:请求体
  • cookies: 请求体,目前仅支持字符串(不支持文件流)
  • connectTimeout: 连接超时(秒)默认10秒
  • readTimeout 读取超时(秒)默认10秒
  • writeTimeout写入超时(秒)默认10秒

请求参数格式说明

  • paramsbody同时存在时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命令

bash
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/post

HTTP 混合示例

groovy
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 }
  """
}

上例paramsbody同时存在时params将直接拼入url的query部分,上例效果等同如下curl命令

bash
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/post

json 方法注意事项

  1. 当前指的jsonHttpTask中的一个方法只有在HTTP任务块中才能被调用
  2. json 是方法调用,不要写成赋值操作 如:json="{ }"
  3. 如果被双引号包裹的插值还有其它字符将不进行转义如:"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 鉴权

目前支持basicAuthbearerAuth 两种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 中断流程,并设置流程返回指定结果。

勿略错误

groovy
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 后置拦截也可用于结果封装,例如某接口返回数据结构复杂,只需提取其中部分内容

json
{
    "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
  }
}

下一步