How can server push asynchronous changes to a HTML page created by JSF?

后端 未结 4 947
轻奢々
轻奢々 2020-11-22 02:25

When we create a JSF page, a client request allows generation of HTML dynamically using a combination of Java code and HTML. Can we introduce hooks in the HTML page using JS

4条回答
  •  野性不改
    2020-11-22 03:11

    JSF 2.3+

    You can use @Push and for this. Below is a kickoff example which updates a data table upon an application scoped event fired by the backend.

    
        #{notification.message}
    
    
    
        
            
        
    
    

    @Named @ApplicationScoped
    public class Bean {
    
        private List notifications;
    
        @Inject
        private NotificationService service;
    
        @Inject @Push
        private PushContext push;
    
        @PostConstruct
        public void load() {
            notifications = service.list();
        }
    
        public void onNewNotification(@Observes Notification newNotification) {
            notifications.add(0, newNotification);
            push.send("updateNotifications");
        }
    
        public List getNotifications() {
            return notifications;
        }
    
    }
    

    @Stateless
    public class NotificationService {
    
        @Inject
        private EntityManager entityManager;
    
        @Inject
        private BeanManager beanManager;
    
        public void create(String message) {
            Notification newNotification = new Notification();
            newNotification.setMessage(message);
            entityManager.persist(newNotification);
            beanManager.fireEvent(newNotification);
        }
    
        public List list() {
            return entityManager
                .createNamedQuery("Notification.list", Notification.class)
                .getResultList();
        }
    
    }
    

    JSF 2.2-

    If you're not on JSF 2.3 yet, you need to head to 3rd party JSF libraries.

    • OmniFaces has (JSR356 WebSocket + CDI)
    • PrimeFaces has (Atmosphere)
    • ICEfaces has ICEpush (long polling)

    Noted should be that the was the basis for the JSF 2.3 . So if you have found a lot of similarities, then that's correct.

    PrimeFaces uses Atmosphere under the hoods (which is troublesome to setup without Maven). Atmosphere supports websockets with fallback to SSE and long polling. ICEfaces is based on ancient long polling technique. All of those do not implement native JSR356 WebSocket API which was only later introduced in Java EE 7.

    OmniFaces uses native JSR356 WebSocket API (supported in all Java EE 7 servers and Tomcat 7.0.27+). It is therefore also most simple to setup and use (one JAR, one context param, one tag and one annotation). It only requires CDI (not hard to install on Tomcat), but it enables you to even push from a non-JSF artifact on (e.g. a @WebServlet). For security and JSF view state keeping reasons, it only supports one-way push (server to client), not the other way round. For that you can keep using JSF ajax the usual way. The JSF 2.3 is largely based on OmniFaces , hence you'll find a lot of similarities in their APIs (JSF - OmniFaces).

    Alternatively, you can also use polling instead of pushing. Pretty much every ajax aware JSF component library has a component, such as PrimeFaces with . This allows you to send every X seconds an ajax request to the server and update the content whenever necessary. It's only less efficient than push.

    See also:

    • How to monitor asynchronous/background thread status and get notifications in a JSF component
    • Real time updates from database using JSF/Java EE
    • Notify only specific user(s) through WebSockets, when something is modified in the database

提交回复
热议问题