Skip to content

工具类API

概述

ApiFlow 在工作流中自动导入了一些常用的工具类,这些工具类提供了静态方法,可以在工作流的任何地方直接调用,无需额外导入。本章节介绍这些工具类的使用方法。

自动导入的工具类

ApiFlow 默认导入以下工具类:

  • JSON - JSON 序列化与反序列化工具
  • Assert - 断言验证工具

这些工具类可以在工作流的任意位置直接使用其静态方法,包括任务定义、编排指令中等。

JSON 工具类

JSON 工具类提供了 JSON 数据的序列化和反序列化功能,基于 Jackson 库实现。

JSON.parse() - 解析JSON

将 JSON 字符串解析为 Java 对象。

JSON.parse(jsonString)

参数:

  • jsonString (String) - JSON 格式的字符串

返回值:

  • Object - 解析后的对象,可能是 Map、List、String、Number、Boolean 等类型

示例:

groovy
// 解析JSON对象
task1 = CODE {
  def jsonStr = '{"name":"张三","age":25,"city":"北京"}'
  def obj = JSON.parse(jsonStr)
  return obj.name  // 返回 "张三"
}

// 解析JSON数组
task2 = CODE {
  def jsonStr = '[{"id":1,"name":"产品A"},{"id":2,"name":"产品B"}]'
  def list = JSON.parse(jsonStr)
  return list[0].name  // 返回 "产品A"
}

// 在HTTP任务中使用
httpTask = HTTP {
  url = "https://api.example.com/data"
  method = "GET"
}

parseTask = CODE {
  // 假设httpTask返回JSON字符串
  def data = JSON.parse(httpTask.result)
  return data.items.size()
}

start {
  run httpTask
  run parseTask
}

JSON.string() - 序列化为JSON

将 Java 对象序列化为 JSON 字符串。

JSON.string(object)

参数:

  • object (Object) - 要序列化的对象(Map、List、POJO等)

返回值:

  • String - JSON 格式的字符串

示例:

groovy
// 将Map转为JSON
task1 = CODE {
  def data = [
    name: "李四",
    age: 30,
    hobbies: ["阅读", "旅游", "编程"]
  ]
  return JSON.string(data)
  // 返回: {"name":"李四","age":30,"hobbies":["阅读","旅游","编程"]}
}

// 在HTTP请求中使用
prepareData = CODE {
  return [
    username: "admin",
    password: "123456",
    remember: true
  ]
}

loginTask = HTTP {
  url = "https://api.example.com/login"
  method = "POST"
  contentType = "application/json"
  body = ${-> JSON.string(prepareData.result)}
}

start {
  run prepareData
  run loginTask
}

// 列表转JSON
task2 = CODE {
  def users = [
    [id: 1, name: "用户A"],
    [id: 2, name: "用户B"],
    [id: 3, name: "用户C"]
  ]
  return JSON.string(users)
}

JSON 使用场景

  1. HTTP 请求/响应处理

    groovy
    // 发送JSON请求
    task1 = HTTP {
      url = "https://api.example.com/create"
      method = "POST"
      contentType = "application/json"
      body = ${-> JSON.string([name: "新项目", status: "active"])}
    }
    
    // 解析JSON响应
    task2 = CODE {
      def response = JSON.parse(task1.result)
      return response.id
    }
  2. 数据转换

    groovy
    // 将数据库查询结果转为JSON
    dbTask = mysql "SELECT * FROM users WHERE status = 'active'"
    
    convertTask = CODE {
      return JSON.string(dbTask.result)
    }
  3. 日志记录

    groovy
    task1 = CODE {
      def logData = [
        timestamp: new Date(),
        action: "user_login",
        userId: input.userId
      ]
      log.info("操作日志: {}", JSON.string(logData))
      return true
    }

JSON 注意事项

  • JSON.parse() 解析失败时会抛出 RuntimeException
  • JSON.string() 序列化时会忽略 null 值的字段
  • 支持 Groovy 的 GString 类型自动转换
  • 不支持循环引用的对象序列化

Assert 工具类

Assert 工具类提供了参数验证和断言功能,用于在工作流执行过程中验证数据的有效性。断言失败时会抛出 IllegalArgumentExceptionIllegalStateException

Assert.notNull() - 非空断言

断言对象不为 null

Assert.notNull(object)
Assert.notNull(object, message)

参数:

  • object (Object) - 待检查的对象
  • message (String, 可选) - 断言失败时的错误消息

示例:

