Занятие 2. Валидация. Использование globalMessages.properties
В первом занятии рассматривалась ручная валидация данных, которые были введены пользователем в форме, т.е если класс-экшин реализует интерфейс Validateable, то Struts вызывает метод validate.
public class LoginAction extends ActionSupport
implements Validateable {
...
}
Также Struts позволяет использовать валидацию на основе XML параллельно c ручной валидацией.
Чтобы использовать XML-валидацию, нужно создать XML-файл, имя которого состоит из имени класса и постфикса -validation: LoginAction-validation.xml. В нём указано, какие поля являются обязательными для заполнения, и какими сообщениями должны быть заполнены поля сообщений в случае, если пользователь пропустил то или иное поле:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-
//OpenSymphony Group//XWork Validator 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd">
<validators>
<field name="name">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message key="error.nameRequired"/>
</field-validator>
</field>
<field name="password">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message key="error.passwordRequired"/>
</field-validator>
</field>
</validators>
Рассмотрим подробнее:
<field name="name"> <field-validator type="requiredstring"> <param name="trim">true</param> <message key="error.nameRequired"/> </field-validator> </field>
Это равноценно следующему:
if (this.getName().length() < 1) {
if (this.getName().length() < 1)
addFieldError("name", this.getText("error.nameRequired"));
}
Struts проверяет, заполнены ли необходимые поля, обрезая пробелы по бокам введённых значений, и если не заполнены, возвращает сообщения об ошибках.
То есть валидация может выполняться на 2 уровнях: на уровне XML и на уровне классов, определённых программистом. В нашем примере часть класса LoginAction, отвечающую за валидацию, можно переписать так:
public void validate() {
if (this.getFieldErrors() != null &&
!this.getFieldErrors().isEmpty())
return;
if (!"user".equalsIgnoreCase(this.getName()) ||
!"user".equalsIgnoreCase(this.getPassword()))
addFieldError("invalidLoginPassw",
this.getText("error.invalidLoginPassw"));
}
Так же как и в первом уроке, если валидация не пройдена и у нас есть сообщения об ошибках, то method="loginSubmit" не вызывается, и мы сразу переходим на result с name="input". Т.е. вернемся к странице с формой и заполненными полями об ошибках.
В следующих занятиях мы избавимся и от прямого указания логина и пароля, которые должен указать пользователь.
В методе validate() внутри класса LoginAction встречается такая конструкция: this.getText("error.invalidLoginPassw"), которая возвращает некоторый текст (на странице результата этот текст такой: «Invalid login/password»). Текст берётся из системного файла globalMessages.properties, где располагаются пары «ключ=значение» через знак равенства. Конструкция запрашивает ключ, по ключу возвращается значение. Построение файла globalMessages.properties напоминает синтаксис конфигурационных ini-файлов:
login=Login name=Name password=Password welcome=Welcome! error.nameRequired=Name is required error.passwordRequired=Password is required error.invalidLoginPassw=Invalid login/password
Ключ может включать в себя латинские буквы, цифры, точки и знак подчёркивания. Обращение из методов к этому файлу производится при помощи конструкции this.getText("ключ"), а из файлов, загружаемых как результаты экшнов, это обращение производится двумя другими способами.
Во-первых, с помощью тэгов с префиксами. Наряду с зарезервированными Struts-тэгами, такими как <s:textfield name="name"/>, есть тэги, которые обращаются к globalMessages.properties. Рассмотрим переработанное содержимое файла login.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head></head>
<body>
<div>
<s:fielderror><s:param>invalidLoginPassw</s:param></s:fielderror><br>
<s:fielderror><s:param>name</s:param></s:fielderror><br>
<s:fielderror><s:param>password</s:param></s:fielderror><br>
</div>
<s:form name="loginForm" action="loginSubmit" method="post">
<table>
<tr>
<td><s:text name="name"/>:</td>
<td><s:textfield name="name"/></td>
</tr>
<tr>
<td><s:text name="password"/>:</td>
<td><s:password name="password"/></td>
</tr>
<tr>
<td></td>
<td><s:submit value="%{getText('login')}"/></td>
</tr>
</table>
</s:form>
</body>
</html>
Тэг <s:text name="name"/> и является подобным обращением: он берёт из globalMessages.properties значение по ключу name, то есть текст «Name». Аналогично тэг <s:text name="password"/> при обработке файла Struts’ом будет заменен на слово «Password».
Во-вторых, случается необходимость поместить текст-значение из этого файла в другой тэг. Таким образом формируется текст на Submit-кнопке: тэг <s:submit value="%{getText('login')}"/> заменится на HTML-тэг кнопки, а конструкция %{getText('login')} внутри атрибута value — на текст «Login». Конструкция построена по правилам OGNL (Object Graph Navigation Language, см. http://struts.apache.org/2.0.12/docs/ognl.html или http://www.ognl.org/).
Содержимое файла home.jsp из примеров первого занятия тоже изменено с использованием обращения к globalMessages.properties:
<%@ taglib prefix="s" uri="/struts-tags" %> <html> <head></head> <body> <s:text name="welcome"/> </body> </html>
Очевидно, что тэг <s:text name="welcome"/> заменится на приветствие «Welcome!».


Copyright © 19992012 LAR
14.05.2009 в 16:02
if (this.getName().length() < 1) {
if (this.getName().length() < 1)
addFieldError(”name”, this.getText(”error.nameRequired”));
}
Это что? Контрольный выстрел?
04.06.2009 в 02:43
Видимо, авторы хотели где-то там воткнуть .trim()…