我真的很困惑,在检查了很多次之后,我请求你的帮助。
我有一个 MySQL 表,其中包含我需要在我正在创建的网站的主页上显示的引号。它们在这里与此代码一起展示
<h:outputText value="#{fraseMB.aleatoria.frase}"></h:outputText>
<h:outputText value=" (#{fraseMB.aleatoria.autor})"></h:outputText>
如您所见,我们的想法是显示引文(frase,葡萄牙语)和作者姓名(autor,葡萄牙语)。
此代码由以下应用程序范围的 bean 支持:
package net.isalicos.frase;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ApplicationScoped;
@ManagedBean(name="fraseMB")
@ApplicationScoped
public class Frase implements Serializable {
private static final long serialVersionUID = -1211720749246194248L;
private int contador;
private FraseVO aleatoria;
private FraseDAO dao;
private List<FraseVO> lista;
@PostConstruct
public void init() {
this.contador = 0;
dao = new FraseDAO();
try {
lista = dao.getList();
} catch (ClassNotFoundException | SQLException e) {
}
}
public FraseVO getAleatoria() {
if(this.contador >= lista.size()) {
contador = 0;
}
this.aleatoria = lista.get(contador);
contador++;
return this.aleatoria;
}
public void setAleatoria(FraseVO aleatoria) {
this.aleatoria = aleatoria;
}
}
如您所见,我们的想法是轮换列表。当它到达终点时,计数器(contador,葡萄牙语)重置为 0,引号从头开始重新显示。由于有很多人同时访问该网站,事情不会变得太无聊和可预测...
引用列表由 DAO 对象使用以下代码检索:
private String queryBase() {
String qry = "SELECT t1.id,t1.frase,t1.autor,t1.idioma";
qry += " FROM frases AS t1";
return qry;
}
public List<FraseVO> getList() throws ClassNotFoundException, SQLException {
List<FraseVO> lista = new ArrayList<>();
FraseVO frase;
String qry = queryBase();
qry += " ORDER BY id";
ResultSet rs = getResult(qry);
while (rs.next()) {
frase = new FraseVO();
frase.setId(rs.getLong("id"));
frase.setFrase(rs.getString("frase"));
frase.setAutor(rs.getString("autor"));
frase.setIdioma(rs.getString("idioma"));
lista.add(frase);
}
return lista;
}
至此一切都很好,一切都是正统而简单的。现在我们有了奇怪的部分!
当我转到主页时,它显示了引述但作者错误。它在表的下一条记录中显示作者。例如,如果引用在记录 #1 中,作者就是记录 #2 中的作者。
我什么都试过了。起初我以为这是我的 bean 的范围。最初它是 RequestScoped 并且可以合理地假设它正在将记录从一个请求推进到另一个请求。但后来我将其更改为 ViewScoped
、SessionScoped
,最后更改为 ApplicationScoped
,获得相同的结果!
这可能非常简单,但我承认我看不出错误在哪里。
最佳答案
假设计数器从 0 开始。当您调用 #{fraseMB.aleatoria.frase}
时,将调用 getAleatoria()
方法,从列表中获取结果 0 并递增柜台。计数器值现在是 1。
然后调用#{fraseMB.aleatoria.autor}
。再次调用 getAleatoria()
方法。它现在从列表中返回结果 1。计数器再次递增,其值现在为 2。
这就是您的短语和作者不匹配的原因。
解决这个问题的最简单方法可能是使用 c:set
,并将短语存储在一个临时变量中:
<c:set var="frase" value="#{fraseMB.aleatoria}" scope="request" />
<h:outputText value="#{frase.frase}"></h:outputText>
<h:outputText value=" (#{frase.autor})"></h:outputText>
关于java - 应用程序范围的 bean 生成一个非常奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26726336/