提交为空字符串与空字符串的空白输入字符串字段 - JSF 2.3 MyFaces - Tomcat (TomEE)/9.0.12 (8.0.0-M1)

Blank input String fields submitted as Empty Strings vs Null - JSF 2.3 MyFaces - Tomcat (TomEE)/9.0.12 (8.0.0-M1)

当预期值为 NULL 时,绑定到 bean String 类型的空表单输入字段将作为空字符串 ("") 接收。

这是一个老问题,似乎每个版本的 Oracle EL 或 Apache EL 或 Tomcat 都会重新创建。

@BalusC 已经解决了很多次。 Empty String Madness, 是几个例子。

我已经尝试了所有以前的解决方法,但都没有成功。

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");    
    }
}

面孔-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>

当我使用自定义 EmptyToNullStringELResolver 方法时,抛出 NPE。

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 ...

从 Oracle 中删除最新的 EL jar 到 WEB/lib 似乎没有效果。 (javax.el-3.0.1-b11.jar)

谢谢, 泰德

根据 The Empty String Madness 文章,EmptyToNullStringELResolver 和 Oracle EL 不需要同时完成。对于 Tomcat 8.0.16 或更新版本,列出了以下内容:

JF: add javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL=true context param.
ER: register EmptyToNullStringELResolver, or alternatively, just do UE.
UE: migrate/upgrade to Oracle EL implementation version 3.0.1-b05 or newer.

注意 "alternatively" 这个词。因此,只做一个或另一个都可以。

至于观察到的 NullPointerException,当 ResourceHandler 需要流式传输可能包含 EL 表达式的资源时,就会发生这种情况。默认情况下,这仅发生在 CSS 资源上,以便能够支持 How to reference JSF image resource as CSS background image urlValueExpressionFilterInputStream 表示 MyFaces 的内部 class,它用于在读取 InputStream 时评估 EL 表达式。但是,它显然有一个错误,即它不期望使用 return null 而不是具体对象的 EL 表达式。该问题实际上与 "The Empty String Madness" 的解决方案无关。尽管如此,它还是会发生。您至少应该扫描您的自定义 CSS 文件以查找错误 return null 的 EL 表达式并修复它们。