我最近继承了一个遗留 (JSF 1.2) 项目,并负责使其与 JSF 2.2 兼容。我不是一位经验丰富的 JSF 开发人员,并且一直在听从网络上的各种建议。我遇到的一个问题是我找不到合适的解决方案,那就是通过表达式语言参数将方法绑定传递给自定义组件。这是一个例子:
浏览.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:custom="http://www.custom.com/jsf/custom">
<f:view>
<head>
<title>Title</title>
</head>
<body>
<custom:condition test="#{MyBean.canView}">
Some private data here
</custom:condition>
</body>
</f:view>
</html>
MyBean.java:
public class MyBean {
public String canView() { return "true"; }
}
Conditional.java(映射到 custom:condition 标签):
public class Conditional extends UIComponentBase {
<snip>
private MethodBinding testBinding;
public MethodBinding getTest() {
return testBinding;
}
public void setTest(MethodBinding test) {
testBinding = test;
}
public boolean test(FacesContext context) {
boolean ret = true;
if (testBinding != null) {
try {
Object o = testBinding.invoke(context, null);
ret = o != null;
} catch (Exception e) {
e.printStackTrace();
}
}
return ret;
}
<snip>
}
我已经通过传递一个String
表达式(例如"MyBean.canView"
将 EL 哈希/大括号关闭,然后将它们连接回组件中并创建和调用MethodExpression
. 这一切似乎有点像 hack,更不用说没有像之前的 JSF 1.2 代码那样完成 facelet 中的 EL 表达式求值。
我错过了什么吗?应该如何将此 JSF 1.2 代码上转换为 JSF 2.2?
编辑:这是我的“hack”,有点工作。希望有更好的方法。
public class Conditional extends UIComponentBase {
<snip>
public boolean test(FacesContext context) {
if (testBinding != null) {
Object ret = null;
try {
ApplicationFactory factory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
MethodExpression methodExpression = factory.getApplication().getExpressionFactory().createMethodExpression(
FacesContext.getCurrentInstance().getELContext(),
"#{" + testBinding + "}", Boolean.class, new Class[] {});
ret = methodExpression.invoke(FacesContext.getCurrentInstance().getELContext(), null);
} catch (Exception e) {
e.printStackTrace();
}
if (ret == null) return false;
}
return true;
}
<snip>
}