Issue
Empty form input fields bound to bean String type are received as empty strings ("") when the expected value is NULL.
This is an old problem that seems to get recreated with each version of Oracle EL or Apache EL or Tomcat.
@BalusC has addressed it many times. Empty String Madness, Tomcat 8 (and 9) coerce behaviour, null strings are incorrectly set as empty strings are a couple of examples.
I have tried all previous workarounds without success.
someform.xhtml
<h:form>
<h:outputText value="Some Input: " />
<p:inputText value="#{someBean.stringVariable}" />
<p:commandButton id="search-button"
value="Search"
actionListener="#{someBean.doSearch}" />
</form>
SomeBean.java
private String stringVariable;
// Setter & Getter
public void doSearch()
{
if(stringVariable == null)
{
System.out.println("Input is NULL");
}
else if(stringVariable.equals(""))
{
System.out.println("Input is EMPTY STRING");
}
}
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd"
version="2.3">
<application>
<el-resolver>com.example.EmptyToNullStringELResolver</el-resolver>
</application>
<application>
<resource-handler>org.jepsar.primefaces.theme.jepsar.FontAwesomeResourceHandler</resource-handler>
<resource-handler>org.omnifaces.resourcehandler.UnmappedResourceHandler</resource-handler>
</application>
<application>
<el-resolver>
org.primefaces.application.exceptionhandler.PrimeExceptionHandlerELResolver
</el-resolver>
</application>
<factory>
<exception-handler-factory>
org.primefaces.application.exceptionhandler.PrimeExceptionHandlerFactory
</exception-handler-factory>
</factory>
</faces-config>
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
<param-value>com.sun.el.ExpressionFactoryImpl</param-value>
</context-param>
</web-app>
When I use the custom EmptyToNullStringELResolver method, a NPE is thrown.
java.lang.NullPointerException
at org.apache.myfaces.shared.resource.ValueExpressionFilterInputStream.read(ValueExpressionFilterInputStream.java:130)
at java.io.InputStream.read(InputStream.java:179)
at java.nio.channels.Channels$ReadableByteChannelImpl.read(Channels.java:385)
at org.omnifaces.util.Utils.stream(Utils.java:397)
at org.omnifaces.resourcehandler.UnmappedResourceHandler.handleResourceRequest(UnmappedResourceHandler.java:176)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:196)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at ...
Dropping the most recent EL jar from Oracle into WEB/lib seems to have no effect. (javax.el-3.0.1-b11.jar)
Thank you, Ted S
Solution
As per The Empty String Madness article, The EmptyToNullStringELResolver
and Oracle EL doesn't need to be done simultaneously. For Tomcat 8.0.16 or newer the following is listed:
JF: add
javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL=true
context param.
ER: registerEmptyToNullStringELResolver
, or alternatively, just do UE.
UE: migrate/upgrade to Oracle EL implementation version 3.0.1-b05 or newer.
Note the "alternatively" word. Thus it's fine to do only one or the other.
As to the observed NullPointerException
, it's thus happening when a ResourceHandler
needs to stream a resource which could possibly contain EL expressions. This by default only happens on CSS resources in order to be able to support How to reference JSF image resource as CSS background image url. The ValueExpressionFilterInputStream
represents MyFaces' internal class which is being used to evaluate EL expressions while reading an InputStream
. However, it has apparently a bug whereby it doesn't expect EL expressions which return null
instead of a concrete object. That problem is in turn actually unrelated to the solutions for "The Empty String Madness". It would have occurred nonetheless. You should at least scan your custom CSS files for EL expressions which incorrectly return null
and fix them.
Answered By - BalusC