【问题标题】:How to run a thread in the backgound of a jsf website?如何在jsf网站后台运行线程?
【发布时间】:2013-07-09 07:01:13
【问题描述】:

我正在尝试执行以下操作:我有一个网站,并且我的网站上有 jsf 页面。在某些页面中,我有一个 DataTable,其中填充了来自 database 的一些值。我想定期更新这个数据库,这样这些表中的值也会改变。当我搜索时,我发现我需要为此使用石英。我正在考虑制作一个托管 bean 来填充数据库中的表,然后从该 bean 的数据库中获取值。这是我的示例代码:

 <h:form>
        <rich:extendedDataTable style=" column-width: 174px; width:174px;" value="#{exchangeRates.values}" var="values"  id="accountsTable"  styleClass="accountsTable" headerClass="accountsTableHeader" rowClasses="accountsTableOddRow,accountsTableEvenRow"  >

            <rich:column width="40px;">
                <f:facet name="header">Currency</f:facet>
                   #{values.type}
            </rich:column>
            <rich:column width="45px;">
                <f:facet name="header">Alış</f:facet>
                   #{values.buy}
            </rich:column >
            <rich:column  width="45px;" >
                <f:facet name="header">Satış</f:facet>
                   #{values.sell}
            </rich:column>

        </rich:extendedDataTable>

以及此 jsf 页面的托管 bean:

private String value;
private ArrayList<Money> values = new ArrayList<>();

public ArrayList<Money> getValues() {
    try {
        getCurrentExchangeValue();
    } catch (IOException ex) {
        Logger.getLogger(ExchangeRates.class.getName()).log(Level.SEVERE, null, ex);
    }
    return values;
}

private void getCurrentExchangeValue() throws IOException {
     //GET THE VALUES FROM THE DATABASE AND
     //FILL THE  "values" ArrayList
}


public String getValue() {
    return value;
}

public void setValue(String value) {
    this.value = value;
}

我在页面中的数据表已成功填充此代码,但未定期更新。 我的问题是,我应该把“手动更新数据库”代码放在哪里?它应该在另一个函数中的这个托管 bean 上吗?我觉得我需要在免费中运行另一个线程,并且每当像 #{values.buy} 这样的东西调用托管 bean 时,线程应该更新数据库。我该怎么做?

谢谢

编辑:我认为我的问题并不清楚,所以总结一下:我希望数据库定期更新,比如每 10 分钟一次。由于我从数据库中填充了我的数据表,因此每当用户浏览查看此数据表的页面时,该表都会填充最新更新的数据库值。

【问题讨论】:

  • 您是否需要一直更新数据库,还是仅在用户查看页面时更新?您需要在用户查看时自动更新这些值还是仅在用户重新加载页面时自动更新?
  • @Simon 我想一直更新数据库,比如每 20 分钟一次,无论人们查看数据表所在的页面。我希望 db 中的值自动更新,这样如果用户查看数据表所在的页面,表中就会填充最新更新的值
  • 可以在查看页面时更新数据表视图

标签: java database jsf jakarta-ee quartz-scheduler


【解决方案1】:

使用数据表内容自动更新数据库,您需要定期向服务器发出 AJAX 请求。

除非您向服务器发出请求,否则在服务器端代码上使用多线程将无济于事。

要定期发送AJAX请求,可以使用JS timer和richfaces AJAX支持组件。

像这样启动计时器...

var pingInterval = 1000; // 1 sec
setInterval(contactServer, pingInterval);

function contactServer(){
    // send request to server 
}

您可以参考this 了解有关使用 Richfaces 发送 AJAX 请求的各种选项。

【讨论】:

  • 谢谢,但如果我手动更新数据表,则不会发生任何事情,因为数据库中的值仍然相同。我正在尝试更新“数据库”,在那里我保留了一些需要定期更改的值
  • 当您向托管 bean 发送请求时,您需要从托管 bean 查询数据库以获取最新结果。
  • 您要更新数据库吗?您是否希望使数据库与数据表保持同步,以防数据表中的内容发生更改?
  • 哦,我想我必须解释更多,是的,我需要查询数据库并将查询它,但我没有手动更新数据库,我从网页 html 中获取一些数据并输入这些值在我的数据库中。
  • 所以如果数据库是定期更新的,当页面加载时,表格会填充数据库的最后更新值
【解决方案2】:

在后台更新数据库不需要托管 bean。它都与服务器应该处理的业务逻辑有关。

您可以在上下文初始化期间或使用 Application Scoped Bean Post 构造方法启动 ScheduledExecutorService

查看 Scoped 数据表可以使用 db 中的最新更改进行刷新。

【讨论】:

    【解决方案3】:

    前段时间我也遇到过类似的问题,得出以下结论:

    至于在用户网络浏览器中自动更新页面,您可以使用 ajax。

    至于更新数据库,您有哪些选择取决于您工作的环境(web-server/servlet 容器和框架)。

    如果您使用 JPA 来完成数据库工作,那么您将需要获取无法注入到石英线程中的 EntityManager。同样在由石英管理的线程中,您将无法访问 JSF context(如果您使用它,也无法访问 CDI 上下文)。如果您在使用 EJB 3.1 的 Web 服务器上,那么您可以使用 @Schedule。这样,您将能够注入您的EntityManager 并获取 JSF/CDI 上下文,尽管它在调度方面并没有完成石英所做的所有事情。如果您直接连接到数据库,那么石英是一个非常好的选择。 如果您需要访问 JSF/CDI 上下文并且没有 EJB 3.1(或者如果您需要石英具有但 @Schedule 缺少的某些功能,那么您可以拥有一个调用 Web 服务的石英作业(例如 JAX -RS) 将访问上下文。

    总结一下:

    如果您需要 JPA 或 JSF/CDI 上下文并且可以使用@Schedule
    @Schedule 作业中更新数据库。

    如果您需要 JPA 但无法使用 @Schedule 或需要高级调度:
    设置一个调用网络服务并让网络服务更新数据库的石英作业。

    如果您直接连接到数据库:
    使用石英作业并直接从那里更新数据库。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-27
      • 2022-07-02
      • 2016-12-13
      • 1970-01-01
      • 2011-06-20
      • 1970-01-01
      相关资源
      最近更新 更多