<?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); }
。
