java - 应用程序范围的 bean 生成一个非常奇怪的结果

标签 java mysql jsf javabeans

我真的很困惑,在检查了很多次之后,我请求你的帮助。

我有一个 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 并且可以合理地假设它正在将记录从一个请求推进到另一个请求。但后来我将其更改为 ViewScopedSessionScoped,最后更改为 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/

相关文章:

php - 这段代码可以更干净吗?看起来是一个正确的状态?

mysql - 数据库设计缺陷

java - 程序仅以特定值进入无限循环

mysql - 重命名结果

java - Java如何维护字符串的格式

spring - 静态代码分析与 Spring 和其他抽象的配合如何?

java - JSF Maven Mojarra 实现

java - JSF/莫贾拉 2.0.2 : ui:repeat is totally broken when updating via AJAX

java - 有没有一种简单的方法可以在 Java 中计算和格式化时间/日期间隔?

java - 父类(super class)上 protected 数组的值意外更改