Xhtml page mapping from ManagedBean - spring

Here Is Managed Bean Class
package Controller;
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import Model.Employee;
#ManagedBean(name="employeeController")
#SessionScoped
public class Employeecontroller implements Serializable{
public String show(){
System.out.println("hello");
return "Login";
}
}
Here Is web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Secondproject</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>homepage.xhtml</welcome-file>
</welcome-file-list>
</web-app>
Here id home.xhtml page
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:rich="http://richfaces.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:h="http://java.sun.com/jsf/html">
<h:head></h:head>
<body>
<rich:panel>
<f:facet name="header">
Write your own custom rich components with built-in AJAX support
</f:facet>
<h:outputText value="Panel Body" />
<h:form>
<h:commandButton action="#{employeeController.show()}" value="Login" />
</h:form>
</rich:panel>
</body>
</html>
Here is the code for mapping xhtml page from ManagedBean.
I just want when the button is clicked then the login page will show....But when the button is clicked there is only home.xhtml page reloading...Login page is not loading....

The selection of the next view depends on the value of the action attribute of the UICommand components. If the navigation handler finds a navigation rule for this page with this outcome, the next view will be the element content. If there is no any rule like this it looks for a page with the value (or it appended with ".xhtml" file extension).
The variations:
1., Direct view definition:
<h:commandButton action="next_page_name"/>
It must be a full qualified name (page names + file name), but the xhtml could be omitted.
2., Indirect view definition:
In this case the action value is contains a bean method invocation:
<h:commandButton action="#{myBean.methodName}"/>
This method should be a function without any parameter and passes back a String value. This result will be the income for the navigation handler. It could return a page name or a navigation rule.
Now let us see your problem. If the name of your current view is id_home.xhml and you want to navigate to the login.xhtml page (both are in the x package):
1., Direct view definition. Return value "x/login" or "x/login.xhtml" from the show() method:
public String show()
{
//...
return "x/login";
}
2., Indirect view definition. Define a page navigation rule in the faces-config.xml like this:
<navigation-rule>
<from-view-id>/x/id_home.xhtml</from-view-id>
<navigation-case>
<from-outcome>go_to_login</from-outcome>
<to-view-id>x/login.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
In this case myBean.methodName passes back the content of the form-outcome element:
public String show()
{
//...
return "go_to_login";
}

Related

JSF xhtml page not found

