Tomcat 8(和9)强制行为,空字符串被错误地设置为空字符串

时间:2015-10-25 19:37:32

标签: jsf el jsf-2.2 tomcat8 tomee

我刚刚迁移到Tomcat 8.我曾经使用系统属性org.apache.el.parser.COERCE_TO_ZERO=false,所以空字符串,数字,布尔值等被视为null

在Tomcat 8,EL 3.0中,它应该是默认值,但它实际上是在JSF端将null字符串转换为空字符串""

它应该是bug并且它应该被纠正但我无法在TomEE快照(Tomcat 8.0.27.0,MyFaces 2.2.8)中使用它。

1 个答案:

答案 0 :(得分:8)

这是EL 3.0规范中的错误。由于EL 3.0,由于JSP spec issue 184的过度修复,null将在调用模型值设置器之前被强制回空字符串。基本上,javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL不再有任何影响。另请参阅JSF issue 3071EL spec issue 18

基本上,要解决这个问题,您需要提供一个自定义EL解析器,或者更换/升级EL实现(或者只是整个服务器,因为它实际上是从盒子里提供EL的那个)到一个带有错误修复的版本。您链接的Tomcat issue 57309与从null到空字符串的不必要强制的特定EL 3.0问题无关,它只与Tomcat对自定义EL解析器的无知有关。

您可以通过两种方式解决此问题:

  1. 提供如下所示的自定义EL解析器。确保使用Tomcat 8.0.16或更高版本,如您找到的Tomcat问题报告中所指定的那样。

    public class EmptyToNullStringELResolver extends ELResolver {
    
        @Override
        public Class<?> getCommonPropertyType(ELContext context, Object base) {
            return String.class;
        }
    
        @Override
        public Object convertToType(ELContext context, Object value, Class<?> targetType) {
            if (value == null && targetType == String.class) {
                context.setPropertyResolved(true);
            }
    
            return value;
        }
    
        @Override
        public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
            return null;
        }
    
        @Override
        public Class<?> getType(ELContext context, Object base, Object property) {
            return null;
        }
    
        @Override
        public Object getValue(ELContext context, Object base, Object property) {
            return null;
        }
    
        @Override
        public boolean isReadOnly(ELContext context, Object base, Object property) {
            return true;
        }
    
        @Override
        public void setValue(ELContext context, Object base, Object property, Object value) {
            // NOOP.
        }
    
    }
    

    要使其运行,请在faces-config.xml

    中注册如下
    <application>
        <el-resolver>com.example.EmptyToNullStringELResolver</el-resolver>
    </application>
    
  2. 或者,切换到Oracle EL。他们已经在version 3.0.1 b05修复了它,自2014年7月7日开始提供(只需选择今天为3.0.1-b10的newest)。

    只需将javax.el.jar文件放入/WEB-INF/lib并将以下上下文参数添加到web.xml,以指示MyFaces改为使用Oracle EL实现:

    <context-param>     
        <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name>
        <param-value>com.sun.el.ExpressionFactoryImpl</param-value>   
    </context-param>
    

    如果您使用的是Mojarra,请使用参数名称com.sun.faces.expressionFactory

  3. 由于我自己也很困惑,我在博客上写道:The empty String madness

    另见: