I would like to have my Spring MVC application mapped to the following extension *html for jsp and *.action for controllers.
this is for login page:
#RequestMapping(value="/login.html", method=RequestMethod.GET)
public ModelAndView login(){
ModelAndView mv = new ModelAndView("login/login");
//omitted
return mv;
}
and this is for action:
#RequestMapping(value="/login.action", method=RequestMethod.POST)
public ModelAndView actionSignUp(#Valid User user){
//omitted
return mv;
}
and jsp is simple:
<form:form method="POST" action="/login.action" commandName="user" >
<form:input path="userName" id="userName" /><br />
<form:input path="password" id="password"/><br />
<input id ="login" type="submit" value="Login"></input>
</form:form>
my web.xml is the following:
<display-name>SpringMVC</display-name>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
I have no problem to get /login.html, but I have a problem with POST request on /login.action
I'm getting
HTTP Status 404 - /login.action
Why my mapping for *.action is not working?
Can I map two different extensions *html and *.action ?
The action method in your form was defined as action="/login.action". The / makes the url relative to your domain. You should notice that the form posted to a url similar to http://localhost:8080/login.action which should be http://localhost:8080/[context root]/[sub dir if defined]/login.action
I recon that removing the '/' will fix it.
Related
Hi I am getting following error in spring MVC PUT example
Aug 14, 2017 12:28:57 PM org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver handleHttpRequestMethodNotSupported
WARNING: Request method 'PUT' not supported
on following form
<form:form action="../${user.id}" method="PUT" commandName="user">
<div class="form-group">
<label for="txtUserName">User-name</label>
<form:input path="userName" class="form-control" id="txtUserName"
placeholder="User Name" />
</div>
<div class="form-group">
<label for="txtName">First Name</label>
<form:input path="name" class="form-control" id="txtName"
placeholder="Full Name" />
</div>
<div class="form-group">
<label for="calDob">Date of Birth</label>
<form:input path="dateOfBirth" class="form-control" id="calDob"
placeholder="dd/MM/yyyy" />
</div>
<input type="hidden" name="_method" value="PUT">
<input type="submit" class="btn btn-success" value="SAVE">
</form:form>
with controller
#GetMapping(path = "/{id}/edit")
public String editUser(#PathVariable(value = "id") Long id, Model model) {
model.addAttribute("user", userService.findById(id));
return "user/edit";
}
#PutMapping(path = "/{id}/edit")
public String updateUser(#PathVariable(value = "id") long id, #ModelAttribute("user") User user, Model model) {
userService.updateUser(user);
model.addAttribute("user", userService.findById(id));
LOG.info("" + user.toString());
return "redirect:/users/" + id;
}
with following web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>httpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>httpMethodFilter</filter-name>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
<filter>
<filter-name>httpPutFormFilter</filter-name>
<filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>httpPutFormFilter</filter-name>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
can you please guide me how to solve this error.
And if you need more information, let me know.
Thanks :)
EDIT User.java
public class User {
private Long id;
private String name;
private String userName;
private String password;
private Date dateOfBirth;
public User() {
}
public User(Long id, String name, String userName, String password, Date dateOfBirth) {
super();
this.id = id;
this.name = name;
this.userName = userName;
this.password = password;
this.dateOfBirth = dateOfBirth;
}
//getters setters ommitted
}
Your put mapping expects 'edit' in the end #PutMapping(path = "/{id}/edit") but your form's action <form:form action="../${user.id}" does not have the edit so the controller can't intercept the action.
I'm practicing how to include ajax in spring-mvc with an example that I took from Internet but it doesn't work. I think that the problem is that I'm not able to run two servlets in the same xml but i don't know how to solve it.
Here is my xml code:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 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_1.xsd">
<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>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>JsonServlet</servlet-name>
<servlet-class>controladores.JsonServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>JsonServlet</servlet-name>
<url-pattern>/JsonServlet</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>redirect.jsp</welcome-file>
</welcome-file-list>
</web-app>
This is my jsp code with javascript:
<html>
<head>
<title>AJAX in Servlet using JQuery and JSON</title>
<script src="js/jquery-1.11.1.js" type="text/javascript"></script>
<script>
$(document).ready(function() {
$('#sports').change(function(event) {
var sports = $("select#sports").val();
$.get('JsonServlet', {
sportsName : sports
}, function(response) {
var select = $('#player');
select.find('option').remove();
$.each($(foo), function(index, value) {
$('<option>').val(value).text(value).appendTo(select);
});
});
});
});
</script>
</head>
<body>
<h3>AJAX in Servlet using JQuery and JSON</h3>
Select Favorite Sports:
<select id="sports">
<option>Select Sports</option>
<option value="Football">Football</option>
<option value="Cricket">Cricket</option>
</select>
<br /> <br />
Select Favorite Player:
<select id="player">
<option>Select Player</option>
</select>
</body>
</html>
And this is my controller:
public class JsonServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String sportsName = request.getParameter("sportsName");
List<String> list = new ArrayList<String>();
String json = null;
if (sportsName.equals("Football")) {
list.add("Lionel Messi");
list.add("Cristiano Ronaldo");
list.add("David Beckham");
list.add("Diego Maradona");
} else if (sportsName.equals("Cricket")) {
list.add("Sourav Ganguly");
list.add("Sachin Tendulkar");
list.add("Lance Klusener");
list.add("Michael Bevan");
} else if (sportsName.equals("Select Sports")) {
list.add("Select Player");
}
json = new Gson().toJson(list);
response.setContentType("application/json");
response.getWriter().write(json);
}
}
When I try to put only the JsonServlet appears this error: invalid path was requested.
And when I try to run the two servlets at the same time the application never goes through the controller.
Why you are using spring dispatcherServlet, but write the raw servlet by yourself?
I'm new to Struts2, just finished a no action mapped issue, my action new will be execute, but while it return to JSP, there is always 404. Tried to set namespace and result like following, but still don't get it work.
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<constant name="struts.convention.result.path" value="/WebContent/jsp/" />
<package name="default" extends="json-default">
<action name="testAction" class="tw.com.rrstudio.java.test.TestAction" method="execute">
<result name="login">index.jsp</result>
<result name="success">TestAction.jsp</result>
</action>
</package>
</struts>
Also tried remove convention result path and set result as this
<package name="default" extends="json-default">
<action name="testAction" class="tw.com.rrstudio.java.test.TestAction" method="execute">
<result name="login">/jsp/index.jsp</result>
<result name="success">/jsp/TestAction.jsp</result>
</action>
</package>
But still gives 404.
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>Struts2Test</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-context.xml
/WEB-INF/spring-mvc.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<init-param>
<param-name>actionPackages</param-name>
<param-value>tw.com.rrstudio.java.test</param-value>
</init-param>
</filter>
<jsp-config>
<taglib>
<taglib-uri>HTTP://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/lib/tld/c.tld</taglib-location>
</taglib>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
</jsp-property-group>
</jsp-config>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>10</session-timeout>
</session-config>
</web-app>
my action java code
package tw.com.rrstudio.java.test;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.interceptor.ServletRequestAware;
import com.opensymphony.xwork2.ActionSupport;
public class TestAction extends ActionSupport implements ServletRequestAware
{
private static final long serialVersionUID=1L;
public HttpServletRequest request;
private String name="";
public String execute() throws Exception
{
System.out.println("Debug: name="+name);
System.out.println("Debug: path="+request.getContextPath());
System.out.println("Debug: path="+request.getServletContext().getRealPath("/"));
if(name!=null && !"".equals(name))
{return "success";}
else
{return "login";}
}
#Override
public void setServletRequest(HttpServletRequest request)
{this.request=request;}
public String getName()
{return name;}
public void setName(String name)
{this.name=name;}
}
While I call my action, it do printed debug message like this,
http://127.0.0.1:8080/Struts2Test/testAction.action
Debug: name=
Debug: path=/Struts2Test
Debug: path=D:\eclipse\workspace2.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Struts2Test\
http://127.0.0.1:8080/Struts2Test/testAction.action?name=XYZ
Debug: name=XYZ
Debug: path=/Struts2Test
Debug: path=D:\eclipse\workspace2.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\Struts2Test\
but always give me a 404 page, and no any message.
HTTP Status 404 -
type Status report
message
description The requested resource is not available.
BTW, here's my package structure.
+Struts2Test
+Struts2Test/src
+tw.com.rrstudio.java.test
-Struts2Test/src/tw/com/rrstudio/java/test/TestAction.java
+Struts2Test/build
+Struts2Test/WebContent
+Struts2Test/WebContent/img
+Struts2Test/WebContent/jsp
-Struts2Test/WebContent/jsp/error.jsp
-Struts2Test/WebContent/jsp/index.jsp
-Struts2Test/WebContent/jsp/TestAction.jsp
+Struts2Test/WebContent/META-INF
+Struts2Test/WebContent/WEB-INF
+Struts2Test/WebContent/WEB-INF/classes
-Struts2Test/WebContent/WEB-INF/classes/logging.properties
-Struts2Test/WebContent/WEB-INF/classes/struts.xml
+Struts2Test/WebContent/WEB-INF/lib
-Struts2Test/WebContent/WEB-INF/spring-context.xml
-Struts2Test/WebContent/WEB-INF/spring-mvc.xml
-Struts2Test/WebContent/WEB-INF/struts2-action.xml
-Struts2Test/WebContent/WEB-INF/web.xml
Please give any tips or suggestions, I appreciate for your help.
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 !
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.