Tomcat 8(和9)强制行为,空字符串被错误地设置为空字符串 [英] Tomcat 8 (and 9) coerce behaviour, null strings are incorrectly set as empty strings

查看:157
本文介绍了Tomcat 8(和9)强制行为,空字符串被错误地设置为空字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have just migrated to Tomcat 8. I used to work with system property org.apache.el.parser.COERCE_TO_ZERO=false so empty strings, numbers, booleans etc. are treated as null.

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

In Tomcat 8, EL 3.0, it is supposed to be the default but it is in fact converting null string to empty string "" on JSF side.

应该是 bug ,并且应该可以更正,但是我无法在TomEE快照(Tomcat 8.0.27.0,MyFaces 2.2.8)中使用它.

It is supposed to be a bug and it is supposed to be corrected but I'm not able to get it working in TomEE snapshot (Tomcat 8.0.27.0, MyFaces 2.2.8).

推荐答案

这是EL 3.0规范中的错误.从EL 3.0开始,由于 JSF问题3071

This is a bug in the EL 3.0 specification. Since EL 3.0, as consequence of overzealous fix of JSP spec issue 184, null will be coerced back to empty string before the model value setter is invoked. Basically, the javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL doesn't have any affect anymore. See also JSF issue 3071 and EL spec issue 18.

基本上,要解决此问题,您需要提供一个自定义的EL解析器,或者将EL实现(或实际上是整个服务器,因为它是实际提供EL的那个)替换/升级为带有错误修正的版本.您链接的 Tomcat问题57309 与该特定EL不相关3.0出现从空字符串到空字符串的不必要强制,这仅与Tomcat对自定义EL解析器的无知有关.

Basically, to solve this problem you need to provide either a custom EL resolver, or to replace/upgrade the EL implementation (or simply the whole server as it's the one actually providing EL out the box) to a version with the bugfix. The Tomcat issue 57309 which you linked is not related to this particular EL 3.0 issue of unnecessary coercion from null to empty string, it's only related to Tomcat's ignorance of the custom EL resolver.

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

You can solve this problem in two ways:

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

  1. Provide a custom EL resolver like below. Make sure that you use Tomcat 8.0.16 or newer, as specified in the Tomcat issue report you found.

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中进行以下注册:

In order to get it to run, register as below in faces-config.xml:

<application>
    <el-resolver>com.example.EmptyToNullStringELResolver</el-resolver>
</application>


  • 或者,切换到Oracle EL.他们已经在版本3.0.1 b05 <中修复了该问题/a>(自2014年7月7日起可用)(只需选择最新就是今天的3.0.1-b10).


  • Or, switch to Oracle EL. They already fixed it in version 3.0.1 b05 which has been available since 7 July 2014 (just pick the newest one which is 3.0.1-b10 as of today).

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

    Just drop javax.el.jar file in /WEB-INF/lib and add the below context param to web.xml in order to instruct MyFaces to use the Oracle EL implementation instead:

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

    In case you're using Mojarra, use param name com.sun.faces.expressionFactory.

    当我也感到一时困惑时,我写了博客使它一切正常:空字符串疯狂.

    As I got momentarily confused myself too, I blogged to get it all right: The empty String madness.

    这篇关于Tomcat 8(和9)强制行为,空字符串被错误地设置为空字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