Apache el implementation do the empty string (or 0 int value). You can find it in org.apache.el.parser.AstValue class:
public void setValue(EvaluationContext ctx, Object value)
throws ELException {
Target t = getTarget(ctx);
ctx.setPropertyResolved(false);
ELResolver resolver = ctx.getELResolver();
// coerce to the expected type
Class<?> targetClass = resolver.getType(ctx, t.base, t.property);
if (COERCE_TO_ZERO == true
|| !isAssignable(value, targetClass)) {
resolver.setValue(ctx, t.base, t.property,
ELSupport.coerceToType(value, targetClass));
} else {
resolver.setValue(ctx, t.base, t.property, value);
}
if (!ctx.isPropertyResolved()) {
throw new PropertyNotFoundException(MessageFactory.get(
"error.resolver.unhandled", t.base, t.property));
}
}
You can set COERCE_TO_ZERO to false (-Dorg.apache.el.parser.COERCE_TO_ZERO=false).
Or use other el impl:
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>el-impl</artifactId>
<version>2.2</version>
</dependency>
And set context-param:
servletContext.setInitParameter("com.sun.faces.expressionFactory", "com.sun.el.ExpressionFactoryImpl");
That was el-api side.
Other side is JSF. You have to set this context-param for JSF:
servletContext.setInitParameter("javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL", "true");
Sorry for my english!