将初始化参数从 JSF 视图传递到后台的托管 bean
Pass initialization argument from JSF view to managed bean in background
我是 JSF 的新手,正在努力将数据传递给我的支持 bean。我有一个 bean 应该读取数据并将其保存到一个特定的 table。此 table 有两列 "Property" 和 "Val"。 class 的简化版本如下所示:
@ManagedBean
@SessionScoped
public class GlobalProperties implements Serializable {
// private void setKey(param);
// private String getKey();
// some more attributes and getters / setters
private String property; // + getter/setter
private void saveProperty() throws SQLException {
try {
dbHandler = dbConnection.connect();
ps = dbHandler.prepareStatement("UPDATE TABLEXXX SET VAL = '" + getValue() + "' WHERE PROPERTYKEY = '" + getProperty() + "'");
ps.executeQuery();
} catch (SQLException ex) {
Logger.getLogger(GlobalProperties.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (dbHandler != null) {
dbHandler.close();
}
}
}
private void readProperty() throws SQLException {
try {
dbHandler = dbConnection.connect();
ps = dbHandler.prepareStatement("SELECT VAL FROM TABLEXXX WHERE PROPERTYKEY = '" + getProperty() + "'");
rs = ps.executeQuery();
while (rs.next()) {
setValue("VAL");
}
} catch (SQLException ex) {
Logger.getLogger(GlobalProperties.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (dbHandler != null) {
dbHandler.close();
}
}
}
}
此 class 已在多个页面上使用。在每个使用它的页面上,它需要为 属性 属性填充不同的值,因为我必须从 table 读取不同的键。在 JSF 端有一个文本输入,它显示值并在用户单击保存按钮时设置它。
每当创建此 class 的实例时,我都需要向 class 传递有关它必须读取的键的信息。但是我无法在 JSF 端找到合适的机制来实现这一点,因为它非常重要,用户不能更改该值。
我最后一次尝试是像这样使用 "preRenderView"-事件:
<f:metadata>
<f:event type="preRenderView" listener="#{globalProperties.setKey('SYSTEM_NAME')}" />
</f:metadata>
这样对吗?
在后台的 ManagedBean 中设置 属性 的最佳做法是什么,无需任何用户操作并且以安全的方式,以便它不能被用户操纵?
谢谢大家。
<f:event type="preRenderView">
在每次请求时被调用。这对于请求作用域 bean 可能没问题,但对于 view/session 作用域 bean 则不必要。另见 What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
另一方面,虽然 preRenderView
方法可行,但 JSF 视图应该是声明式的。模型(这个特定视角中的支持 bean)实际上应该根据视图执行初始化,而不是相反。所以当你对此有疑问时,你的直觉是正确的。
JSF 对此没有专门的方法。最接近的声明方法是在 <f:metadata>
("define a metadata attribute on the view").
中使用 <f:attribute>
<f:metadata>
<f:attribute name="key" value="SYSTEM_NAME" />
</f:metadata>
UIViewRoot#getAttributes()
在 a.o @PostConstruct
:
String key = (String) context.getViewRoot().getAttributes().get("key");
或者当你碰巧使用 OmniFaces:
String key = Faces.getMetadataAttribute("key");
OmniFaces 展示应用程序也使用这种方法来声明文档和源代码的路径(参见示例 /push/socket.xhtml
source of <o:socket>
showcase)。
另一种方法是通过视图 ID 在应用程序范围内映射键,并改为依赖视图 ID。
Map<String, String> keysByViewId = new HashMap<>();
keysByViewId.put("/foo.xhtml", "SYSTEM_NAME");
String key = keysByViewId.get(context.getViewRoot().getViewId());
我是 JSF 的新手,正在努力将数据传递给我的支持 bean。我有一个 bean 应该读取数据并将其保存到一个特定的 table。此 table 有两列 "Property" 和 "Val"。 class 的简化版本如下所示:
@ManagedBean
@SessionScoped
public class GlobalProperties implements Serializable {
// private void setKey(param);
// private String getKey();
// some more attributes and getters / setters
private String property; // + getter/setter
private void saveProperty() throws SQLException {
try {
dbHandler = dbConnection.connect();
ps = dbHandler.prepareStatement("UPDATE TABLEXXX SET VAL = '" + getValue() + "' WHERE PROPERTYKEY = '" + getProperty() + "'");
ps.executeQuery();
} catch (SQLException ex) {
Logger.getLogger(GlobalProperties.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (dbHandler != null) {
dbHandler.close();
}
}
}
private void readProperty() throws SQLException {
try {
dbHandler = dbConnection.connect();
ps = dbHandler.prepareStatement("SELECT VAL FROM TABLEXXX WHERE PROPERTYKEY = '" + getProperty() + "'");
rs = ps.executeQuery();
while (rs.next()) {
setValue("VAL");
}
} catch (SQLException ex) {
Logger.getLogger(GlobalProperties.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (dbHandler != null) {
dbHandler.close();
}
}
}
}
此 class 已在多个页面上使用。在每个使用它的页面上,它需要为 属性 属性填充不同的值,因为我必须从 table 读取不同的键。在 JSF 端有一个文本输入,它显示值并在用户单击保存按钮时设置它。
每当创建此 class 的实例时,我都需要向 class 传递有关它必须读取的键的信息。但是我无法在 JSF 端找到合适的机制来实现这一点,因为它非常重要,用户不能更改该值。
我最后一次尝试是像这样使用 "preRenderView"-事件:
<f:metadata>
<f:event type="preRenderView" listener="#{globalProperties.setKey('SYSTEM_NAME')}" />
</f:metadata>
这样对吗?
在后台的 ManagedBean 中设置 属性 的最佳做法是什么,无需任何用户操作并且以安全的方式,以便它不能被用户操纵?
谢谢大家。
<f:event type="preRenderView">
在每次请求时被调用。这对于请求作用域 bean 可能没问题,但对于 view/session 作用域 bean 则不必要。另见 What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
另一方面,虽然 preRenderView
方法可行,但 JSF 视图应该是声明式的。模型(这个特定视角中的支持 bean)实际上应该根据视图执行初始化,而不是相反。所以当你对此有疑问时,你的直觉是正确的。
JSF 对此没有专门的方法。最接近的声明方法是在 <f:metadata>
("define a metadata attribute on the view").
<f:attribute>
<f:metadata>
<f:attribute name="key" value="SYSTEM_NAME" />
</f:metadata>
UIViewRoot#getAttributes()
在 a.o @PostConstruct
:
String key = (String) context.getViewRoot().getAttributes().get("key");
或者当你碰巧使用 OmniFaces:
String key = Faces.getMetadataAttribute("key");
OmniFaces 展示应用程序也使用这种方法来声明文档和源代码的路径(参见示例 /push/socket.xhtml
source of <o:socket>
showcase)。
另一种方法是通过视图 ID 在应用程序范围内映射键,并改为依赖视图 ID。
Map<String, String> keysByViewId = new HashMap<>();
keysByViewId.put("/foo.xhtml", "SYSTEM_NAME");
String key = keysByViewId.get(context.getViewRoot().getViewId());