java - Custom Validator class not working -
i have question here:
scenario: have jsf-2, spring (beans wiring) application. have written custom validator, want execute.
@facesvalidator("com.test.vali") @named("com.test.vali") public class testvalidator implements validator { @override public void validate(facescontext arg0, uicomponent arg1, object arg2) throws validatorexception { system.out.println("dhkdfkbhdfbkdfksdfdfk"); } }
i trying inject validator using following ways:
way#1:
<h:inputtext value="#{helloworld.name}"> <f:validator binding="#{com.test.vali}" /> </h:inputtext>
output
when tried render page, threw exception.
javax.servlet.servletexception: /testrichfaces.xhtml @17,48 <f:validator> validator id not specified. typically validator id set in constructor validatehandler(validatorconfig)
searched lot on this, , verified few ways like:
- java file in package.
way#2
<f:validator validatorid="com.test.vali" />
output
javax.servlet.servletexception: expression error: named object: com.test.vali not found.
so way#1 , way#2, interpret none of annotations working me.
then, tried move last approach:
way#3: adding validator in faces-config.xml, show using 2.0 compliance:
<faces-config 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-facesconfig_2_0.xsd" version="2.0">
and validator config is:
<validator> <validator-id>com.test.vali</validator-id> <validator-class>teet.testvalidator</validator-class> </validator>
output
works
now question arises, using jsf-2.0, had resort faces-config.xml.
what might mistake doing?
let know if more configurations required.
first of all, you're mixing 2 ways of registering validator instance work independently each other: registering faces validator via @facesvalidator
, or registering cdi managed bean via @named
. annotations not know each other, nor take each other account. end 2 distinct instances not share each others data. avoid future confusion, it's therefore recommended remove 1 of annotations can guarantee use 1 , same instance.
as why way 1 failed:
@named("com.test.vali") public class testvalidator implements validator { // ... }
<f:validator binding="#{com.test.vali}" />
this because period .
special operator in el representing bean property access or bean method call. using #{com.test.vali}
bean #{com}
, test
property , in turn vali
property. in other words, it's trying validator via com.gettest().getvali()
com
cdi managed bean @named("com")
.
this not intented. rid of periods in name. better, stick default instance name, testvalidator
. it's sane choice, sure if give classes sensible names.
@named public class testvalidator implements validator { // ... }
<f:validator binding="#{testvalidator}" />
as why way 2 failed:
@facesvalidator("com.test.vali") public class testvalidator implements validator { // ... }
<f:validator validatorid="com.test.vali" />
that may happen when @facesvalidator
isn't been picked during startup. may in turn happen when class in question not inside war, instead inside e.g. ear or ejb. in case, you'd need explicitly register validator in faces-config.xml
. better put class in war, should namely absolutely not have jsf artifacts in ear or ejb part of project. tight-couple model/service logic (jpa, ejb, etc) view (jsf) , make them not reusable anymore other views (front-ends) such jax-rs, spring mvc, struts2, etc.