Salesforce中Apex InvocableMethod拆分全名返回空值问题排查
问题
我要优化企业内的自动化流程,当Opportunity记录的自定义全名字段首次新增时创建Contact记录。为实现模块化并适配多对象,我尝试在现有Flow中嵌入带InvocableMethod的Apex类,该类接收字符串输入,通过String.split()方法拆分出firstName、lastName和middleNames(规则:首尾分别为名和姓,中间所有内容为中间名,比如"Kiefer William Frederick Dempsey George Rufus Sutherland"拆分后,名是Kiefer,姓是Sutherland,中间名是William Frederick Dempsey George Rufus)。
这是我第一次实现InvocableMethod并在Flow中使用Apex,参考相关模板和Java论坛的拆分逻辑后写了如下代码:
public class getFirstMiddleLastNames { @InvocableMethod public static List<ReturnVariables> getFirstMiddleLastNames(List<InputVariables> inputVariables) { // Get the inputs String name = inputVariables.get(0).name; // Define output variables String newFirstName; String newMiddleNames; String newLastName; // Perform logic List<String> result = name.split(' '); newFirstName = result.get(0); newLastName = result.get(result.size()-1); if (result.size() >= 3){ for (Integer i = 1; i < result.size()-1; i++){ newMiddleNames = newMiddleNames + result.get(i) + ' '; } } // Get the output values List<ReturnVariables> returnVarsList = new List<ReturnVariables>(); ReturnVariables returnVars = new ReturnVariables(); returnVars.firstName = newFirstName; returnVars.middleNames = newMiddleNames; returnVars.lastName = newLastName; return returnVarsList; } public class InputVariables{ // Used a list in case I need to add more inputs down the line @InvocableVariable public String name; } public class ReturnVariables{ @InvocableVariable public String firstName; @InvocableVariable public String middleNames; @InvocableVariable public String lastName; } }
但把它添加到Flow中触发时,出现Contact.LastName为空的错误。Flow调试显示Apex步骤的输出全为null:
Inputs name = {!$Record.primary_contact__c} (Kiefer William Frederick Dempsey George Rufus Sutherland) Outputs {!newPrimaryContactLastName} = lastName (null) {!newPrimaryContactFirstName} = firstName (null) {!newPrimaryContactMiddleNames} = middleNames (null)
我试过把name.split(' ')替换为name.split('\\s'),用result[0]替代result.get(0),甚至直接给newFirstName赋值'Steve',结果还是返回null。请问我忽略了什么问题?
解决方案
你的代码核心问题是创建了ReturnVariables实例,但没有把它添加到返回的列表中,导致Flow接收到空列表,自然所有输出都是null。除此之外还有几个潜在问题需要修复:
1. 核心错误:未将ReturnVariables实例加入返回列表
你创建了returnVars对象,但没有执行returnVarsList.add(returnVars),最终返回的是空列表,Flow无法获取任何输出值。
2. 中间名初始化与拼接问题
newMiddleNames未初始化就直接拼接,会导致开头出现null字符串;同时循环结束后会多一个 trailing 空格,需要处理。
3. 边界情况处理
比如输入只有两个名字(名+姓)时,中间名应该设为空字符串,而不是保持null;还要处理输入为空或只有单个名字的异常场景,避免索引越界。
修复后的完整代码如下:
public class getFirstMiddleLastNames { @InvocableMethod public static List<ReturnVariables> getFirstMiddleLastNames(List<InputVariables> inputVariables) { // 初始化返回列表 List<ReturnVariables> returnVarsList = new List<ReturnVariables>(); ReturnVariables returnVars = new ReturnVariables(); // 处理空输入场景,避免空指针 if (inputVariables == null || inputVariables.isEmpty() || String.isBlank(inputVariables.get(0).name)) { returnVars.firstName = ''; returnVars.middleNames = ''; returnVars.lastName = ''; returnVarsList.add(returnVars); return returnVarsList; } String name = inputVariables.get(0).name.trim(); List<String> nameParts = name.split('\\s+'); // 用\\s+匹配任意空白字符,处理多个空格的情况 // 处理只有单个名字的情况 if (nameParts.size() == 1) { returnVars.firstName = nameParts.get(0); returnVars.middleNames = ''; returnVars.lastName = ''; } else { returnVars.firstName = nameParts.get(0); returnVars.lastName = nameParts.get(nameParts.size() - 1); // 拼接中间名 if (nameParts.size() >= 3) { StringBuilder middleNameBuilder = new StringBuilder(); for (Integer i = 1; i < nameParts.size() - 1; i++) { if (i > 1) { middleNameBuilder.append(' '); } middleNameBuilder.append(nameParts.get(i)); } returnVars.middleNames = middleNameBuilder.toString(); } else { returnVars.middleNames = ''; } } // 关键:将实例加入返回列表 returnVarsList.add(returnVars); return returnVarsList; } public class InputVariables{ @InvocableVariable(required=true) // 标记为必填,Flow中会做校验 public String name; } public class ReturnVariables{ @InvocableVariable public String firstName; @InvocableVariable public String middleNames; @InvocableVariable public String lastName; } }
额外优化点
- 给
InputVariables的name字段加上required=true,Flow配置时会强制输入,避免空值传入 - 使用
StringBuilder拼接中间名,比直接字符串拼接更高效(尤其是长名字场景) - 用
\\s+拆分字符串,处理名字中多个连续空格的情况 - 增加了空输入、单名字的边界场景处理,避免运行时异常
内容的提问来源于stack exchange,提问作者a guy i kno

