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

coc*_*llo 6 jsf el jsf-2.2 tomee tomcat8

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

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

它应该是一个错误,它应该被纠正,但我无法让它在TomEE快照(Tomcat 8.0.27.0,MyFaces 2.2.8)中运行.

Bal*_*usC 8

这是EL 3.0规范中的一个错误.由于EL 3.0,由于过分热心的修复后果JSP规范问题184,null将回空字符串被调用模型正值设置器之前裹挟.基本上,javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL它不再有任何影响.另见JSF issue 3071EL spec issue 18.

基本上,要解决这个问题,您需要提供一个自定义EL解析器,或者将EL实现(或简单地整个服务器,因为它是实际提供EL的那个)替换/升级到带有错误修复的版本.您链接的Tomcat问题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.
        }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

    要使其运行,请按以下方式注册faces-config.xml:

    <application>
        <el-resolver>com.example.EmptyToNullStringELResolver</el-resolver>
    </application>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 或者,切换到Oracle EL.他们已经在版本3.0.1 b05中修复了它,该版本已于2014年7月7日开始提供(只需选择最新版本为3.0.1-b10的版本).

    只需删除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>
    
    Run Code Online (Sandbox Code Playgroud)

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

由于我一时也弄糊涂了,我在博客上说得很好:空的String疯狂.

也可以看看: