我最近继承了遗留(JSF 1.2)项目,其任务是使其符合JSF 2.2标准。我不是一位经验丰富的JSF开发人员,并且一直在关注网络上的各种建议。我遇到的一个无法找到适当解决方案的问题是通过表达式语言参数将方法绑定传递给自定义组件。这是一个例子:
browse.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
。这一切似乎都是一个黑客,更不用说没有完成facelet中的EL表达式评估,就像之前的JSF 1.2代码一样。
我错过了什么吗?如何将这个JSF 1.2代码转换为JSF 2.2?
编辑:这是我的“黑客”,有点,sorta工作。希望有更好的方法。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>
}