groovy
task1 = CODE {
  def userId = input.userId
  Assert.notNull(userId, "用户ID不能为空")
  return userId
}

// 检查任务结果
task2 = CODE {
  def result = task1.result
  Assert.notNull(result)  // 使用默认错误消息
  return result
}

Assert.isNull() - 空值断言

断言对象为 null

Assert.isNull(object)
Assert.isNull(object, message)

示例:

groovy
task1 = CODE {
  def cache = input.cache
  Assert.isNull(cache, "缓存应该为空")
  // 初始化逻辑...
}

Assert.isTrue() - 布尔真值断言

断言表达式为 true

Assert.isTrue(expression)
Assert.isTrue(expression, message)

示例:

groovy
task1 = CODE {
  def age = input.age
  Assert.isTrue(age >= 18, "年龄必须大于等于18岁")
  return age
}

// 验证业务规则
checkTask = CODE {
  def amount = input.amount
  def balance = input.balance
  Assert.isTrue(amount <= balance, "余额不足")
  return true
}

Assert.isFalse() - 布尔假值断言

断言表达式为 false

Assert.isFalse(expression)
Assert.isFalse(expression, message)

示例:

groovy
task1 = CODE {
  def isLocked = input.accountLocked
  Assert.isFalse(isLocked, "账户已锁定,无法操作")
  return true
}

Assert.hasText() - 文本非空断言

断言字符串不为 null、不为空字符串、且包含至少一个非空白字符。

Assert.hasText(text)
Assert.hasText(text, message)

示例:

groovy
task1 = CODE {
  def username = input.username
  Assert.hasText(username, "用户名不能为空")

  def password = input.password
  Assert.hasText(password, "密码不能为空")

  return [username: username, password: password]
}

Assert.hasLength() - 字符串长度断言

断言字符串不为 null 且长度大于 0。

Assert.hasLength(text)
Assert.hasLength(text, message)

示例:

groovy
task1 = CODE {
  def code = input.verifyCode
  Assert.hasLength(code, "验证码不能为空")
  return code
}

Assert.state() - 状态断言

断言状态表达式为 true,失败时抛出 IllegalStateException(而非 IllegalArgumentException)。

Assert.state(expression)
Assert.state(expression, message)

示例:

groovy
task1 = CODE {
  def status = input.orderStatus
  Assert.state(status == "pending", "订单状态必须为pending才能修改")
  // 执行修改逻辑...
}

Assert.isInstanceOf() - 类型断言

断言对象是指定类的实例。

Assert.isInstanceOf(clazz, object)
Assert.isInstanceOf(clazz, object, message)

示例:

groovy
task1 = CODE {
  def data = input.data
  Assert.isInstanceOf(Map.class, data, "数据必须是Map类型")
  return data.name
}

Assert.noNullElements() - 数组无空元素断言

断言数组中没有 null 元素。

Assert.noNullElements(array)
Assert.noNullElements(array, message)

示例:

groovy
task1 = CODE {
  def items = input.items as Object[]
  Assert.noNullElements(items, "列表中不能包含空元素")
  return items.length
}

Assert.notEmpty() - 集合非空断言

断言集合不为空。

Assert.notEmpty(collection, message)

示例:

groovy
task1 = CODE {
  def userList = input.users
  Assert.notEmpty(userList, "用户列表不能为空")
  return userList.size()
}

Assert 使用场景

  1. 输入参数验证

    groovy
    validateInput = CODE {
      Assert.notNull(input.orderId, "订单ID不能为空")
      Assert.hasText(input.productName, "产品名称不能为空")
      Assert.isTrue(input.quantity > 0, "数量必须大于0")
      Assert.isTrue(input.price >= 0, "价格不能为负数")
      return true
    }
    
    start {
      run validateInput
      // 后续处理...
    }
  2. 业务规则校验

    groovy
    checkOrder = CODE {
      def stock = input.stock
      def quantity = input.quantity
      Assert.isTrue(quantity <= stock, "库存不足,当前库存:${stock}")
      return true
    }
  3. 前置条件检查

    groovy
    checkPermission = CODE {
      def role = input.userRole
      Assert.isTrue(role in ["admin", "manager"], "权限不足,需要管理员权限")
      return true
    }
    
    start {
      run checkPermission
      // 执行需要权限的操作...
    }
  4. 任务结果验证

    groovy
    httpTask = HTTP {
      url = "https://api.example.com/data"
    }
    
    validateResult = CODE {
      def result = httpTask.result
      Assert.notNull(result, "API返回结果为空")
    
      def data = JSON.parse(result)
      Assert.isTrue(data.code == 200, "API返回错误: ${data.message}")
    
      return data.data
    }
    
    start {
      run httpTask
      run validateResult
    }

