当在 JSF 中处理一个表单时,它是否全部发生在一个线程中?
When a form is handled in JSF, does it all happen in one thread?
说我有这段代码
<p:dataTable styleClass="scheduleTable" value="#{todaySchedule.hours}" var="hour">
<p:column headerText="Hour" styleClass="hourColumn" >
#{hour.time}
</p:column>
</p:dataTable>
并且在名为 todaySchedule 的 class 中,有一个方法
public List<Hour> getHours() {
final List<Hour> hours = IntStream.range(0, Hour.TIME.values().length)
.mapToObj($ -> new Hour()).collect(Collectors.toList());
for (int i = 0; i < 5; i++) {
hours.get(i).setHour(1);
}
return hours;
}
现在是时间 class
public class Hour {
private int time;
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
}
现在,我不确定 JSF 在幕后做了什么来使这个动态 dataTable 数据迭代通过小时列表成为可能,但我假设如果这一切都发生在一个线程中,那就没问题了。但是,如果在幕后,getHours 在实际生成列的另一个线程中使用并看到 Hour 处于错误状态怎么办?如果 getHours() 方法是
,则可以避免这种情况
public List<Hour> getHours() {
final List<Hour> hours = new ArrayList<>();
for (int i = 0; i < 5; i++) {
hours.add(new Hour(i + ""));
}
return hours;
}
with the corresponding Hour class being
public class Hour {
private final int time;
public Hour(int time) {
this.time = time;
}
public int getTime() {
return time;
}
}
但是,我的问题是,如果不更改为后一种设计,在发布此 Hour 实例时,由于 Java 中的可见性问题,使用基本动态 JSF dataTable 呈现时是否会出现问题?
JSF 运行s 在 Servlet API 之上,它在一个线程中处理一个请求,因此除非您自己引入更多线程,否则您可能希望您的代码 运行 在一个单线程。
另一方面,您应该了解 JSF 生命周期的基础知识以及如何访问 bean 属性,如果您不了解这可能会给您带来很多麻烦。
例如,如果您的 Java 代码保持不变,则向您的 JSF 添加对 todaySchedule.hours 的另一个引用会导致 getter 被调用两次,从而生成两次内容.这很快就会变得非常混乱,所以做一些 "caching" 是一件好事。我个人使用这种方法:
private List<Hour> hours = null;
private void initHours() {
this.hours = new LinkedList<>();
// Fill hours here
}
public List<Hour> getHours() {
if (this.hours == null) {
initHours();
}
return this.hours;
}
尽管在 JSF 生命周期的哪个阶段执行此操作,但您必须小心。例如,如果您在表单处理方法中更改影响列表生成的数据,则列表可能已经 "cached" 来自恢复视图阶段,并且在呈现视图阶段开始时不会反映更改。在这种情况下,您应该注意缓存并在需要重新加载时清除列表。
public void saveHours() {
// Save the data, do whatever you need to do
// This will ensure re-initializing the list on the next call
this.hours = null;
}
说我有这段代码
<p:dataTable styleClass="scheduleTable" value="#{todaySchedule.hours}" var="hour">
<p:column headerText="Hour" styleClass="hourColumn" >
#{hour.time}
</p:column>
</p:dataTable>
并且在名为 todaySchedule 的 class 中,有一个方法
public List<Hour> getHours() {
final List<Hour> hours = IntStream.range(0, Hour.TIME.values().length)
.mapToObj($ -> new Hour()).collect(Collectors.toList());
for (int i = 0; i < 5; i++) {
hours.get(i).setHour(1);
}
return hours;
}
现在是时间 class
public class Hour {
private int time;
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
}
现在,我不确定 JSF 在幕后做了什么来使这个动态 dataTable 数据迭代通过小时列表成为可能,但我假设如果这一切都发生在一个线程中,那就没问题了。但是,如果在幕后,getHours 在实际生成列的另一个线程中使用并看到 Hour 处于错误状态怎么办?如果 getHours() 方法是
,则可以避免这种情况public List<Hour> getHours() {
final List<Hour> hours = new ArrayList<>();
for (int i = 0; i < 5; i++) {
hours.add(new Hour(i + ""));
}
return hours;
}
with the corresponding Hour class being
public class Hour {
private final int time;
public Hour(int time) {
this.time = time;
}
public int getTime() {
return time;
}
}
但是,我的问题是,如果不更改为后一种设计,在发布此 Hour 实例时,由于 Java 中的可见性问题,使用基本动态 JSF dataTable 呈现时是否会出现问题?
JSF 运行s 在 Servlet API 之上,它在一个线程中处理一个请求,因此除非您自己引入更多线程,否则您可能希望您的代码 运行 在一个单线程。
另一方面,您应该了解 JSF 生命周期的基础知识以及如何访问 bean 属性,如果您不了解这可能会给您带来很多麻烦。
例如,如果您的 Java 代码保持不变,则向您的 JSF 添加对 todaySchedule.hours 的另一个引用会导致 getter 被调用两次,从而生成两次内容.这很快就会变得非常混乱,所以做一些 "caching" 是一件好事。我个人使用这种方法:
private List<Hour> hours = null;
private void initHours() {
this.hours = new LinkedList<>();
// Fill hours here
}
public List<Hour> getHours() {
if (this.hours == null) {
initHours();
}
return this.hours;
}
尽管在 JSF 生命周期的哪个阶段执行此操作,但您必须小心。例如,如果您在表单处理方法中更改影响列表生成的数据,则列表可能已经 "cached" 来自恢复视图阶段,并且在呈现视图阶段开始时不会反映更改。在这种情况下,您应该注意缓存并在需要重新加载时清除列表。
public void saveHours() {
// Save the data, do whatever you need to do
// This will ensure re-initializing the list on the next call
this.hours = null;
}