<?xml version="1.0" encoding="UTF-8"?> <flow xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/webflow" xsi:schemaLocation="http://www.springframework.org/schema/webflow http://www.springframework.org/schema/webflow/spring-webflow.xsd"> <action-state id="initializeLoginForm"> <evaluate expression="initializeLoginAction" /> <transition on="success" to="viewLoginForm"/> </action-state> <view-state id="viewLoginForm" view="casLoginView" model="credential"> <binder> <binding property="username" required="true"/> <binding property="password" required="true"/> </binder> <transition on="submit" bind="true" validate="true" to="realSubmit" history="invalidate"/> </view-state> <action-state id="realSubmit"> <evaluate expression="authenticationViaFormAction"/> <transition on="warn" to="warn"/> <transition on="success" to="createTicketGrantingTicket"/> <transition on="successWithWarnings" to="showAuthenticationWarningMessages"/> <transition on="authenticationFailure" to="handleAuthenticationFailure"/> <transition on="error" to="initializeLoginForm"/> </action-state> <end-state id=""/> </flow>
首先说明一下,expression的值:可以有两种,一种是调用pojo的方法,一种是调用flow的Action,或者是实现multiAction的类 ,在文档中有说明
登录成功后,在调用 authenticationViaFormAction进行一系列的验证后,会有返回值,根据返回值 在transition中配置,然后跳转,to后面跟着的应该是一个state的id,但是却没有找到createTicketGrantingTicket 的state。然后去跟源码,原来这个state是在配置文件中使用程序创建的,并不xml的配置中,源码如下:在DefaultLoginWebflowConfigurer配置文件中可以rh看到,创建了一个action-state,并且设置了两个transition,成功会跳转到sendTicketGrantingTicket
/** * Create create ticket granting ticket action. * * @param flow the flow */ protected void createCreateTicketGrantingTicketAction(final Flow flow) { final ActionState action = createActionState(flow, CasWebflowConstants.STATE_ID_CREATE_TICKET_GRANTING_TICKET, CasWebflowConstants.ACTION_ID_CREATE_TICKET_GRANTING_TICKET); createTransitionForState(action, CasWebflowConstants.TRANSITION_ID_SUCCESS, CasWebflowConstants.STATE_ID_SEND_TICKET_GRANTING_TICKET); createTransitionForState(action, CasWebflowConstants.TRANSITION_ID_SUCCESS_WITH_WARNINGS, CasWebflowConstants.VIEW_ID_SHOW_AUTHN_WARNING_MSGS); }
在创建action-state的方法可以看到
@Override public ActionState createActionState(final Flow flow, final String name, final Action... actions) { if (containsFlowState(flow, name)) { LOGGER.debug("Flow [{}] already contains a definition for state id [{}]", flow.getId(), name); return getTransitionableState(flow, name, ActionState.class); } final ActionState actionState = new ActionState(flow, name); LOGGER.debug("Created action state [{}]", actionState.getId()); actionState.getActionList().addAll(actions); LOGGER.debug("Added action to the action state [{}] list of actions: [{}]", actionState.getId(), actionState.getActionList()); return actionState; }
/** * Create action state action state. * * @param flow the flow * @param name the name * @param action the action * @return the action state */ public ActionState createActionState(final Flow flow, final String name, final String action) { return createActionState(flow, name, createEvaluateAction(action)); }
然后进入,createEvaluateAction可以看到
@Override public EvaluateAction createEvaluateAction(final String expression) { if (this.flowBuilderServices == null) { LOGGER.error("Flow builder services is not configured correctly."); return null; } final ParserContext ctx = new FluentParserContext(); final Expression action = this.flowBuilderServices.getExpressionParser().parseExpression(expression, ctx); final EvaluateAction newAction = new EvaluateAction(action, null); LOGGER.debug("Created evaluate action for expression [{}]", action.getExpressionString()); return newAction; }
这里是为刚才创建的action-state创建了一个evaluate,expression是createTicketGrantingTicketAction,到这为止就可以明白,
<transition on="success" to="createTicketGrantingTicket"/>这句最终其实是去调用了createTicketGrantingTicketAction,在这个类中的doExecute方法有具体的业务逻辑,来生成tgt
/** * Due to a bug in mod-auth-cas and possibly other clients in the way tickets are parsed, * the ticket id body is sanitized to remove the character "_", replacing it with "-" instead. * This might be revisited in the future and removed, once at least mod-auth-cas fixes * the issue. * @param prefix The prefix we want attached to the ticket. * @return the ticket id */ @Override public String getNewTicketId(final String prefix) { final String number = this.numericGenerator.getNextNumberAsString(); final String ticketBody = this.randomStringGenerator.getNewString().replace('_', '-'); return prefix + '-' + number + '-' + ticketBody + StringUtils.defaultString(this.suffix); }
。