繁体   English   中英

Java EL表达式:“属性(num1 | str)在类型(int | String)上不可读”

[英]Java EL expressions: “property (num1|str) not readable on type (int|String)”

我试图使用EL表达式创建一个谓词,用于使用提供的字符串来过滤任意对象来描述过滤器。 它适用于原始类型,但由于某种原因,它试图访问我提供的POJO,就好像它们是他们试图接收的类型一样。

例如,过滤器: "item.num1 > item.num2"应用于POJO:

 private class TestClass {
        private String str;
        private int num1, num2;

        public String getStr() {
            return str;
        }

        public void setStr(String str) {
            this.str = str;
        }

        // getters/setters continue below here
 }

产生这个例外:

javax.el.PropertyNotFoundException: Property 'num1' not readable on type int
    at javax.el.BeanELResolver$BeanProperty.read(BeanELResolver.java:267)
    at javax.el.BeanELResolver$BeanProperty.access$000(BeanELResolver.java:216)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:55)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:183)
    at org.apache.el.parser.AstGreaterThan.getValue(AstGreaterThan.java:38)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:185)
    at com.<redacted>.filters.ELPredicate.apply(ELPredicate.java:78)
    at com.google.common.collect.Iterators$7.computeNext(Unknown Source)
    at com.google.common.collect.AbstractIterator.tryToComputeNext(Unknown Source)
    at com.google.common.collect.AbstractIterator.hasNext(Unknown Source)
    at com.google.common.collect.Lists.newArrayList(Unknown Source)
    at com.google.common.collect.Lists.newArrayList(Unknown Source)
    at com.<redacted>.common.el.ELPredicateTest.pojoTest(ELPredicateTest.java:44)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

我把这个谓词放在一起是这样的:

public class ELPredicate<T extends Object> implements Predicate<T> {
    private String expression;
    private String radix;

    /**
     * @param expression
     *            expression
     * @param radix
     *            string to be replaced with value in expression
     */
    public ELPredicate(String expression, String radix) {
        this.expression = String.format("${%s}", expression);
        this.radix = radix;
    }

    @Override
    public boolean apply(final T input) {
        final Map<String, T> map = ImmutableMap.of(radix, input);
        ELContext context = new ELContext() {

            @Override
            public VariableMapper getVariableMapper() {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public FunctionMapper getFunctionMapper() {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public ELResolver getELResolver() {
                return new CompositeELResolver() {
                    {
                        this.add(new AttributeELResolver((Map<String, Object>) map));
                        this.add(new BeanELResolver(true));
                        this.add(new MapELResolver(true));
                        this.add(new ListELResolver(true));
                        this.add(new ArrayELResolver(true));

                    }
                };
            }
        };

        return (boolean) ExpressionFactory.newInstance().createValueExpression(context, expression, boolean.class).getValue(context);
    }

}

AttributeELResolver是我在这里无法粘贴的内部代码,但它只是将表达式中的字符串解析为它们在地图中的值,它允许我定义“项目”是什么。

找到了解决方案!

事实证明,这是一个访问问题,而不是我首先想到的类型兼容性问题。 将私有内部类(TestClass)更改为public使一切按预期工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM