Spring Web Flow. Тесты. Часть 3. Обзор flow

января
17
2012
Метки: spring spring web flow

Содержание

Как и в предыдущей статье о Spring Web Flow, в данном примере используются вложенные flow. На этот раз их будет два: один отвечает за авторизацию пользователя, второй - за прохождение тестирования пользователем. Родительский flow управляет взаимодействием между вышеупомянутыми списками действий.

Листинг родительского tests-flow представлен ниже:

tests-flow.xml

<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/webflow 
  http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
      
    <on-start>
        <evaluate expression="new com.seostella.swftests.domain.TestChecker()" 
                  result="flowScope.testChecker" />
    </on-start>
    
    <subflow-state id="identifyUser" subflow="tests/user">
        <output name="user" value="flowScope.testChecker.user"/>
        <transition on="userReady" to="startTest" />
    </subflow-state>
  
    <subflow-state id="startTest" subflow="tests/test">
        <output name="testList" value="flowScope.testChecker.testList"/>
        <transition on="testsFinished" to="successResult" />
        <transition on="testsFail" to="failResult" />
    </subflow-state>
  
    <view-state id="successResult">
        <transition to="endState" />
    </view-state>
    
    <view-state id="failResult">
        <transition to="endState" />
    </view-state>    
  
    <end-state id="endState" />
</flow>

В предыдущих двух статьях о Spring Web Flow были рассмотренны все описанные в tests-flow.xml состояния, кроме одного - on-start. Как следует из названия, это состояние вызывается во время запуста test-flow.

Действие evaluate. Вы будете использовать его достаточно часто. Оно предназначено для выполнения выражения, указанного в атрибуте expression. Если Вас также интересует результат выполнения выражения, то необходимо указать атрибут result с названием переменной, в которую запишется результат. В нашем случае это flowScope.testChecker.

В вышеприведенном коде появилась "магическая" переменная flowScope. flowScope - это область видимости flow, в которую можно добавлять/изменять переменные. В Spring Web Flow есть еще несколько подобных сущностей: viewScope, requestScope, flashScope и др. Подробнее о них можно почитать на странице Spring Web Flow Reference Guide.

То есть, в flowScope будет записана вновь созданная переменная testChecker. Это мы делаем для того, чтобы у каждого нового пользователя при старте flow создавалось отдельное хранилище, отвечающее за информацию о пользователе и о проходимых им тестах.

Разберемся с первым subflow identifyUser:


    <subflow-state id="identifyUser" subflow="tests/user">
        <output name="user" value="flowScope.testChecker.user"/>
        <transition on="userReady" to="startTest" />
    </subflow-state>

Этот subflow предназначен для идентификации пользователя.


<output name="user" value="flowScope.testChecker.user"/>

- означает, что после того как пользователь будет идентифицирован (т.е., выполнение дочернего flow будет окончено), информация о нем запишется в переменную flowScope.testChecker.user.


<transition on="userReady" to="startTest" />

- по завершении выполнения identifyUser (достигнуто состояние userReady) управление передается состоянию startTest, которое отвечает за прохождение тестов пользователем.


    <subflow-state id="startTest" subflow="tests/test">
        <output name="testList" value="flowScope.testChecker.testList"/>
        <transition on="testsFinished" to="successResult" />
        <transition on="testsFail" to="failResult" />
    </subflow-state>

Переходим к subflow под названием startTest. Его описание очень напоминает предыдущий identifyUser flow.


<output name="testList" value="flowScope.testChecker.testList"/>

- по окончании выполнения результат (а точнее, значение свойства testList) записывается в переменную flowScope.testChecker.testList.


<transition on="testsFinished" to="successResult" />

- по достижению конечного состояния testsFinished, управление передается состоянию successResult. Это успешное завершение тестирования, что означает, что было допущено меньше 3-х ошибок или ни одной ошибки.


<transition on="testsFail" to="failResult" />

- по достижению конечного состояния testsFail, управление передается состоянию failResult. В это состояние приложение переходит сразу же после третьего неправильного ответа.

В tests-flow осталось еще три состояния: два состояния-представления (successResult и failResult) и конечное состояние endState. Как стало известно из предыдущих статей о Spring Web Flow, для состояний-представлений должны быть одноименные jspx-файлы. Приведем исходники стриниц successResult.jspx и failResult.jspx:

successResult.jspx

<html xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions"
      xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:form="http://www.springframework.org/tags/form">
    <jsp:output omit-xml-declaration="yes"/>  
    <jsp:directive.page contentType="text/html;charset=UTF-8" />  

    <head><title>Tests - Spring Web Flow 2.x Tutorial | seostella.com</title></head>

    <body>
        <h1>Результыты тестов пользователя ${testChecker.user.name}</h1>
        <p>Допущено ошибок: ${testChecker.testList.wrongAnswerCount}</p>
    <c:forEach items="${testChecker.testList.tests}" var="test">
    <li>${test.question} - ${test.userAnswerAsText} 
        <c:if test="${test.correctAnswer}">
            (<font style="color: green">правильно</font>)
        </c:if>
        <c:if test="${!test.correctAnswer}">
            (<font style="color: red">неправильно</font>)
        </c:if>
    </li>
    </c:forEach>
</body>
</html>

failResult.jspx

<html xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fn="http://java.sun.com/jsp/jstl/functions"
      xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:form="http://www.springframework.org/tags/form">
    <jsp:output omit-xml-declaration="yes"/>  
    <jsp:directive.page contentType="text/html;charset=UTF-8" />  

    <head><title>Tests - Spring Web Flow 2.x Tutorial | seostella.com</title></head>

    <body>
        <h1>Результыты тестов пользователя ${testChecker.user.name}</h1>
        <p>Допущено ошибок: ${testChecker.testList.wrongAnswerCount}. Вы провалили тест.</p>
    </body>
</html>

После успешного прохождения тестов пользователю отобразится страница successResult.jspx:

Рис 2. Успешное завершение тестирования
Рис 2. Успешное завершение тестирования

Если тесты будут провалены, то пользователь увидит страницу failResult.jspx:

Рис 3. Неуспешное завершение тестирования
Рис 3. Неуспешное завершение тестирования

< Spring Web Flow. Тесты. Часть 2. Модель и Контроллер Spring Web Flow. Тесты. Часть 4. Flow Авторизации >

Напишите первое сообщение!

Вы должны войти под своим аккаунтом чтобы оставлять комментарии