나는 Hibernate Validator와 JSF에서 놀라운 행동을 경험했다. 그 행동이 버그인지 또는 내 자신의 기대에 대한 오해인지 알고 싶습니다.JSF가 숨겨진 비공개 필드의 Bean 유효성 검사를 적용하는 이유는 무엇입니까?
나는이 Facelets의 페이지가 있습니다
<?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">
<h:body>
<h:form>
<h:inputText value="#{backingBean.someClass.someField}"/>
<h:commandButton value="submit" action="#{backingBean.submit1()}"/>
</h:form>
</h:body>
</html>
을 그리고 나는이 백업 콩이 : SomeSubClass.someField
는 부모 클래스의 private 변수와 같은 이름을 가진
import java.util.Set;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.hibernate.validator.constraints.NotEmpty;
@ManagedBean
@RequestScoped
public class BackingBean {
private SomeClass someClass = new SomeSubClass();
public SomeClass getSomeClass() {
return someClass;
}
public void setSomeClass(SomeClass someClass) {
this.someClass = someClass;
}
public void submit1() {
System.out.println("BackingBean: " + someClass.getSomeField());
((SomeSubClass) someClass).submit2();
}
public static class SomeClass {
private String someField;
public String getSomeField() {
return someField;
}
public void setSomeField(String someField) {
this.someField = someField;
}
}
public static class SomeSubClass extends SomeClass {
@NotEmpty
private String someField;
private void submit2() {
System.out.println("SomeSubClass: " + someField);
}
}
public static void main(String[] args) {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
SomeClass someClass = new SomeSubClass();
someClass.setSomeField("ham");
Set<ConstraintViolation<SomeClass>> errors = validator.validate(someClass);
for (ConstraintViolation<SomeClass> error : errors) {
System.out.println(error);
}
}
}
하는 것으로합니다. 이것은 사적인 영역을 그늘지게 할 수 없으므로 중요하지 않습니다.
두 가지 참고 사항 : 당신이 BackingBean
에서 main
방법을 실행하는 경우
- 은 발리는 항상 유효성 검사 오류 (메시지 "비어있을 수 없습니다")
SomeSubClass.someField
는 항상 null이기 때문에 반환됩니다. 이 문제는 나에게 맞는 것 같습니다. - 빈 값으로 양식을 제출하면 "비어 있지 않을 수도 있습니다"라는 오류 메시지가 나타납니다. 값을 입력하면 유효성 검사를 통과하지만
SomeSubClass.someField
값이 여전히 null임을 콘솔에 알 수 있습니다. 이 문제는 나에게 잘못된 것 같습니다.SomeSubClass.someField
의 이름을someField2
으로 변경하면 양식을 빈 값으로 제출할 수 있습니다. 이 문제는 나에게 잘못된 것 같습니다.
JSF의 검증 단계 및 최대 절전 모드 검사기는이 동작에 동의하지 않을 것으로 보인다. JSF는 서브 클래스의 private 필드의 유효성 검사기를 부모 클래스의 동일한 이름의 필드에 적용하지만 Hibernate Validator는 격리 된 상태로 테스트 할 때이 동작을 표시하지 않습니다.
누구든지이 동작을 설명 할 수 있습니까? 그것은 버그입니까, 아니면 내 자신의 기대에 대한 오해입니까?
사용 :
- 글래스 피쉬 서버 오픈 소스 버전 3.1.2.2
- 인 Mojarra 2.1.6
- 최대 절전 모드 검사기 4.3.0.Final을 는
@BalusC, 편집 해 주셔서 감사합니다. 귀하의 의견을 따를 때, 나는 Hibernate Validator를 고립 상태로 시험해 보았고, 그것은 내가하는 한 그것이 올바른 행동임을 알았다. 나는 JSF의 Validation Phase와 Hibernate Validator의 비교를이 문제를 보여주는 나의 질문에 추가했다. – DavidS
나는 본다. 좋은 업데이트! – BalusC