-
1. Re: Customize validation messages
hstang Jan 3, 2007 2:03 PM (in response to hamtho2)Inside the hibernate-annotations.jar file, under org/hibernate/validator/resources, there are numerous property files.
i.e. DefaultValidatorMessages.properties
Just override those key values in your own messages.properties.
As well, there's a message attribute with most, if not all of the hibernate annotations that you can override. -
2. Re: Customize validation messages
norman.richards Jan 3, 2007 4:18 PM (in response to hamtho2)The validation annotations themselves have a place for a validation message. You can use either a custom message for the field or a resource to look for in your resource bundle.
-
3. Re: Customize validation messages
hamtho2 Jan 4, 2007 5:52 AM (in response to hamtho2)Thanks for your help! Norman, your solution worked perfectly as I wanted it to be, besides the fact that you have to use a slightly different annotation if you want to use messages fro the seam resourceBundle which caused me some confusions until I realized that fact. So if anyone else has the same problem use this syntax as an example:
@Length(min=3, message="#{messages['validation.user.name.length']}")
But I´d like to extend this topic a little bit, because I have some more questions about that. Unfortunately the hibernate validation were not used if the required=true attribute is missing in the jsf-tag. Although I´d say that for example a @Length(min=3) annotation also means that it should not be empty and for some reason the @NotEmpty-annotation is not supported with the current seam-release (is there a reason?).
So I have to add the required="true" attribute to every input field to work with the hibernate validation. Is there also a possibility to customize the "field-is-required"-messages for every input field, so it is not the standard-message from "javax.faces.component.UIInput.REQUIRED" for every field?
I saw, that sun uses a syntax like in the following code-snippet, to provide this functionality but it doesn´t seem to be a standard-jsf-tag:<h:inputText id="ccno" size="19" required="true" requiredMessage="#{customMessages.ReqMessage}" > ... </h:inputText> <h:message styleClass="error-message" for="ccno"/>
Furthermore I get an error while trying to use the sun jsf-impl, whereas myfaces works perfectly. But that´s probably another topic.
So is there also a solution to this problem?
Thank you very much for your help
Thomas -
4. Re: Customize validation messages
waheed.murad Jan 4, 2007 10:54 AM (in response to hamtho2)i have also faces the same problem? i have to also go for a same solution "required=true" instead of @NotNull. is it some thing wrong with this anotation if not then for what exactly it is for...
-
5. Re: Customize validation messages
norman.richards Jan 4, 2007 10:54 AM (in response to hamtho2)I think this is a real pain point for people. I through together a quick proof of concept. It works with MyFaces, but it shouldn't take that much to make a proper component out of. If anyone is ambitious enough, have ago at it:
package org.jboss.seam.ui; import javax.faces.component.*; import javax.faces.context.FacesContext; import javax.faces.application.FacesMessage; import org.jboss.seam.core.*; public class UIRequiredInput extends UIInput { String requiredMessage; public void setRequiredMessage(String requiredMessage) { this.requiredMessage = requiredMessage; } public String getRequiredMessage() { return requiredMessage; } @Override public boolean isRequired() { return true; } @Override protected void validateValue(FacesContext context, Object convertedValue) { System.out.println("*CHECKING! " + convertedValue); if (empty(convertedValue)) { context.addMessage(getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR, requiredMessage, requiredMessage)); System.out.println("*INVALID! " + convertedValue); setValid(false); } else { super.validateValue(context, convertedValue); } } protected boolean empty(Object value) { if (value == null) { return true; } if (value instanceof String) { String text = (String) value; if (text.length() == 0) { return true; } } return false; } @Override public void restoreState(FacesContext context, Object state) { Object[] values = (Object[]) state; super.restoreState(context, values[0]); requiredMessage = (String) values[1]; } @Override public Object saveState(FacesContext context) { Object[] values = new Object[2]; values[0] = super.saveState(context); values[1] = requiredMessage; return values; } }
Usage:<s:input id="payee" value="#{newPayment.payee}" requiredMessage="You have to send a payment TO somebody" />
This shouldn't be taken as saying this will ever become a proper seam component. I just put it in the ui package because it was easier to get started with. -
6. Re: Customize validation messages
hamtho2 Jan 25, 2007 8:56 AM (in response to hamtho2)Norman,
can you please give a little bit more detail about using your code. Simply creating the class and using the s:input-tag leads to an exception. Sorry - but I haven´t done anything in the tag-libraries yet, so I´m not so familiar how to add a new Tag.
I get the following exception:com.sun.facelets.tag.TagException: /WEB-INF/pages/registerUser/userDataForm.xhtml @53,142 <s:input> Tag Library supports namespace: http://jboss.com/products/seam/taglib, but no tag was defined for na me: input at com.sun.facelets.compiler.CompilationManager.pushTag(CompilationManager.java:193) at com.sun.facelets.compiler.SAXCompiler$CompilationHandler.startElement(SAXCompiler.java:194) at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source) at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source) at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) at javax.xml.parsers.SAXParser.parse(Unknown Source) at javax.xml.parsers.SAXParser.parse(Unknown Source) at com.sun.facelets.compiler.SAXCompiler.doCompile(SAXCompiler.java:232) at com.sun.facelets.compiler.Compiler.compile(Compiler.java:104) at com.sun.facelets.impl.DefaultFaceletFactory.createFacelet(DefaultFaceletFactory.java:192) at com.sun.facelets.impl.DefaultFaceletFactory.getFacelet(DefaultFaceletFactory.java:141) at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:293) at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:273) at com.sun.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:143) at com.sun.facelets.tag.ui.IncludeHandler.apply(IncludeHandler.java:60) at com.sun.facelets.tag.ui.DefineHandler.apply(DefineHandler.java:58) at com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:128) at com.sun.facelets.impl.DefaultFaceletContext$TemplateManager.apply(DefaultFaceletContext.java:306) at com.sun.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletContext.java:279) at com.sun.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:68) at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47) at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49) at com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.java:47) at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25) at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:248) at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:294) at com.sun.facelets.impl.DefaultFacelet.include(DefaultFacelet.java:273) at com.sun.facelets.impl.DefaultFaceletContext.includeFacelet(DefaultFaceletContext.java:143) at com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:113) at com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49) at com.sun.facelets.compiler.EncodingHandler.apply(EncodingHandler.java:25) at com.sun.facelets.impl.DefaultFacelet.apply(DefaultFacelet.java:95) at com.sun.facelets.FaceletViewHandler.buildView(FaceletViewHandler.java:510) at com.sun.facelets.FaceletViewHandler.renderView(FaceletViewHandler.java:553) at org.ajax4jsf.framework.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:101) at org.ajax4jsf.framework.ajax.AjaxViewHandler.renderView(AjaxViewHandler.java:222) at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:384) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:138) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.ajax4jsf.framework.ajax.xmlfilter.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:75) at org.ajax4jsf.framework.ajax.xmlfilter.BaseFilter.doFilter(BaseFilter.java:213) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.seam.servlet.SeamRedirectFilter.doFilter(SeamRedirectFilter.java:32) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.seam.servlet.SeamExceptionFilter.doFilter(SeamExceptionFilter.java:46) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
Thanks a lot.
By the way: I think that would be a great benefit for seam to have this component, so why don´t you make it a core-feature? I think it´s a very common and important thing to display user-friendly validation-messages. You should definately think about it
Thomas -
7. Re: Customize validation messages
agori Jan 25, 2007 9:32 AM (in response to hamtho2)"hamtho2" wrote:
By the way: I think that would be a great benefit for seam to have this component, so why don´t you make it a core-feature? I think it´s a very common and important thing to display user-friendly validation-messages. You should definately think about it
Thomas
If you need, JSF RI (1.2) has already the requiredMessage attribute... -
8. Re: Customize validation messages
pmuir Jan 25, 2007 10:10 AM (in response to hamtho2)Trinidad supports this as well.
-
9. Re: Customize validation messages
spambob Jan 25, 2007 4:17 PM (in response to hamtho2)+1 on the idea that stuff like @Length(min=3) triggers a validation error although required=true is missing if the field is empty! Is there an actual reason that this isn't the way it behaves?
For the people who want custom validation messages for certain input fields: http://www.oracle.com/technology/pub/articles/masterj2ee/j2ee_wk7.html (the "Adding Meaningful Field References" section) describes a way doing this by using a PhaseListener that customizes the validation messages based on parameter supplied by f:attribute tags inside the h:input stuff.
Does anyone now if the above approach is performance expensive? -
10. Re: Customize validation messages
gavin.king Jan 25, 2007 5:36 PM (in response to hamtho2)Is there an actual reason that this isn't the way it behaves?
We are limited by the JSF spec. -
11. Re: Customize validation messages
hamtho2 Jan 26, 2007 4:00 AM (in response to hamtho2)So what would you guys say: which jsf-implementation works better for seam? Right now we have the Sun JSF RI, Trinidad and myFaces (which I´m currently working with). In the seam documentation it is said, that trinidad is the better choice. Are there any major differences or any deviation from the standard specification between the alternatives, that should be kept in mind? What about future development? Do I have to be afraid that one of them won´t be developed furthermore?
What are your experiences? Right now I´m at the very beginning of development, so it´s still time to change. I don´t wanna realize that I did the wrong choice when it´s too late and I have to do a lot of rework then.
Thanks for sharing your experiences
Thomas -
12. Re: Customize validation messages
pmuir Jan 26, 2007 6:41 AM (in response to hamtho2)Choice of JSF impl is the RI or myfaces. Icefaces, tomahawk, trinidad are component libraries.
-
13. Re: Customize validation messages
hamtho2 Jan 26, 2007 8:44 AM (in response to hamtho2)Thanks for that - I guess that wasn´t too clear for me.
So a component-library like Trinidad also uses a standard-jsf component like inputText, but extends them without keeping the jsf-specifications? So I´m kind of stucked to one component-library if I choose to use one? -
14. Re: Customize validation messages
pmuir Jan 26, 2007 8:51 AM (in response to hamtho2)1) Yes.
2) Your stuck with one JSF impl but not component lib (but you may well find that they aren't that compatible!) - I know that a target of Trinidad is that it will be completely compatible with Tomahawk. And Seam's seam-ui , seam-pdf and seam-mail are component libraries and will (mostly) play nicely with any other component set. I use a couple internally as well (JSF versions of DOJO and support components).