Зміст
Як і в попередній статті про Spring Web Flow, в даному прикладі використовуються вкладені flow. На цей раз їх буде два: один відповідає за авторизацію користувача, другий - за проходження тестування користувачем. Батьківський flow управляє взаємодією між вищезазначеними списками дій.
Лістинг батьківського tests-flow представлений нижче:
<?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:
<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>
<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. Успішне завершення тестування
Якщо тести будуть провалені, то користувач побачить сторінку failResult.jspx:
Рис 3. Неуспішне завершення тестування
< | Spring Web Flow. Тести. Частина 2. Модель і Контролер | Spring Web Flow. Тести. Частина 4. Flow Авторизації | > |