You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by Jesus Jr M Salvo <je...@gmail.com> on 2012/11/13 10:17:49 UTC

Extval: Getting a simple @RequiredIf working in JSF2

Hi,

As can be seen from the subject, I haven't used Extval before, and I
am having trouble testing out a simple proof-of-concept for
cross-validation in a JSF2 application.

My environment is as follows:

1) JBoss 7.1.1 ( NOT using MyFaces Core, but using the built-in
Mojarra JSF implementation )
2) Extval JARs in WEB-INF/lib:

   myfaces-extval-bean-validation-2.0.5.jar
   myfaces-extval-core-2.0.5.jar
   myfaces-extval-property-validation-2.0.5.jar

I did not include myfaces-extval-generic-support-2.0.5.jar as I get a

   Caused by: java.lang.ClassNotFoundException:
net.sf.cglib.proxy.MethodInterceptor

I could not find what version of cglib and asm is required, so I
downloaded the latest versions of cglib and asm from the corresponding
websites and added them to WEB-INF/lib. But then, I get:

   java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter
overrides final method visit
   Critical error during deployment: : java.lang.NoClassDefFoundError:
net/sf/cglib/core/DebuggingClassWriter

So therefore removed myfaces-extval-generic-support-2.0.5.jar. It
seems that I don't really need it anyway. After removing
generic-support, JBoss startsup.

But anyway, back to the original question, I need to conditionally
validate that a property is required only when another property is set
to a specific value. So, I have the following bean:

	package test;

	import java.io.Serializable;

	import javax.faces.bean.ManagedBean;
	import javax.faces.bean.ViewScoped;

	import org.apache.myfaces.extensions.validator.crossval.annotation.RequiredIf;

	@ManagedBean
	@ViewScoped
	public class ViewBean implements Serializable {

		private static final long serialVersionUID = 1L;

		private String type;
		@RequiredIf(valueOf="#{type eq 'OPT2'}")
		private String text;

		public String getType() {
			return type;
		}

		public String getText() {
			return text;
		}

		public void setType(String type) {
			this.type = type;
		}

		public void setText(String text) {
			this.text = text;
		}

	}

In the bean above, I only want to indicate that the property "text" is
required only if the property type is "OPT2". The sample XHTML file
below shows a fixed list of f:selectItems, one of which has a
itemValue of "OPT2", which I am expecting that, if I select the option
of "OPT2" ( with label of "Option 2" ), and I leave the text field
blank ( thereby leaving the "text" property of the bean empty, I am
expecting an output from h:messages.


	<!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:f="http://java.sun.com/jsf/core"
	      xmlns:ui="http://java.sun.com/jsf/facelets">

	<h:head></h:head>
	<body>
	<h:form>
	        Type:<h:selectOneMenu id="f_clmTyp" value="#{viewBean.type}"
	            required="true" requiredMessage="Claim Type is required">
	            <f:selectItem itemLabel="Option 1" itemValue="OPT1"/>
	            <f:selectItem itemLabel="Option 2" itemValue="OPT2"/>
	            <f:selectItem itemLabel="Option 3" itemValue="OPT3"/>
	        </h:selectOneMenu>
	        <br/>
	        Text:
	        <h:inputText id="f_text" value="#{viewBean.text}"/>
	        <br/>
	        <h:commandButton name="Submit" value="Submit"/>
	        <br/>
	</h:form>
	Submitted type: <h:outputText value="#{viewBean.type}"/><br/>
	Submitted text: <h:outputText value="#{viewBean.text}"/>
	<h:messages/>
	</body>
	</html>


In WEB-INF/web.xml, I have:

	<context-param>
	  <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
	  <param-value>false</param-value>
	</context-param>
	<context-param>
	  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
	  <param-value>client</param-value>
	</context-param>

But when I submit the form, I do not get any validation messages
outputted by h:messages.
I must be missing something simple, but what is it ??

Note: I have also tried setting
javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL to true
with the same result. In any case, in the long run, I have to rely on
setting it to false because of existing bugs in both Mojarra and
MyFaces core implementations ( actually, in the JSF specs themslves )
with regards to this context parameter:

https://forums.oracle.com/forums/thread.jspa?threadID=2459557&tstart=0
https://issues.apache.org/jira/browse/MYFACES-3525
http://java.net/jira/browse/JAVASERVERFACES-2262
http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-939

Also, another question is .. and maybe answers my original question
above.. how does Extval perform cross-validation on the bean
properties when according to the JSF lifecycle, the bean properties
are updated ( UPDATE_MODEL_VALUES ) AFTER the validation phase (
PROCESS_VALIDATION ) ?

Thanks,

John

Re: Extval: Getting a simple @RequiredIf working in JSF2

Posted by Gerhard Petracek <ge...@gmail.com>.
hi john,

@ #1:
in case of el-expressions extval records the ValueExpression of the
EditableValueHolder components during the validation phase and stores them
side by side with the converted value,... . -> you can use those
expressions to reference a target. if your validation target isn't a
value-binding or it doesn't get submitted with the same request, extval
just delegates to the jsf-api
(javax.faces.application.Application#evaluateExpressionGet) for resolving
the value.
-> it looks like you are just trying something which isn't supported
out-of-the-box. however, (if needed) you can register your
own ReferencingStrategy which allows to implement your own concepts for
resolving the target-value.

@ #2:
it's done at the end of the validation phase of jsf (see e.g. [1] - slide
28)

@ #3:
please start a new thread about myfaces-core and
javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
(extval supports this config-parameter as well, but with 'true' as the
default value.)

regards,
gerhard

[1]
http://os890.blogspot.co.at/2009/12/metadata-based-validation-ejug-seminar.html

http://www.irian.at

Your JSF/JavaEE powerhouse -
JavaEE Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces



2012/11/13 Jesus Jr M Salvo <je...@gmail.com>

> Hi,
>
> As can be seen from the subject, I haven't used Extval before, and I
> am having trouble testing out a simple proof-of-concept for
> cross-validation in a JSF2 application.
>
> My environment is as follows:
>
> 1) JBoss 7.1.1 ( NOT using MyFaces Core, but using the built-in
> Mojarra JSF implementation )
> 2) Extval JARs in WEB-INF/lib:
>
>    myfaces-extval-bean-validation-2.0.5.jar
>    myfaces-extval-core-2.0.5.jar
>    myfaces-extval-property-validation-2.0.5.jar
>
> I did not include myfaces-extval-generic-support-2.0.5.jar as I get a
>
>    Caused by: java.lang.ClassNotFoundException:
> net.sf.cglib.proxy.MethodInterceptor
>
> I could not find what version of cglib and asm is required, so I
> downloaded the latest versions of cglib and asm from the corresponding
> websites and added them to WEB-INF/lib. But then, I get:
>
>    java.lang.VerifyError: class net.sf.cglib.core.DebuggingClassWriter
> overrides final method visit
>    Critical error during deployment: : java.lang.NoClassDefFoundError:
> net/sf/cglib/core/DebuggingClassWriter
>
> So therefore removed myfaces-extval-generic-support-2.0.5.jar. It
> seems that I don't really need it anyway. After removing
> generic-support, JBoss startsup.
>
> But anyway, back to the original question, I need to conditionally
> validate that a property is required only when another property is set
> to a specific value. So, I have the following bean:
>
>         package test;
>
>         import java.io.Serializable;
>
>         import javax.faces.bean.ManagedBean;
>         import javax.faces.bean.ViewScoped;
>
>         import
> org.apache.myfaces.extensions.validator.crossval.annotation.RequiredIf;
>
>         @ManagedBean
>         @ViewScoped
>         public class ViewBean implements Serializable {
>
>                 private static final long serialVersionUID = 1L;
>
>                 private String type;
>                 @RequiredIf(valueOf="#{type eq 'OPT2'}")
>                 private String text;
>
>                 public String getType() {
>                         return type;
>                 }
>
>                 public String getText() {
>                         return text;
>                 }
>
>                 public void setType(String type) {
>                         this.type = type;
>                 }
>
>                 public void setText(String text) {
>                         this.text = text;
>                 }
>
>         }
>
> In the bean above, I only want to indicate that the property "text" is
> required only if the property type is "OPT2". The sample XHTML file
> below shows a fixed list of f:selectItems, one of which has a
> itemValue of "OPT2", which I am expecting that, if I select the option
> of "OPT2" ( with label of "Option 2" ), and I leave the text field
> blank ( thereby leaving the "text" property of the bean empty, I am
> expecting an output from h:messages.
>
>
>         <!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:f="http://java.sun.com/jsf/core"
>               xmlns:ui="http://java.sun.com/jsf/facelets">
>
>         <h:head></h:head>
>         <body>
>         <h:form>
>                 Type:<h:selectOneMenu id="f_clmTyp"
> value="#{viewBean.type}"
>                     required="true" requiredMessage="Claim Type is
> required">
>                     <f:selectItem itemLabel="Option 1" itemValue="OPT1"/>
>                     <f:selectItem itemLabel="Option 2" itemValue="OPT2"/>
>                     <f:selectItem itemLabel="Option 3" itemValue="OPT3"/>
>                 </h:selectOneMenu>
>                 <br/>
>                 Text:
>                 <h:inputText id="f_text" value="#{viewBean.text}"/>
>                 <br/>
>                 <h:commandButton name="Submit" value="Submit"/>
>                 <br/>
>         </h:form>
>         Submitted type: <h:outputText value="#{viewBean.type}"/><br/>
>         Submitted text: <h:outputText value="#{viewBean.text}"/>
>         <h:messages/>
>         </body>
>         </html>
>
>
> In WEB-INF/web.xml, I have:
>
>         <context-param>
>
> <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
>           <param-value>false</param-value>
>         </context-param>
>         <context-param>
>           <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
>           <param-value>client</param-value>
>         </context-param>
>
> But when I submit the form, I do not get any validation messages
> outputted by h:messages.
> I must be missing something simple, but what is it ??
>
> Note: I have also tried setting
> javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL to true
> with the same result. In any case, in the long run, I have to rely on
> setting it to false because of existing bugs in both Mojarra and
> MyFaces core implementations ( actually, in the JSF specs themslves )
> with regards to this context parameter:
>
> https://forums.oracle.com/forums/thread.jspa?threadID=2459557&tstart=0
> https://issues.apache.org/jira/browse/MYFACES-3525
> http://java.net/jira/browse/JAVASERVERFACES-2262
> http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-939
>
> Also, another question is .. and maybe answers my original question
> above.. how does Extval perform cross-validation on the bean
> properties when according to the JSF lifecycle, the bean properties
> are updated ( UPDATE_MODEL_VALUES ) AFTER the validation phase (
> PROCESS_VALIDATION ) ?
>
> Thanks,
>
> John
>