使用 VariableResolver 装饰来扩展表达式语言功能性的 JavaServer Faces 技术应用程序可能无法正常工作。
JavaServer Faces 技术规范 的第 10.4.5 条规定:
“替换默认的 PropertyResolver、VariableResolver、ActionListener、NavigationHandler、ViewHandler 或 StateManager 时,将利用装饰程序的设计模式,从而在您提供具有一个合适参数类型的构造函数时,自定义实现会收到对先前履行该职责的实现的引用。这样,自定义实现可以只覆盖功能的子集(或只提供某些附加功能)并将剩余部分委托给现有实现。”
在 Application Server 9 中,自定义的 VariableResolver 实现将收到未完全履行变量解析职责的“先前”的 VariableResolver。
我们建议不委托“先前”的 VariableResolver 来解析表达式,而是创建 ValueExpression 并计算它的值。
public class CustomVR extends VariableResolver { private VariableResolver previous = null; public CustomVR(VariableResolver previous) { this.previous = previous; } public Object resolveVariable(FacesContext context, String name) throws EvaluationException { Object result = null; // Do some action that may resolve the variable. If not, you // may be tempted to simply do: // result = previous.resolveVariable(context, name); // But this would not work due to bug 6419278. A fix is // available, please see the Release Notes. However, a // workaround is the following. ValueExpression ve = context.getApplication().getExpressionFactory(). \ createValueExpression(context.getELContext(), "#{" + name + "}", Object.class); try { result = ve.getValue(context.getELContext()); } catch (PropertyNotFoundException pnfe) { throw new EvaluationException(pnfe); } catch (ELException ele) { throw new EvaluationException(ele); } return result; } }