概述
动作是Rapido当中提供的用于实现将前台数据提交给后台处理或执行一个Ajax调用的功能,从本质上来说,它所完成的就是Dorado7当中的UpdateAction与AjaxAction两种类型Action要做的事情。动作在定义的过程当中,如果选择与某实体关联,那么最终将会生成一个UpdateAction;如果不选择与某实体关联,那么它就是一个AjaxAction。
动作定义中,除了可以选择具体要绑定的实体外,还允许用户编写BeanShell脚本与绑定若干个预先定义好的实现了IAction接口的实现类,这样就尽可能赋予动作最大的灵活性,在不编写Java代码的情况下完成足够多的后台复杂的业务逻辑,以进一步增加Rapido开发复杂业务页面的能力。
操作
切换到Rapido工作区,展开动作节点,在需要维护动作的包下双击,就可以打开动作维护页面,效果如下图所示:
点击添加按钮,在弹出的窗口当中就可以添加一个动作,在动作定义时还可以定义动作使用的参数,这些参数在支持执行期间会从前台页面传输到后台供使用。
扩展
前面提过,动作定义时可以添加若干个预置的“具体动作”,它们是一些实现了IAction接口的配置在Spring当中的Java类,在Rapido当中默认提供了三个IAction接口实现,分别是:
- 根据流程模版的ID,开启一个流程实例。
- 保存流程任务审批过程中的审批意见信息。
- 根据任务ID完成一个具体的流程任务。
可以看到,这三个接口实现都与流程相关,有了这三个实现,就可以将Rapido做的页面与流程关联起来,从而实现与流程相关业务页面开发。IAction接口内容如下:
package com.bstek.bdf2.rapido.action; import java.util.Collection; import java.util.Map; import com.bstek.bdf2.rapido.domain.Parameter; /** * 用于定义前后台交互时要执行的具体动作,<br> * 动作可以累加,也就是说可以一次性执行多个当前接口的实现类,<br> * 用户可以通过实现该接口,在execute方法中添加具体的需要执行的具体逻辑代码,然后将实现类配置到spring当中即可 * @author jacky.gao@bstek.com * @since 2012-7-5 */ public interface IAction { /** * 返回当前动作的名称 * @return 返回动作名称 */ String getName(); /** * 具体要执行的动作代码,这里的参数只有一个Map,<br> * 在这个Map当中包含了当前业务数据的ID(key为businessId)以及所有在动作定义时定义的参数 * @param map 外部传入的参数 */ Map<String,Object> execute(Map<String,Object> map); /** * 执行这个实现时需要哪些参数 * @return 返回一个Parameter对象实例集合 */ Collection<Parameter> requiredParameters(); }
如果您需要编写一个IAction接口实现,那么同样需要将实现类配置到Spring上下文当中。
在编写BeanShell脚本时,除了可以使用Rapido内置的变量外,用户可以通过实现com.bstek.bdf2.bsh.VariableRegister,该接口源码如下:
package com.bstek.bdf.bsh; import java.util.Map; /** * 注册BeanShell脚本中要使用的变量信息,实现类需要配置到Spring环境当中,<br> * 因此在注册时可使用Spring环境中各种类型的Bean对象 * @author jacky.gao@bstek.com * @since 2012-8-28 */ public interface VariableRegister { /** * 返回注册到BeanShell上下文中的变量集合 * @return 返回一个变量集合的Map,Map中key为变量名,Value就是一个VariableInfo对象,用于描述变量信息 */ Map<String,VariableInfo> register(); }
一旦将实现该接口的Bean配置到Spring当中,我们在动作中编写BeanShell脚本时就可以下图所示的可用脚本变量中看到新加的BeanShell变量信息。
扩展示例
自定义执行存储过程的BeanShell变量示例:
1.定义ProcedureTemplate对象
package com.bstek.rapido.demo; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.SQLException; import java.sql.Types; import java.util.HashMap; import java.util.Map; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.CallableStatementCallback; import org.springframework.jdbc.core.CallableStatementCreator; import com.bstek.bdf.rapido.RapidJdbcDaoSupport; /** * 存储过程执行对象 * @author Lucas * */ public class ProcedureTemplate extends RapidJdbcDaoSupport { /** * @param procedureSql * 执行存储过程语句 * @param param * 向存储过程传递的参数 * @return */ @SuppressWarnings({ "unchecked", "rawtypes" }) public Map<String, Object> call(final String procedureSql, final Map<String, Object> param) { final Map<String, Object> outParam = new HashMap<String, Object>(); this.getJdbcTemplate().execute(new CallableStatementCreator() { @Override public CallableStatement createCallableStatement(Connection con) throws SQLException { CallableStatement cs = con.prepareCall(procedureSql); int i = 1; for (String key : param.keySet()) { Object obj = param.get(key); if (obj instanceof String) { int j = i++; cs.setString(j, (String) obj); cs.registerOutParameter(j, Types.VARCHAR); } else if (obj instanceof Integer) { int j = i++; cs.registerOutParameter(j, Types.INTEGER); cs.setInt(j, (Integer) obj); } else if (obj instanceof Long) { int j = i++; cs.registerOutParameter(j, Types.INTEGER); cs.setLong(j, (Long) obj); } } return cs; } }, new CallableStatementCallback() { @Override public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException { cs.execute(); int i = 1; for (String key : param.keySet()) { Object obj = param.get(key); if (obj instanceof String) { outParam.put(key, cs.getString(i++)); } else if (obj instanceof Integer) { outParam.put(key, cs.getInt(i++)); } else if (obj instanceof Long) { outParam.put(key, cs.getLong(i++)); } } return null; } }); return outParam; } /** * 执行无参存储过程 * * @param procedureSql * 执行存储过程语句 */ public void execute(final String procedureSql) { this.getJdbcTemplate().execute(procedureSql); } }
2.将ProcedureTemplate对象注册为BeanShell变量
package com.bstek.rapido.demo; import java.util.HashMap; import java.util.Map; import com.bstek.bdf.d7.bsh.VariableExecutor; import com.bstek.bdf.d7.bsh.VariableInfo; import com.bstek.bdf.d7.bsh.VariableRegister; /** * 注册ProcedureTemplate对象实例 * @author Lucas * */ public class ProcedureTemplateRegister implements VariableRegister { private ProcedureTemplate procedureTemplate; public ProcedureTemplate getProcedureTemplate() { return procedureTemplate; } public void setProcedureTemplate(ProcedureTemplate procedureTemplate) { this.procedureTemplate = procedureTemplate; } @Override public Map<String, VariableInfo> register() { Map<String, VariableInfo> map = new HashMap<String, VariableInfo>(); VariableInfo procedureTemplateInfo = new VariableInfo(); procedureTemplateInfo.setName("procedureTemplate"); procedureTemplateInfo.setDesc("自定义的执行存储过程的ProcedureTemplate对象实例"); procedureTemplateInfo.setVariableExecutor(new VariableExecutor() { public Object execute() { return procedureTemplate; } }); map.put("procedureTemplate", procedureTemplateInfo); return map; } }
3.配置到Spring配置文件中
<bean id="procedureTemplate" class="com.bstek.rapido.demo.ProcedureTemplate" /> <bean class="com.bstek.rapido.demo.ProcedureTemplateRegister"> <property name="procedureTemplate" ref="procedureTemplate" /> </bean>
4.BeanShell脚本中使用procedureTemplate变量
Map resultMap=new HashMap(); Map paramMap=new HashMap(); paramMap.put("id","123"); paramMap.put("name","beanShell"); resultMap = procedureTemplate.call("exec test_insert ?,?",paramMap); resultMap.put("id_test",resultMap.get("id")); return resultMap;