JSFWebSocket更新视图范围

JSFWebSocket更新视图范围,jsf,jsf-2.3,Jsf,Jsf 2.3,我有一个名为sampleBean的bean,其作用域是viewScope。 这个bean从数据库MySQL加载一些数据。 我的问题是一些用户之间共享的记录。 现在可能[USER A]删除了那个共享记录,我想更新其他用户的视图 我无法将作用域更改为ApplicationScope,因为所有记录都共享给所有用户 如何解决这个问题? 注意:我读了这篇文章,但不明白如何解决这个问题。 注意:我使用JavaEE8WebProfile提供的Liberty 18.0.0.4,通过这个简单的代码解决了这个问题。

我有一个名为sampleBean的bean,其作用域是viewScope。 这个bean从数据库MySQL加载一些数据。 我的问题是一些用户之间共享的记录。 现在可能[USER A]删除了那个共享记录,我想更新其他用户的视图

我无法将作用域更改为ApplicationScope,因为所有记录都共享给所有用户

如何解决这个问题? 注意:我读了这篇文章,但不明白如何解决这个问题。 注意:我使用JavaEE8WebProfile提供的Liberty 18.0.0.4,通过这个简单的代码解决了这个问题。我为你分享了这个代码

这是一个简单的服务。我在这门课上模拟了数据库

@Stateless
public class InformationService {

    private static final List<Information> db = new ArrayList<>();

    @Inject
    @Push(channel = "infoChannel")
    PushContext push;

    @PostConstruct
    public void init() {
        Information userA = new Information("John", "Vankate");
        Information userB = new Information("Julius", "Sampao");
        db.add(userA);
        db.add(userB);
    }

    public void remove(Information info) {
        db.remove(info);
        push.send("deleteInfo");
    }

    public List<Information> findAll() {
        return db;
    }
}
现在启动JSF:

@Named
@ViewScoped
public class InformationBean implements Serializable {

    private Information info ;
    private List<Information> informationList ;

    @EJB
    private InformationService informationService ;


    @PostConstruct
    public void init() {
        informationList = informationService.findAll();
        info = new Information() ;
    }

    public void deleteInformation() {
        informationService.remove(info);
    }

    public Information getInfo() {
        return info;
    }

    public void setInfo(Information info) {
        this.info = info;
    }

    public List<Information> getInformationList() {
        return informationList;
    }

    public void setInformationList(List<Information> informationList) {
        this.informationList = informationList;
    }
}
和xhtml:

<h:body>
    <p:dataTable value="#{informationBean.informationList}" var="info" id="infoTable">
        <p:column rowHeader="name">
            <h:outputText value="#{info.name}"/>
        </p:column>
        <p:column rowHeader="family">
            <h:outputText value="#{info.family}"/>
        </p:column>
        <p:column rowHeader="action">
            <h:form>
                <p:commandButton value="Delete" action="#{informationBean.deleteInformation}">
                    <f:setPropertyActionListener value="#{info}" target="#{informationBean.info}"/>
                </p:commandButton>
            </h:form>
        </p:column>
    </p:dataTable>
    <hr/>
    <f:websocket channel="infoChannel">
        <p:ajax event="deleteInfo" update="infoTable"/>
    </f:websocket>
</h:body>
我已经想到,PushContext必须在JSFbean上实现,现在我知道可以在服务或业务逻辑层实现它。 现在您可以从JAXRSRESTAPI中删除信息,并从p:dataTable中删除记录,而无需刷新页面。
注意:此示例使用@ViewScoped

将范围更改为@ApplicationScoped不会解决任何问题。正如您链接到的帖子所讨论的,您可以使用f:websocket来完成上述要求。这个标签需要JSF2.3。要使其与Liberty一起工作,请参阅。另外,如果你能为我们提供一个覆盖你的案例的例子,也许是一个只提供随机数据的支持bean,我们可以为你提供一个具体案例的例子。我修复了这个问题,JSF中的@Observer使用了不好的cased@mah454:这个问题在当前状态下对其他人来说是无用的,因为它不清楚代码的味道是什么以及应该做什么更改。你能改进它并创建一个好的对应答案吗?@Kukeltje,我回答了我的问题,请投赞成票:DSorry,不,投反对票。见评论。答案不是正确的做法,甚至有点错误,而且问题中没有相应的代码,因此其他人很难看出错误所在。添加前端技术推送后端服务是一种不好的做法。您发布的链接包含正确操作的信息,我一直在使用它,因为您没有发布您在我们无法帮助之前尝试过的内容,因此此Q/A有点有用。如果从webservice Rest或soap收到请求,您是否更新视图?响应应该来自服务。tbat服务的实现应该对调用或依赖服务隐藏。对于调用方的回调,使用观察者;艾克张贴在link@Kukeltje@Observer未使用ViewScope bean。如何解决此问题?如何不使用viewscoped bean?请做一个示例,您是否真的需要与“推送”相关的bean成为viewsoped bean?
@Named
@ViewScoped
public class InformationBean implements Serializable {

    private Information info ;
    private List<Information> informationList ;

    @EJB
    private InformationService informationService ;


    @PostConstruct
    public void init() {
        informationList = informationService.findAll();
        info = new Information() ;
    }

    public void deleteInformation() {
        informationService.remove(info);
    }

    public Information getInfo() {
        return info;
    }

    public void setInfo(Information info) {
        this.info = info;
    }

    public List<Information> getInformationList() {
        return informationList;
    }

    public void setInformationList(List<Information> informationList) {
        this.informationList = informationList;
    }
}
<h:body>
    <p:dataTable value="#{informationBean.informationList}" var="info" id="infoTable">
        <p:column rowHeader="name">
            <h:outputText value="#{info.name}"/>
        </p:column>
        <p:column rowHeader="family">
            <h:outputText value="#{info.family}"/>
        </p:column>
        <p:column rowHeader="action">
            <h:form>
                <p:commandButton value="Delete" action="#{informationBean.deleteInformation}">
                    <f:setPropertyActionListener value="#{info}" target="#{informationBean.info}"/>
                </p:commandButton>
            </h:form>
        </p:column>
    </p:dataTable>
    <hr/>
    <f:websocket channel="infoChannel">
        <p:ajax event="deleteInfo" update="infoTable"/>
    </f:websocket>
</h:body>