22

I have a JSF 2.0 application on Tomcat with many <h:inputText> fields to input data in my database. Some fields are not required.

<h:inputText value="#{registerBean.user.phoneNumber}" id="phoneNumber">
    <f:validateLength maximum="20" />
</h:inputText>

When the user leave this field empty JSF sets empty string "" instead of null.

How can I fix this behavior without checking every String with

if (string.equals("")) { string = null; }
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
ThreeFingerMark
  • 989
  • 3
  • 12
  • 21
  • are you sure your "user" object doesn't have "" as default value? – Bozho Feb 04 '10 at 22:06
  • 1
    @Bozho: don't you mean `phoneNumber`? ;) AFAIK this is the default behaviour in JSF 1.x and workaroundable with a `Converter` in JSF 1.2 (not in 1.1 or older). I just did little test in JSF 2.0 and it's indeed also the default behaviour and workaroundable with a `Converter`. But I was also almost certain that I've read somewhere before that you can configure JSF 2.x to set `null` in case of an empty string by some special `init-param`. I only don't recall anymore which one it is and where I've read it :( – BalusC Feb 04 '10 at 22:26
  • Finally found it somewhere at the bottom of the JSF 2.0 spec.. See answer ;) – BalusC Feb 04 '10 at 23:00

2 Answers2

51

You can configure JSF 2.x to interpret empty submitted values as null by the following context-param in web.xml (which has a pretty long name, that'll also be why I couldn't recall it ;) ):

<context-param>
    <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
    <param-value>true</param-value>
</context-param>

For reference and for ones who are interested, in JSF 1.2 (and thus not 1.1 or older because it's by design not possible to have a Converter for java.lang.String) this is workaroundable with the following Converter:

public class EmptyToNullStringConverter implements Converter {

    public Object getAsObject(FacesContext facesContext, UIComponent component, String submittedValue) {
        if (submittedValue == null || submittedValue.isEmpty()) {
            if (component instanceof EditableValueHolder) {
                ((EditableValueHolder) component).setSubmittedValue(null);
            }

            return null;
        }

        return submittedValue;
    }

    public String getAsString(FacesContext facesContext, UIComponent component, Object modelValue) {
        return (modelValue == null) ? "" : modelValue.toString();
    }

}

...which needs to be registered in faces-config.xml as follows:

<converter>
    <converter-for-class>java.lang.String</converter-for-class>
    <converter-class>com.example.EmptyToNullStringConverter</converter-class>
</converter>

In case you're not on Java 6 yet, replace submittedValue.empty() by submittedValue.length() == 0.

See also

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 4
    @James: so you're using Tomcat (or JBoss or Websphere which uses Tomcat under covers)? If true, add VM argument `-Dorg.apache.el.parser.COERCE_TO_ZERO=false`. See also http://stackoverflow.com/questions/3116517 – BalusC Jun 17 '11 at 17:11
  • @BalusC: That fixes it, but I honestly don't understand why since I am binding into a String field, care to explain? Unfortunately it's also a solution that's not going to work for me as we don't direct control over the servers (Tomcat or otherwise) that the client may be running our app under. – James McMahon Jun 17 '11 at 17:32
  • @James: That's something new in Tomcat 7. See also http://stackoverflow.com/questions/6304025/work-around-for-faulty-interpret-empty-string-submitted-values-as-null-in-mojarra/6306137#6306137 – BalusC Jun 17 '11 at 17:33
  • @BalusC: I'm not using Tomcat 7. I am using 6.0.32. Must be a bug in both. – James McMahon Jun 17 '11 at 17:36
  • @James: Well, things have changed again in Tomcat between 6.0.17 and 6.0.32 which I am not aware of. I am pretty certain that this didn't affect strings in Tomcat 6.0.20. – BalusC Jun 17 '11 at 17:57
  • @BalusC: Well that's certainly a pain :). Thanks for your help. – James McMahon Jun 17 '11 at 18:39
  • 1
    Coworker looked at the Tomcat code, COERCE_TO_ZERO is a misleading property. It actually turns off coercion unless the objects don't match (number to string). So when this property is set Tomcat doesn't coerce the null String into a blank String. – James McMahon Jun 17 '11 at 20:06
  • @BalusC: Why is it necessary to call setSubmittedValue(null)? What does this do? – Craig Wohlfeil Aug 31 '12 at 20:55
  • @Craig: this sets the submitted value to `null`, for the case some (custom) validator extracts it directly from the component instead of from the `validate()` method argument. – BalusC Aug 31 '12 at 21:19
0

i hope this is the right way to say that i can't find a solution for the Problem.

I have add the context-param to my web.xml but it has no result. I use a Tomcat 6.0.24 Server with this two context-param: javax.faces.PROJECT_STAGE = Development javax.faces.VALIDATE_EMPTY_FIELDS = true

Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
ThreeFingerMark
  • 989
  • 3
  • 12
  • 21
  • In the future, just edit your question :) As to the problem: what if you remove one or both of the other parameters? I have tested it at Glassfish v3 by the way. I'll test at Tomcat later this day when I have chance. – BalusC Feb 08 '10 at 11:34
  • Yes, i have remove the other parameters but without a result. I wait for your test. Thanks – ThreeFingerMark Feb 08 '10 at 14:16
  • I was able to reproduce the same problem. The cause seems to be inside Tomcat's EL implementation. We can't do anything against it than hacking in it. Until they get it officially fixed and released, I would suggest to use the `Converter` as shown in my answer. It works fine. – BalusC Feb 09 '10 at 01:09
  • Thank you for your Help. I use now Glasfish and it works like a charm – ThreeFingerMark Feb 11 '10 at 14:00