现在手头的工作流页面端用的是struts2,由于以前没有用过webwork,所以现在用起来基本上是摸着石头过河,感觉蛮辛苦的,不过很有挑战性。
在经过一个早上的努力之后,实现了针对工作流页面的转发action,用于将不同的ProcessDefinition转发到相应的action。这里听取了同事的意见,直接把页面action的名字和流程定义名默认一样,这样就可以少一张table来维护,何乐不为。所以这个DispatchAction最后变成很简单的,就实现了一个可以动态转发action的动作。参考apache上面的文章,很快完成了这一部分的操作。
- <action name="FlowDispatch" class="com.ivo.wfl.action.FlowDispatchAction">
- action>
- <global-results>
- <result name="forwardAction" type="chain">${forwardAction}result>
- global-results>
- import com.ivo.common.BaseAction;
- public class FlowDispatchAction extends BaseAction {
- private String forwardAction;
- public FlowDispatchAction() {
- }
- @Override
- public String execute() {
- String workflow_ID = request.getParameter("Workflow_ID");
- forwardAction = workflow_ID;
- return "forwardAction";
- }
- public String getForwardAction() {
- return forwardAction;
- }
- public void setForwardAction(String forwardAction) {
- this.forwardAction = forwardAction;
- }
- }
以上的实现基本上参考apache上的说明文档,设置一个全局result,type为chain,这样在每一个package中都可以调用,并能保存request范围的数据。在repuest中会把ProcessDefinition带过来,这样通过约定的方式,直接转发到对应的action。
然后就是页面端button的部分,每一个环节都有不同的按钮,所以这里也用约定的方式,transition名字就作为button的名字,然后action里面的方法也要与transition相同,这样,在调用相应的button时,就默认去执行这个transition对应的方法。这样的实现比较简单。
- public class ButtonTag extends TagSupport{
- private String taskName;
- private Long taskId;
- private String workflowId;
- public int doEndTag() throws JspException {
- Request objRequest = new Request();
- Response objResponse = null;
- String acceptButton = "accept";
- String saveButton = "save";
- try{
- String out = "";
- if (taskId == 0) {
- out += "< input type=\"submit\" id=\" " + workflowId + "_0\" " +
- "name=\"action:" + acceptButton + this.workflowId + "\" value=\"" + acceptButton + "\" " +
- "οnclick=\"form.οnsubmit=null\"/>";
- out += "< input type=\"submit\" id=\" " + workflowId + "_0\" " +
- "name=\"action:" + saveButton + this.workflowId + "\" value=\"" + saveButton + "\" " +
- "οnclick=\"form.οnsubmit=null\"/>";
- }else {
- objRequest.setTaskId(this.taskId);
- objResponse = objRequest.call("Transition");
- for( String transition : objResponse.getTransitions()) {
- if (transition.equals("loop")) continue;
- out += "< input type=\"submit\" id=\" " + workflowId + "_0\" " +
- "name=\"action:"+transition + this.workflowId + "\" value=\"" + transition + "\" " +
- "οnclick=\"form.οnsubmit=null\"/>";
- }
- }
- pageContext.getOut().print(out);
- }catch (Exception e) {
- e.printStackTrace();
- }
- return SKIP_BODY;
- }
这种方法跟下面那种其实很类似,只需要把onclick部分的代码替换为自定义的js方法即可objRequest这个对象是用来调用web service。通过web service返回了这个taskInstance的transtion,然后根据这个transition名字来循环创建button。
最后就是button端怎么调用action中的方法,刚开始我用struts2默认的格式,使用string将这一段代码拼出来。后来因为客户端验证的问题,因为页面上有很多必选或者其他非业务数据的验证,所以最好能在页面端就验证,这样能减少server的压力。所以出了几个通用的js方法,来调用相应的action。因为流程中transition的名字也不会很多,就那么几个,所以很少会出现添加js方法的时候,最多就再添加一两个。
到下午,把上面的程序都调通,这样,我的第一个表单到目前为止改善的差不多了。
继续努力。