I've been trying to follow various articles on setting up my first JSF application and can't get my first xhtml page to be found. I keep getting the error "This application has no explicit mapping for /error, so you are seeing this as a fallback" in the browser.
In the browser, I type http://localhost:8080/modelSimulation.xhtml to get this error, and in the console, I see:
... :GET "/modelSimulation.xhtml", parameters={}
... :No mapping for GET /modelSimulation.xhtml
My spring boot application has added the various things required to setup JSF with spring boot, but clearly I'm missing something to be able to view my modelSimulation.xhtml page. What am I missing? Thanks!
I also tried http://localhost:8080 but get corresponding no mapping error too.
src/main/webapp/WEB-INF/modelSimulation.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<ui:composition template="layout.xhtml">
<ui:define name="content">
<h:form id="mainForm">
<p:panel header="Details">
<h:panelGrid columns="1">
<p:outputLabel for="symbol" value="Symbol: " />
<p:inputText id="symbol" value="#{tradingModelSimulationController.symbol}" />
<p:outputLabel for="ranking" value="ranking: " />
<p:inputNumber id="ranking" value="#{tradingModelSimulationController.ranking}" />
<h:commandButton value="apply" action="#{tradingModelSimulationController.apply}" />
</h:panelGrid>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
</html>
src/main/webapp/WEB-INF/web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="3.1">
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
</web-app>
I added the 2 required beans to the SpringBootApplication class:
#Bean
public ServletRegistrationBean servletRegistrationBean() {
FacesServlet servlet = new FacesServlet();
return new ServletRegistrationBean(servlet, "*.jsf");
}
#Bean
public FilterRegistrationBean rewriteFilter() {
FilterRegistrationBean rwFilter = new FilterRegistrationBean(new RewriteFilter());
rwFilter.setDispatcherTypes(EnumSet.of(DispatcherType.FORWARD, DispatcherType.REQUEST,
DispatcherType.ASYNC, DispatcherType.ERROR));
rwFilter.addUrlPatterns("/*");
return rwFilter;
}
Here's the backing bean (I don't understand the #Join...)
#Scope(value = "session")
#Component(value = "tradingModelSimulationController")
#ELBeanName(value = "tradingModelSimulationController")
#Join(path = "/modelSimulation", to = "/modelSimulation.jsf")
public class TradingModelSimulationController {
ModelSimulation modelSimulation = new ModelSimulation();
String symbol;
int ranking;
public void apply() {
System.out.println("Applied: " + modelSimulation.toString());
RequestContext.getCurrentInstance()
.execute("handleMsg('applied!');");
}
public ModelSimulation getModelSimulation() {
return modelSimulation;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public int getRanking() {
return ranking;
}
public void setRanking(int ranking) {
this.ranking = ranking;
}
}

JSF 2 Managed bean concurrent access between logged in users

Basic example to showcase my problem :
Two users A and B connect to the JSF web app from different browsers, and the welcoming page shows their documents and a search panel.
Both of them want to search for documents using a word or sentence.
(for instance) A wants to search for the word "sheets" and B wants to search for the word "virus".
They write down the word in the form input and they simultaneously submit the form.
A gets the result of her search, while B suddenly gets also the same result as A with a word he didn't type which is "sheets".
Here's my managedBean :
#ManagedBean
#RequestScoped
public class DocumentController implements Serializable {
private String motSearch= null;
private boolean searching = false;
private boolean rechercheStructure = true;
private DocumentDao dao; //Dependency injection with Spring
public void onload(Utilisateur user)
{
if(!searching)
{
motSearch = null;
documentsListForConnectedUser(user);
}
else{
search(user);
}
}
public void search(Utilisateur user)
{
documentsListForConnectedUser(user);// getting documents list from database
searching = true;
List<Document> list = new ArrayList<>();
list.addAll(user.getDocuments());
user.setDocuments(new ArrayList<>());
//...
if(motSearch != null && !motSearch.isEmpty())
{
LOGGER.info("motSearch : "+motSearch.toLowerCase());
List<Document> docs = user.getDocuments();
for(Document doc : list)
{
if(!docs.contains(doc) && (doc.getNom().toLowerCase().contains(motSearch.toLowerCase()) ||
doc.getDescription().toLowerCase().contains(motSearch.toLowerCase()) ||
doc.getTheme().toLowerCase().contains(motSearch.toLowerCase()) ||
doc.getKeywords().contains(motSearch.toLowerCase())))
{
docs.add(doc);
}
}
docs = filter(docs);
if(docs.size() == 0)
{
user.setDocuments(null);
}
}
else
{
user.setDocuments(list);
}
}
}
The JSF page ListeDocuments.xhtml :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<f:metadata>
<f:viewParam name="searching" value="#{documentController.searching}" />
<f:viewParam name="structure" value="#{documentController.rechercheStructure}"/>
<f:viewParam name="q" value="#{documentController.motSearch}"/>
<f:viewAction action="#{documentController.onload(user)}"/>
</f:metadata>
</h:head>
<h:body>
<h:form id="myForm" prependId="false" >
<h:inputHidden value="true" id="searching"/>
<div class="center">
<h:selectOneRadio converter="javax.faces.Boolean"
value="#{documentController.rechercheStructure}" onchange="check()" id="structure">
<f:selectItem itemLabel="Recherche structurée" itemValue="true" />
<f:selectItem itemLabel="Recherche plein texte" itemValue="false" />
</h:selectOneRadio>
</div>
<div class="row">
<div class="input-field col s12 m7 l8">
<p:inputTextarea styleClass="materialize-textarea" id="q" value="#{documentController.motSearch}"/>
<label for="q">Mot/phrase à chercher</label>
</div>
</div>
<p:commandButton styleClass="btn blue-grey" update=":table"
type="submit" value="Chercher"
action="ListeDocuments?faces-redirect=true&includeViewParams=true" />
</h:form>
<p:dataTable id="table" tableStyleClass="hoverable striped" rows="10" paginator="true"
value="#{user.documents}" var="doc"
paginatorPosition="bottom" paginatorAlwaysVisible="false" styleClass="borderless">
<!--Columns-->
</p:dataTable>
</h:body>
</html>
My web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/serverError.xhtml</location>
</error-page>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/serverError.xhtml</location>
</error-page>
<!-- Add Support for Spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<context-param>
<param-name>primefaces.THEME</param-name>
<param-value>none</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
</web-app>
faces-config.xml file :
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
PS : I'm using :
Mojarra 2.2.9 JSF implementation.
Apache Tomcat 7 server with Servlet 3.0.
Spring but I only use it to inject interface implementations like DAOs.
Hibernate 4/JPA as ORM.
Since I needed to use Omnifaces 2.4 library for its converters I was obliged to integrate CDI (weld-servlet-2.3.5 final) and create an empty beans.xml (guidelines from BalusC blog), and I don't use any of its annotations in my managedBeans.
The only annotations I use are #ManagedBean and #xxxxScoped from javax.faces.bean and sometimes #PostConstruct.
Finally Primefaces 6.0
Any help is appreciated !

JSF 2 value not getting parsed in XHTML

I am new to JSF 2 and trying to build simple hello world app.Created maven project in Eclipse Luna with maven-archetype-webapp.
Following is my files :
web.xml :
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
HelloWorld.java :
#ManagedBean(name = "helloWorld", eager = true)
public class HelloWorld {
public HelloWorld() {
System.out.println("HelloWorld started!");
} public String getMessage() {
return "Hello World!";
}
home.xhtml :
<body>
<h1>HI....!!!</h1>
#{helloWorld.message}
<h:outputLabel value="#{helloWorld.message}" />
<h1>END....!!!</h1>
</body>
</html>
When i run, my home.xhtml prints HI....!!! and END...!!!,but nothing else.
I have searched in SO and googled. I found solutions but unfortunately, i am unable to solve it.
Some explanations on your current code:
#ManagedBean defines a managed bean to be used in Facelets by JSF. The attribute eager only applies for #ApplicationScoped beans, and your managed bean doesn't have such scope.
In JSF 2, if you don't define a scope for your bean, then it's #RequestScoped by default.
Looks like your html doesn't use any Facelets code. This is how your home.xhtml should be:
<!-- HTML5 header -->
<!DOCTYPE html>
<!-- define f: and h: usage in the current page -->
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<!-- JSF will include some js files for ajax functionality -->
<h:head>
<!-- this is optional -->
<title>Home</title>
</h:head>
<!-- use <h:body> for the content of your page -->
<h:body>
<h1>HI....!!!</h1>
#{helloWorld.message}
<!--
<h:outputLabel> will render a <label> and
this component should not be used to print
direct text on html but to label other HTML components
instead, use <h:outputText>
-->
<h:outputText value="#{helloWorld.message}" />
<h1>END....!!!</h1>
</h:body>
</html>

Spring Injection + JSF + Hibernate

I'm actually starting with JSF, so go easy.
I'm trying to mix Spring 3.x + Hibernate 4 + JSF 2.2
I used to mix Spring + Hibernate in Desktop applications, and that wasn't a problem at all.
But now, I'm a little confused here.
I'm trying to map through annotations and I'm pretty sure that is a mess.
First of all, I'd like to ask you the best practice to Integrate all those technologies and keep the MVC pattern
That being said, here are my files:
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>WebCD</display-name>
<!-- Spring Config -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/Spring/context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
</web-app>
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
version="2.0">
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
AppMainController.java
#Controller
public class AppMainController {
#Autowired
private CDDao cdDao;
public List<CD> findAllCDs() throws SQLException {
List<CD> cds = cdDao.findAll();
return cds;
}
}
CDDaoImpl.java
#Repository
public class CDDaoImpl extends Dao<CD> implements CDDao {
#Override
public Class<CD> getEntityClass() {
return CD.class;
}
}
And, finally, the *.xhtml file:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Lista de CDs</title>
</h:head>
<h:body>
<center>
<h1>Lista de CDS</h1>
</center>
<h:messages />
<h:dataTable value="#{/*Right here I really don't know what to call*/.findAllCDs()}" var="cd"
rules="rows" cellpadding="5">
<f:facet name="caption">Essa é a lista de todos os CD's cadastrados no sistema</f:facet>
<f:facet name="header">Lista de CD's</f:facet>
<f:facet name="footer">Fim da Lista de CD's</f:facet>
<h:column>
<f:facet name="header">Código</f:facet>
#{cd.id}
</h:column>
<h:column>
<f:facet name="header">Descrição</f:facet>
#{cd.descricao}
</h:column>
<h:column>
<f:facet name="header">Gravadora</f:facet>
#{cd.fkLabel}
</h:column>
<h:column>
<f:facet name="header">Preço</f:facet>
#{cd.preco}
</h:column>
<h:column>
<f:facet name="header">Data Compra</f:facet>
#{cd.dataCompra}
</h:column>
<h:column>
<f:facet name="header">Data Gravação</f:facet>
#{cd.dataGravacao}
</h:column>
</h:dataTable>
</h:body>
</html>
I've tried these approaches:
Add #ManagedBean(name="ctrl") to the AppMainController and call ctrl.findAllCDs().
Create a property private List<CD> cds and a method calling cdDao.findAll() to fill the list and retrieve to the dataTable as myBean.cds.
These were the following exceptions:
NullPointerException: cdDao was null at some points, which leads me to consider the only logical inference: cdDao is not being injected (Autowired)
#ManagedBean was not in the right place..
I'd be grateful if you could show me a guideline, a path, because I'm really confused.
After changing #ManagedBean for #Named("name") and #Autowired for #Inject, the problem was solved.

PrimePush chat is not working

my target is on page load to subscribe two users in chat (teacher and student), and they can send messages to each others, so here's what i did:
1- BackingBean:
package com.myapp.beans;
import org.primefaces.context.RequestContext;
import org.primefaces.push.PushContext;
import org.primefaces.push.PushContextFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.ocpsoft.pretty.faces.annotation.URLMapping;
import com.xeno.xenoTemplate.utils.constants.Pages;
#Component("chatBean")
#Scope("view")
#URLMapping(id = Pages.CHAT, pattern = "/chat", viewId = "/faces/pages/users/chat.xhtml")
public class ChatView {
private final PushContext pushContext = PushContextFactory.getDefault()
.getPushContext();
private String privateMessage;
private String privateUser;
private final static String CHANNEL = "/chat/";
private String student = "student";
private String teacher = "teacher";
private boolean pageLoaded;
private boolean studentLoggedIn;
private boolean teacherLoggedIn;
public void preRender() {
System.out.println("########### preRender CHAT BEAN #########");
if (!pageLoaded) { // invoked first time page loaded
System.out.println("########### Invoking PreRender Code #########");
if (!studentLoggedIn) {
System.out.println("########## STUDENT LOG IN ##########");
RequestContext.getCurrentInstance().execute(
"subscriber.connect('/" + student + "')");
studentLoggedIn = true;
}
if (!teacherLoggedIn) {
System.out.println("########## TEACHER LOG IN ##########");
RequestContext.getCurrentInstance().execute(
"subscriber.connect('/" + teacher + "')");
teacherLoggedIn = true;
}
pageLoaded = true;
}
}
public void sendPrivate() {
System.out.println("######### SEND PRIVATE ##########");
pushContext.push(CHANNEL + privateUser, "[PM] " + "PRIVATE" + ": "
+ privateMessage);
privateMessage = null;
}
public void setTeacher(String teacher) {
this.teacher = teacher;
}
public String getTeacher() {
return teacher;
}
public void setStudent(String student) {
this.student = student;
}
public String getStudent() {
return student;
}
public void setStudentLoggedIn(boolean studentLoggedIn) {
this.studentLoggedIn = studentLoggedIn;
}
public boolean isStudentLoggedIn() {
return studentLoggedIn;
}
public void setTeacherLoggedIn(boolean teacherLoggedIn) {
this.teacherLoggedIn = teacherLoggedIn;
}
public boolean isTeacherLoggedIn() {
return teacherLoggedIn;
}
public String getPrivateUser() {
return privateUser;
}
public void setPrivateUser(String privateUser) {
this.privateUser = privateUser;
}
public String getPrivateMessage() {
return privateMessage;
}
public void setPrivateMessage(String privateMessage) {
this.privateMessage = privateMessage;
}
}
and in the JSF page:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ice="http://www.icesoft.com/icefaces/component"
xmlns:p="http://primefaces.org/ui"
xmlns:pretty="http://ocpsoft.com/prettyfaces"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:sec="http://www.springframework.org/security/tags"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
<title>Chat</title>
</h:head>
<h:body>
<ui:composition template="/pages/template/commonLayout.xhtml">
<ui:define name="content">
<f:event type="preRenderView" listener="#{chatBean.preRender}" />
<h:form id="form">
<p:fieldset id="container" legend="PrimeChat" toggleable="true">
<h:panelGroup>
<h:panelGrid columns="2" columnClasses="publicColumn,usersColumn"
style="width:400px;">
<p:outputPanel style="height: 100px;" id="public" layout="block"
styleClass="ui-corner-all ui-widget-content chatlogs" />
<h:panelGroup id="users" styleClass="usersList">
<p:commandButton id="private_send" title="Chat" icon="ui-icon-comment"
oncomplete="pChat.show()" update=":form:privateChatContainer">
<f:setPropertyActionListener value="#{chatBean.student}"
target="#{chatBean.privateUser}" />
</p:commandButton>
#{chatBean.student}
</h:panelGroup>
</h:panelGrid>
</h:panelGroup>
</p:fieldset>
<!-- Private Chat Dialog -->
<p:dialog widgetVar="pChat" header="Private Chat" modal="true"
showEffect="fade" hideEffect="fade">
<h:panelGrid id="privateChatContainer" columns="2"
columnClasses="vtop,vtop">
<p:outputLabel for="pChatInput"
value="To: #{chatBean.privateUser}" />
<p:inputTextarea id="pChatInput"
value="#{chatBean.privateMessage}" rows="5" cols="30" />
<p:spacer />
<p:commandButton value="Send"
actionListener="#{chatBean.sendPrivate}"
oncomplete="pChat.hide()" />
</h:panelGrid>
</p:dialog>
</h:form>
<p:socket onMessage="handleMessage" channel="/chat"
autoConnect="false" widgetVar="subscriber" />
<script type="text/javascript">
function handleMessage(data) {
alert('handleMessage');
var chatContent = $(PrimeFaces
.escapeClientId('form:public'));
chatContent.append(data + '<br />');
chatContent.scrollTop(chatContent.height());
}
</script>
</ui:define>
</ui:composition>
</h:body>
</html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>MyAPP</display-name>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:META-INF/spring/applicationContext.xml
classpath:META-INF/spring/applicationSecurity.xml
</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>
/WEB-INF/springsecurity.taglib.xml;/WEB-INF/utils.taglib.xml
</param-value>
</context-param>
<context-param>
<param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
<param-value>false</param-value>
</context-param>
<!-- -->
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<welcome-file-list>
<welcome-file>/</welcome-file>
</welcome-file-list>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name>
<param-value>resources.application</param-value>
</context-param>
<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!-- Spring Security -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>
org.springframework.web.filter.DelegatingFilterProxy
</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<!--
<filter>
<filter-name>Pretty Filter</filter-name>
<filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class>
<init-param>
<param-name>logLevel</param-name>
<param-value>ERROR</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Pretty Filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
-->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error</location>
</error-page>
<error-page>
<error-code>400</error-code>
<location>/error</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/pageNotFound</location>
</error-page>
<!-- PrimePush Servlet -->
<servlet>
<servlet-name>Push Servlet</servlet-name>
<servlet-class>org.primefaces.push.PushServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterCacheClass</param-name>
<param-value>org.atmosphere.cache.HeaderBroadcasterCache</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcasterClass</param-name>
<param-value>org.atmosphere.cpr.DefaultBroadcaster</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.broadcastFilterClasses</param-name>
<param-value>org.atmosphere.client.TrackMessageSizeFilter</param-value>
</init-param>
<init-param>
<param-name>org.atmosphere.cpr.sessionSupport</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Push Servlet</servlet-name>
<url-pattern>/primepush/*</url-pattern>
</servlet-mapping>
</web-app>
i am using the following jars:
JSF 2.1.10
PrimeFaces 4.0-SNAPSHOT
Tomcat 7.0.32
atmosphere-runtime 1.0.1
HEADERS
Request URL:http://localhost:8080/MyAPP/chat
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:application/xml, text/xml, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:282
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
Cookie:JSESSIONID=2BB4298A4E291CCCBB80EE3A4A5624BC
Faces-Request:partial/ajax
Host:localhost:8080
Origin:http://localhost:8080
Referer:http://localhost:8080/PrimeTemplate/chat
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11
X-Requested-With:XMLHttpRequest
Form Dataview URL encoded
javax.faces.partial.ajax:true
javax.faces.source:form:j_idt31
javax.faces.partial.execute:#all
form:j_idt31:form:j_idt31
form:form
form:j_idt24:
form:container_collapsed:false
form:pChatInput:aaaaaaaaaaaa
javax.faces.ViewState:5079906166114901626:-433970771510989466
Response Headersview source
Cache-Control:no-cache
Content-Length:190
Content-Type:text/xml;charset=UTF-8
Date:Thu, 18 Oct 2012 10:40:04 GMT
Server:Apache-Coyote/1.1
X-Powered-By:JSF/2.0
RESPONSE:
<?xml version='1.0' encoding='UTF-8'?>
<partial-response><changes><update id="javax.faces.ViewState"><![CDATA[5079906166114901626:-433970771510989466]]></update></changes></partial-response>
ISSUE:
i can open the chat window for the student and type a chat message then press enter, the code gets in the sendPrivate bean method, but the JS handleMessage function is not called and hence the private message is not displayed in the JSF page, i get no errors in browser console.
please advise how to fix that.
Try to add following jars to your lib folder (if you havent already done that):
atmosphere-compat-tomcat-1.0.1.jar
atmosphere-compat-tomcat7-1.0.1.jar
Also have in mind that if you are connected as STUDENT to the "student" channel and if you are pushing message to "teacher" channel, only teacher's channel will receive a message.
To test your chat, you need to login as student in one browser and as teacher in another browser. In this case, when you push message as student to the teacher in one browser, teacher in another browser will receive the message.

Resources