Assert 注意事项

  • 断言失败会立即中断流程并抛出异常
  • 大部分方法抛出 IllegalArgumentExceptionAssert.state() 抛出 IllegalStateException
  • 建议在工作流开始时进行输入验证,避免执行到一半才发现参数错误
  • 合理使用断言可以提高代码的健壮性和可维护性

Groovy 默认导入

除了 ApiFlow 提供的工具类外,Groovy 还默认导入了以下包和类,可以在工作流中直接使用:

默认导入的包

groovy
import java.lang.*
import java.util.*
import java.io.*
import java.net.*
import groovy.lang.*
import groovy.util.*
import java.math.BigInteger
import java.math.BigDecimal

常用类示例

groovy
// 日期类(java.util.Date)
task1 = CODE {
  def now = new Date()
  log.info("当前时间: {}", now)
  return now
}

// 集合类(java.util.List, Map, Set)
task2 = CODE {
  def list = new ArrayList()
  list.add("item1")
  list.add("item2")

  def map = new HashMap()
  map.put("key1", "value1")

  return [list: list, map: map]
}

// 文件操作(java.io.File)
task3 = CODE {
  def file = new File("/tmp/test.txt")
  return file.exists()
}

// URL操作(java.net.URL)
task4 = CODE {
  def url = new URL("https://example.com")
  return url.protocol  // 返回 "https"
}

// 大数运算(java.math.BigDecimal)
task5 = CODE {
  def price = new BigDecimal("99.99")
  def quantity = new BigDecimal("3")
  return price.multiply(quantity)  // 精确计算 299.97
}

Groovy 特有功能

Groovy 提供了许多语法糖和增强功能:

groovy
// 字符串增强
task1 = CODE {
  def str = "hello"
  return str.capitalize()  // "Hello"
}

// 集合操作
task2 = CODE {
  def list = [1, 2, 3, 4, 5]
  def result = list.findAll { it > 2 }  // [3, 4, 5]
  return result
}

// 范围(Range)
task3 = CODE {
  def range = 1..10
  return range.collect { it * 2 }  // [2, 4, 6, ..., 20]
}

// Elvis 操作符
task4 = CODE {
  def value = input.name ?: "默认名称"
  return value
}

// 安全导航操作符
task5 = CODE {
  def name = input?.user?.name  // 自动处理null
  return name
}

综合示例

以下是一个综合使用 JSON 和 Assert 工具类的完整示例:

groovy
// 验证输入参数
validateInput = CODE {
  Assert.notNull(input.userId, "用户ID不能为空")
  Assert.hasText(input.action, "操作类型不能为空")
  return true
}

// 查询用户信息
getUserInfo = HTTP {
  url = "https://api.example.com/users/${-> input.userId}"
  method = "GET"
}

// 解析并验证用户信息
parseUserInfo = CODE {
  def userJson = getUserInfo.result
  def user = JSON.parse(userJson)

  Assert.notNull(user, "用户信息获取失败")
  Assert.hasText(user.name, "用户名称为空")
  Assert.isFalse(user.locked, "用户已被锁定")

  return user
}

// 构建操作日志
buildLog = CODE {
  def logData = [
    userId: input.userId,
    userName: parseUserInfo.result.name,
    action: input.action,
    timestamp: new Date().time,
    ip: input.clientIp
  ]
  return JSON.string(logData)
}

// 保存日志
saveLog = HTTP {
  url = "https://api.example.com/logs"
  method = "POST"
  contentType = "application/json"
  body = ${-> buildLog.result}
}

start {
  run validateInput
  run getUserInfo
  run parseUserInfo
  run buildLog
  run saveLog
}

最佳实践

  1. 输入验证优先

    • 在工作流开始时立即验证所有输入参数
    • 使用 Assert 进行参数校验,快速失败
  2. JSON处理规范

    • 使用 JSON.parse() 解析外部API返回的JSON字符串
    • 使用 JSON.string() 序列化要发送的请求体
    • 捕获并处理可能的解析异常
  3. 错误消息清晰

    • Assert 断言时提供清晰的错误消息
    • 包含必要的上下文信息,便于问题排查
  4. 合理使用Groovy特性

    • 利用Groovy的语法糖简化代码
    • 使用安全导航操作符避免空指针异常
    • 使用集合操作方法提高代码可读性

下一步