Мы недавно обновили наши системы с JSF 1.2 до JSF 2.0 и в настоящее время работаем над тем, чтобы все работало. Однако у нас возникают проблемы с валидаторами, когда они используются внутри таблиц данных или аналогичных компонентов. По сути, проблема в том, что валидатор не может использовать переменную, установленную таблицей данных.
Вот пример:
валидатор:
package test;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
@FacesValidator("test.TestValidator")
public class TestValidator implements Validator {
private Integer length;
public TestValidator() {
super();
}
@Override
public void validate(FacesContext context,
UIComponent component, Object value) throws ValidatorException {
String text = (String) value;
if (text == null || text.trim().length() == 0) {
return;
}
if (length != null && text != null && length.intValue() < text.length()) {
String message = "The text is too long. It was " + text.length() +
", but only " + length + " characters are allowed.";
FacesMessage fm = new FacesMessage(
FacesMessage.SEVERITY_ERROR, message, null);
throw new ValidatorException(fm);
}
}
public Integer getLength() {
return length;
}
public void setLength(Integer length) {
this.length = length;
}
}
TagLib:
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
version="2.0">
<namespace>http://industry-supply.dk/test</namespace>
<tag>
<tag-name>testValidator</tag-name>
<validator>
<validator-id>test.TestValidator</validator-id>
</validator>
<attribute>
<name>length</name>
<required>true</required>
<type>java.lang.Integer</type>
</attribute>
</tag>
</facelet-taglib>
Управляемый боб:
package test;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean(name = "testBean")
@RequestScoped
public class TestBean {
public TestBean() {
}
public String[] getKey() {
return new String[]{
"0",
"1",
"2",
"3"
};
}
public String[] getValue() {
return new String[]{
"This is a text and it's too long.",
"This is a text and it's too long.",
"This is a text and it's too long.",
"This is a text and it's too long."
};
}
}
JSF:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:test="http://industry-supply.dk/test">
<h:head>
<title>Facelet Title</title>
</h:head>
<h:body>
<h:form>
<h:dataTable value="#{testBean.key}" var="k">
<h:column>
<h:message for="val"/>
<h:inputText id="val" value="#{testBean.value[k]}">
<test:testValidator length="#{testBean.key[k]}"/>
</h:inputText>
</h:column>
</h:dataTable>
<h:commandButton value="Submit"/>
</h:form>
</h:body>
</html>
При запуске проекта отображаются 4 поля ввода и командная кнопка. Каждое поле ввода содержит текст длиной 33 символа. Когда вы нажимаете «отправить», появляется сообщение об ошибке «Текст слишком длинный. Это было 33, но допускается только 0 символов». отображается для каждой строки / поля. Это неправильно, потому что "test: testValidator length =" # {testBean.key [k]} "" задает длину до 0 для первой строки, 1 для второй строки, 2 для третьей строки и 3 для четвертой строки. Поэтому для последней строки в сообщении об ошибке должно было быть сказано: «Текст слишком длинный. Это было 33, но допускается только 3 символа».
Проблема в том, что валидатор, похоже, не имеет доступа к переменной k из компонента dataTable в файле JSF. Это работало в JSF 1.2, но мы не можем заставить его работать в JSF 2.0. Мы потратили несколько дней на решение этой проблемы и действительно нуждаемся в помощи. У кого-нибудь есть идеи?