katch
katch

Reputation: 71

@FacesConverter without converter-id and forClass

What should work properly if I do not specify the converter-id and(or) forClass in determining the @FacesConverter annotation? For example:

@FacesConverter
public class SplitConverter implements Converter{

@Override
public Object getAsObject(FacesContext context, UIComponent component,
        String value) {
    //...
}
@Override
public String getAsString(FacesContext context, UIComponent component,
        Object value) {
    //...

} 

After registred in faces-config.xml and use that on .xhtml page:

<h:inputText id="badges" value="#{article.badges}" 
    required="true">
    <f:converter converterId="com.katcgr.SplitConverter" />
</h:inputText>

And all is work. The documentation say that

if converter-id is the empty string, Application.addConverter(java.lang.Class,java.lang.String) is called, passing the converter-for-class as the first argument and the derived converter-class as the second argument.

But why everything works fine even if I not specified the forClass ?

Upvotes: 2

Views: 1353

Answers (1)

BalusC
BalusC

Reputation: 1109532

After registred in faces-config.xml

Registration via @FacesConverter and <converter> in faces-config.xml are mutually exclusive whereby the XML registration overrides any annotation registration. So, when your converter is referenced via the converter ID as registered in XML, then the converter instance behaves basically exactly as if it had no annotations. If you remove the XML registration, then you should have retrieved the below exception on specified converterId:

javax.faces.FacesException: Expression Error: Named Object: com.katcgr.SplitConverter not found.
    at com.sun.faces.application.ApplicationImpl.createConverter(ApplicationImpl.java:1339)
    at javax.faces.application.ApplicationWrapper.createConverter(ApplicationWrapper.java:393)
    at com.sun.faces.facelets.tag.jsf.ConverterTagHandlerDelegateImpl.createConverter(ConverterTagHandlerDelegateImpl.java:158)
    ...

This would basically only work if you had a

@FacesConverter("com.katcgr.SplitConverter")

If you however remove both the XML configuration and the <f:converter>, then it will "work" because the @FacesConverter without an explicit forClass will be automatically invoked for every bean property which is an instance of java.lang.Object (basically, everything), which does not have a more specific converter already registered. In other words, your converter will behave like:

@FacesConverter(forClass=Object.class)

It hopefully doesn't need an elaborate explanation that this is a terribly bad idea. It will also confuse PrimeFaces, because it will then internally initialize and use it as default converter for String class.

Upvotes: 2

Related Questions