I got a problem with JSF 1.2 on websphere 7.
I'm trying to implement a navigation with JSF.
I'm also using RichFaces.
In the console of the browser I got this error: Uncaught ReferenceError: mojarra is not defined
I have seen other with this problem and they solved it with adding <h:head> but this didn't work for me.
Thank you for helping
My navigation.xhtml
<?xml version="1.0" ?>
<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:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition>
<h:form>
<!-- Navigation -->
<div id="navigation" class="navigation">
<div class="level0">
<h:commandLink action="#{navigation.toHome}" value="#{messages.elsi_dg_navigation_home}" />
</div>
<div class="level0">
<h:commandLink action="#{navigation.toHistory}" value="#{messages.elsi_dg_navigation_history}" />
</div>
</div>
</h:form>
</ui:composition></body></html>
The NavigationBean.java
#Controller("navigation")
#Scope("session")
#ManagedBean
public class NavigationBean {
private String lastSite = "home";
public String toHome() {
return this.processOutcome("home");
}
public String toHistory() {
return this.processOutcome("history");
}
public String toCurrentPage() {
return this.lastSite;
}
private String processOutcome(String outcome) {
this.lastSite = outcome;
return outcome;
}
}
HTML output:
<div id="navigation" class="navigation">
<form id="j_id19" name="j_id19" method="post" action="/elsi-dg/xhtml/home.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_id19" value="j_id19">
<!-- Navigation -->
<div id="navigation" class="navigation">
<div class="level0">Home</div>
<div class="level0">History</div>
</div><input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="3428583661652779493:-8865896015881316410" autocomplete="off">
</form>
</div>
UPDATE
<a4j:commandLink> works without problems..
Maybe the problem is with the tag ui:compostion
<ui:composition template="./template/template.xhtml">
It normally needs a template file.
Are you using one?
If you aren't, try to remove the <ui:composition> tag.
Related
I started to work with thymeleaf in a basic project. When I want to display a message in the sign up page the th:text does not work. I used already th:text in other .html files and it works there but in the signUp.html doesn't.
Here is my controller where I set the message:
package com.teszt.thymeleaftest.controller;
#Controller
#RequestMapping("/login")
#AllArgsConstructor
public class MemberController {
MembersService membersService;
#GetMapping("/login")
public String showLoginPage(){
return "/login/login";
}
#GetMapping("/signUp")
public String showSignUpPage(Model theModel){
Members theMember = new Members();
theModel.addAttribute("member", theMember);
return "/login/signUp";
}
#PostMapping("/save")
public String saveMember(#ModelAttribute("member") Members theMember, ModelMap modelMap){
Members tempMember = membersService.findByEmail(theMember.getEmail());
if(tempMember != null){
modelMap.addAttribute("error", "Email is already exist!");
return "redirect:/login/signUp";
}else{
membersService.save(theMember);
//prevent duplication
return "redirect:/login/login";
}
}
}
Here is my signUp.html
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
<title>Signup</title>
</head>
<body>
<div class="container">
<h3>Signup</h3>
<hr>
<p class="h4 mb-4">Signup</p>
<form action="#" th:action="#{/login/save}" th:object="${member}" method="POST">
<input type="text" th:field="*{firstName}" class="form-control mb-4 col-4" placeholder="First name">
<input type="text" th:field="*{lastName}" class="form-control mb-4 col-4" placeholder="Last name">
<input type="text" th:field="*{email}" class="form-control mb-4 col-4" placeholder="Email">
<input type="password" th:field="*{password}" class="form-control mb-4 col-4" placeholder="Password">
<button type="submit" class="btn btn-info col-2">Save</button>
<p th:text="${error}" />
</form>
<br>
Do you have an account? <a th:href="#{/login/login}">Click here</a>
</div>
</body>
</html>
As I mentioned above this is the only html where the th:text does not works, everywhere else is good.
I hope somebody can help me!
When you use a redirect:, you lose all your model attributes (because it's loading a new page). You need to use a FlashAttribute instead. Like this:
#PostMapping("/save")
public String saveMember(#ModelAttribute("member") Members theMember, ModelMap modelMap, RedirectAttributes redirAttrs){
Members tempMember = membersService.findByEmail(theMember.getEmail());
if(tempMember != null){
redirAttrs.addFlashAttribute("error", "Email is already exist!");
return "redirect:/login/signUp";
}else{
membersService.save(theMember);
//prevent duplication
return "redirect:/login/login";
}
}
We have a web application in which we need to show one header if we are logged in, and another one if we are not logged in. I would like to render these server side in a JSP file.
Here is my first attempt:
WebDelivery.java
package xyz.toold.cuebox.web;
import java.util.HashMap;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.glassfish.jersey.server.mvc.Viewable;
#Path("/")
public class WebDelivery {
#Path("/")
#GET
public Viewable index() {
HashMap<String, Object> model = new HashMap<>();
model.put("LoggedIn", true);
return new Viewable("/index", model);
}
#Path("/search/")
#GET
public Viewable search() {
return new Viewable("/search/index", true);
}
#Path("/user/")
#GET
public Viewable user() {
return new Viewable("/user/index");
}
#Path("/board/details/")
#GET
public Viewable boardDetails() {
return new Viewable("/board/details/index");
}
#Path("/board/")
#GET
public Viewable board() {
return new Viewable("/board/index");
}
#Path("/admin/")
#GET
public Viewable admin() {
return new Viewable("/admin/index");
}
}
index.jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="default-src: https: 'unsafe-inline'" />
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="robots" content="index,follow" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="css/bulma.min.css">
<link rel="stylesheet" href="css/style.css">
<title>CueBox</title>
</head>
<body>
<%--TODO: Add logic to decide which header to set--%>
<c:if test="${model.LoggedIn}">
<jsp:include page="assets/partials/header-nologin-popups.jsp"/>
</c:if>
<section class="hero has-plant-image-background is-fullheight">
<div class="title-position">
<div class="hero-body">
<div class="container">
<h1 class="title-size has-text-white">NEW ERA OF<br/>FEEDBACK</h1>
<h2 class="hr subtitle-size has-text-white">GET YOUR FEEDBACK WITH EASE</h2>
</div>
</div>
</div>
</section>
<section class="section is-fullheight has-text-black has-background-grey-light has-text-centered">
<div class="column is-half is-offset-one-quarter">
<div class="hero-body">
<h1 class="title is-1">WHAT TO EXPECT</h1>
<hr class="line has-background-white">
</div>
</div>
<div class="hero-body">
<div class="container">
<div class="columns">
<div class="column">
<div class="content">
<i class="icon is-large fas fa-2x fa-comments"></i>
<h1 class="title is-size-4">Honest Feedback</h1>
<p class="is-size-5">The users can write anonymous posts, so it will be more honest.</p>
</div>
</div>
<div class="column">
<div class="content">
<i class="icon is-large fas fa-2x fa-cogs"></i>
<h1 class="title is-size-4">Easy administration</h1>
<p class="is-size-5">Don't waste time be configuring stupid settings.</p>
</div>
</div>
<div class="column">
<div class="content">
<i class="icon is-large fas fa-2x fa-users"></i>
<h1 class="title is-size-4">Scalable</h1>
<p class="is-size-5">CueBox works for living communities, small companies and lare groups.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<jsp:include page="assets/partials/footer.html"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js" integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT" crossorigin="anonymous"></script>
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js" integrity="sha384-kW+oWsYx3YpxvjtZjFXqazFpA7UP/MbiY4jvs+RWZo2+N94PFZ36T6TFkc9O3qoB" crossorigin="anonymous"></script>
<script src="js/main.js"></script>
<script src="js/validation.js"></script>
<script src="js/helper.js"></script>
</body>
</html>
The problem is my if never fires, so the header never gets shown. I know that the else is missing. I would have implemented it via having another if, which is inverted.
I also tried not passing a HashMap but a plain boolean, but it did not work either.
This is a link to my GitLab project.
What am I doing wrong, or is this entirely the wrong way to do it?
I was creating a quiz application in java to host on Google App Engine. However when I am trying to Deploy it, it gives an error that unable to compile JSP java Class. Even if I try to upload a blank JSP. On local server, everything works fine.
The error is shown below.
Console Error on Eclipse:
------------ Deploying frontend ------------
Preparing to deploy:
Created staging directory at:
'/var/folders/2y/f99pqznd5m3g21gbjl7rgjc40000gn/T/appcfg966104224651839827.tmp'
Scanning for jsp files.
Compiling jsp files.
com.google.appengine.tools.admin.JspCompilationException: Failed to
compile the generated JSP java files. Sep 02, 2015 6:35:38 PM
org.apache.jasper.JspC processFile INFO: Built File: /index.jsp
Debugging information may be found in
/private/var/folders/2y/f99pqznd5m3g21gbjl7rgjc40000gn/T/appengine-deploy2339970973769784997.log
I have already tried to find solution regarding this. However no success till now.
The JSP file is shown below. Its not doing anything, still I am getting the error:
index.jsp
<html>
<head>
<meta charset="UTF-8">
<title>TechnoQuiz | Registration</title>
<meta
content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'
name='viewport'>
<link href="../../bootstrap/css/bootstrap.min.css" rel="stylesheet"
type="text/css" />
<link
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"
rel="stylesheet" type="text/css" />
<link href="../../dist/css/AdminLTE.min.css" rel="stylesheet"
type="text/css" />
</head>
<body class="register-page"
style="background-repeat: repeat; background-image: url('dist/img/carbon_pattern.png');">
<div class="register-box">
<div class="register-box-body">
<div class="register-logo">
<a><b>ZapQuiz</b>.Space</a>
</div>
<hr>
<p class="login-box-msg">Please fill in the details below</p>
<form name="regform">
<div class="form-group has-feedback">
<input name="fullname" type="text" class="form-control"
placeholder="Full name" /> <span
class="glyphicon glyphicon-user form-control-feedback"></span>
<p id="err1" class="text-red hidden">Can't be Empty</p>
</div>
<div id="email" class="form-group has-feedback">
<input type="email" class="form-control" placeholder="Email"
required /> <span
class="glyphicon glyphicon-envelope form-control-feedback"></span>
<p id="err2" class="text-red hidden">Can't be Empty</p>
</div>
<div id="phone" class="form-group has-feedback">
<input type="tel" class="form-control" placeholder="Phone" /> <span
class="glyphicon glyphicon-phone form-control-feedback"></span>
<p id="err3" class="text-red hidden">Can't be Empty</p>
</div>
<div class="row">
<div class="col-xs-12">
<button type="submit" class="btn btn-primary btn-block btn-flat">Register</button>
</div>
</div>
<hr>
<p class="login-box-msg">
Powered by <strong>Xibeat Technologies</strong>
</p>
</form>
</div>
</div>
<script src="../../plugins/jQuery/jQuery-2.1.4.min.js"></script>
<script src="../../bootstrap/js/bootstrap.min.js"
type="text/javascript"></script>
</body>
</html>
I tried to resolve the issue by going through the generated Java class in the Temp Directory. However, I don't see anything wrong.
Generated JAVA class by AppEngine in the Temp Directory
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
private static java.util.List _jspx_dependants;
private javax.el.ExpressionFactory _el_expressionfactory;
private org.apache.AnnotationProcessor _jsp_annotationprocessor;
public Object getDependants() {
return _jspx_dependants;
}
public void _jspInit() {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
_jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
}
public void _jspDestroy() {
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("<html>\n<head>\n<meta charset=\"UTF-8\">\n<title>TechnoQuiz | Registration</title>\n<meta\n\tcontent='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no'\n\tname='viewport'>\n\n<link href=\"../../bootstrap/css/bootstrap.min.css\" rel=\"stylesheet\"\n\ttype=\"text/css\" />\n<link\n\thref=\"https://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css\"\n\trel=\"stylesheet\" type=\"text/css\" />\n<link href=\"../../dist/css/AdminLTE.min.css\" rel=\"stylesheet\"\n\ttype=\"text/css\" />\n\n</head>\n<body class=\"register-page\"\n\tstyle=\"background-repeat: repeat; background-image: url('dist/img/carbon_pattern.png');\">\n\t<div class=\"register-box\">\n\n\t\t<div class=\"register-box-body\">\n\t\t\t<div class=\"register-logo\">\n\t\t\t\t<a><b>ZapQuiz</b>.Space</a>\n\t\t\t</div>\n\t\t\t<hr>\n\t\t\t<p class=\"login-box-msg\">Please fill in the details below</p>\n\n\t\t\t<form name=\"regform\">\n\n\t\t\t\t<div class=\"form-group has-feedback\">\n\t\t\t\t\t<input name=\"fullname\" type=\"text\" class=\"form-control\"\n\t\t\t\t\t\tplaceholder=\"Full name\" /> <span\n\t\t\t\t\t\tclass=\"glyphicon glyphicon-user form-control-feedback\"></span>\n");
out.write("\t\t\t\t\t<p id=\"err1\" class=\"text-red hidden\">Can't be Empty</p>\n\n\t\t\t\t</div>\n\t\t\t\t<div id=\"email\" class=\"form-group has-feedback\">\n\t\t\t\t\t<input type=\"email\" class=\"form-control\" placeholder=\"Email\"\n\t\t\t\t\t\trequired /> <span\n\t\t\t\t\t\tclass=\"glyphicon glyphicon-envelope form-control-feedback\"></span>\n\t\t\t\t\t<p id=\"err2\" class=\"text-red hidden\">Can't be Empty</p>\n\n\t\t\t\t</div>\n\n\t\t\t\t<div id=\"phone\" class=\"form-group has-feedback\">\n\t\t\t\t\t<input type=\"tel\" class=\"form-control\" placeholder=\"Phone\" /> <span\n\t\t\t\t\t\tclass=\"glyphicon glyphicon-phone form-control-feedback\"></span>\n\t\t\t\t\t<p id=\"err3\" class=\"text-red hidden\">Can't be Empty</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"row\">\n\n\t\t\t\t\t<div class=\"col-xs-12\">\n\t\t\t\t\t\t<button type=\"submit\" class=\"btn btn-primary btn-block btn-flat\">Register</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<hr>\n\t\t\t\t<p class=\"login-box-msg\">\n\t\t\t\t\tPowered by <strong>Xibeat Technologies</strong>\n\t\t\t\t</p>\n\n\t\t\t</form>\n\n\t\t</div>\n\n\t</div>\n\n\n\n\t<script src=\"../../plugins/jQuery/jQuery-2.1.4.min.js\"></script>\n\t<script src=\"../../bootstrap/js/bootstrap.min.js\"\n");
out.write("\t\ttype=\"text/javascript\"></script>\n\n\n\n</body>\n</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
Finally, Here is the AppEngine-web.xml File and Web.xml file. In case it may come handy.
appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>zapquiz-1054</application>
<version>1</version>
<!--
Allows App Engine to send multiple requests to one instance in parallel:
-->
<threadsafe>true</threadsafe>
<!-- Configure java.util.logging -->
<system-properties>
<property name="java.util.logging.config.file" value="WEB-INF/logging.properties"/>
</system-properties>
</appengine-web-app>
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"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Thanks and Regards,
Prasun
UPDATE: Log file is shown below
Unable to update:
com.google.appengine.tools.admin.JspCompilationException: Failed to
compile the generated JSP java files. at
com.google.appengine.tools.admin.Application.compileJavaFiles(Application.java:854)
at
com.google.appengine.tools.admin.Application.compileJsps(Application.java:815)
at
com.google.appengine.tools.admin.Application.createStagingDirectory(Application.java:629)
at
com.google.appengine.tools.admin.AppAdminImpl.doUpdate(AppAdminImpl.java:509)
at
com.google.appengine.tools.admin.AppAdminImpl.update(AppAdminImpl.java:55)
at
com.google.appengine.eclipse.core.proxy.AppEngineBridgeImpl.deploy(AppEngineBridgeImpl.java:433)
at
com.google.appengine.eclipse.core.deploy.DeployProjectJob.runInWorkspace(DeployProjectJob.java:158)
at
org.eclipse.core.internal.resources.InternalWorkspaceJob.run(InternalWorkspaceJob.java:38)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
NOTE: This question has been heavily edited as a contrived example has been found to work. However, the problem remains essentially the same as only the contrived example appears to work.
Consider the following JSF page:
<!DOCTYPE html>
<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:ui="http://java.sun.com/jsf/facelets">
<f:view contentType="text/html">
<h:head>
<title>Page</title>
</h:head>
<h:body>
<ui:composition template="/WEB-INF/templates/myLayout.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="foobar" value="#{pageBean.foo}"/>
</f:metadata>
</ui:define>
<ui:define name="content">
<h:form>
<h:commandLink value="Click"
action="#{util.currentPageAction()}"/>
</h:form>
</ui:define>
</ui:composition>
</h:body>
</f:view>
</html>
And these beans:
#Named
#RequestScoped
public class PageBean implements Serializable
{
public String getFoo()
{
return foo;
}
public void setFoo(String foo)
{
this.foo = foo;
}
private String foo;
}
#Named
#ApplicationScoped
public class Util implements Serializable
{
public String currentPageAction()
{
return FacesContext.getCurrentInstance().getViewRoot().getViewId() +
"?faces-redirect=true&includeViewParams=true";
}
}
This contrived example actually does as expected - in particular, it passes through the original values of the view parameters to the URL upon redirect. So, for example, if the original URL is http://localhost:8080/faces/pages/test.xhtml?foo=bar, when I click on the <h:commandLink/> the full URL - including the view parameters - will survive the redirect.
The problem is, when I go from this contrived example to something more real-world (in my case, a search page), the view parameters do not survive the redirect.
Here's the real-world page for which it doesn't work. Sorry, it's a bit lengthy for a typical stackoverflow question.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:search="http://java.sun.com/jsf/composite/components/search"
xmlns:oc="http://java.sun.com/jsf/composite/components/mysite"
xmlns:fn="http://www.mysite.com.au/jsf">
<h:head>
<title></title>
</h:head>
<h:body>
<ui:composition template="/WEB-INF/templates/myLayout.xhtml">
<ui:define name="metadata">
<f:metadata>
<f:viewParam name="address" value="#{searchBean.address}"/>
<f:viewParam name="lng" value="#{searchBean.longitude}" required="#{!facesContext.postback}" requiredMessage="Longitude is required" validatorMessage="Longitude is invalid">
<f:validateDoubleRange minimum="-180" maximum="180"/>
</f:viewParam>
<f:viewParam name="lat" value="#{searchBean.latitude}" required="#{!facesContext.postback}" requiredMessage="Latitude is required" validatorMessage="Latitude is invalid">
<f:validateDoubleRange minimum="-90" maximum="90"/>
</f:viewParam>
<f:viewParam name="gender" value="#{searchBean.gender}"/>
<f:viewParam name="language" value="#{searchBean.spokenLanguageId}"/>
<f:viewParam name="service" value="#{searchBean.serviceId}"/>
<f:viewParam name="rangeKm" value="#{searchBean.rangeKm}" validatorMessage="Range (km) is invalid">
<f:validateLongRange minimum="1"/>
</f:viewParam>
<f:viewParam name="weeksOffset" value="#{searchBean.weeksOffset}"/>
<f:event type="preRenderView" listener="#{searchBean.preRender(e)}"/>
</f:metadata>
</ui:define>
<ui:define name="windowTitle">#{searchBean.address}</ui:define>
<ui:define name="scripts">
<script type="text/javascript">
var mysite = mysite || {};
mysite.longitude = #{searchBean.longitude};
mysite.latitude = #{searchBean.latitude};
mysite.defaultAddress = "#{applicationBean.defaultAddress}";
mysite.region = "#{applicationBean.region}";
mysite.baseUrl = "#{applicationBean.baseUrl}";
</script>
<h:outputScript library="javascript" name="map2.js"/>
<h:outputScript name="geocode.js" library="javascript" target="head"/>
<h:outputScript name="search.js" library="javascript" target="head"/>
</ui:define>
<ui:define name="rightSidebar">
<div class="ocSearch_sidebarSection">
<oc:map styleClass="search"/>
<div>
<a style="font-size:11px;text-decoration:underline;" href="#" onclick="mysite.resetMap();return false;">Reset</a>
</div>
</div>
<oc:context-menu-container isFirstChild="false">
<oc:context-menu title="Search Options">
<form id="searchForm" method="get" onsubmit="return mysite.geocode(this);">
<div style="clear:both;float:left;">
<label for="ocSearchRadius">Service Providers within</label>
<div id="ocSearchRadius">
<input type="text" id="ocRangeKm" name="rangeKm" value="#{searchBean.rangeKm}" style="width:20px;float:left;"/>
<div style="width:40px;margin-top:5px;float:left;overflow:hidden;text-align:center;vertical-align:bottom;">km of</div>
<input type="text" id="ocAddress" name="address" value="#{searchBean.address}" style="width:104px;float:left;"/>
</div>
</div>
<div style="float:left;">
<div style="width:60px;margin-right:10px;float:left;">
<label for="ocGender" style="display:block;">Gender</label>
<select id="ocGender" name="gender" style="width:50px;">
<h:panelGroup rendered="#{searchBean.gender eq 'any'}">
<option value="any" selected="selected">Any</option>
<option value="female">Female</option>
<option value="male">Male</option>
</h:panelGroup>
<h:panelGroup rendered="#{searchBean.gender eq 'female'}">
<option value="any">Any</option>
<option value="female" selected="selected">Female</option>
<option value="male">Male</option>
</h:panelGroup>
<h:panelGroup rendered="#{searchBean.gender eq 'male'}">
<option value="any">Any</option>
<option value="female">Female</option>
<option value="male" selected="selected">Male</option>
</h:panelGroup>
</select>
</div>
<div style="float:left;">
<label for="ocLanguage">Language</label>
<select id="ocLanguage" name="language" style="width:176px;">
<ui:repeat value="#{commonRequestBean.spokenLanguageItems}" var="item">
<h:panelGroup rendered="#{searchBean.spokenLanguageId eq item.value}">
<option value="#{item.value}" selected="yes">#{item.label}</option>
</h:panelGroup>
<h:panelGroup rendered="#{searchBean.spokenLanguageId ne item.value}">
<option value="#{item.value}">#{item.label}</option>
</h:panelGroup>
</ui:repeat>
</select>
</div>
</div>
<div style="float:left;">
<label for="ocService">Reason for visit</label>
<select id="ocService" name="service" style="width:176px;" >
<ui:repeat value="#{commonRequestBean.serviceItems}" var="item">
<h:panelGroup rendered="#{searchBean.serviceId eq item.value}">
<option value="#{item.value}" selected="yes">#{item.label}</option>
</h:panelGroup>
<h:panelGroup rendered="#{searchBean.serviceId ne item.value}">
<option value="#{item.value}">#{item.label}</option>
</h:panelGroup>
</ui:repeat>
</select>
</div>
<div style="float:left;">
<label for="ocStartDate">From</label>
<select id="ocStartDate" name="weeksOffset" style="width:176px;">
<ui:repeat value="#{fn:selectableDates(13)}" var="date" varStatus="dateStatus">
<h:panelGroup rendered="#{date.value eq searchBean.weeksOffset}">
<option value="#{date.value}" selected="yes">#{date.label}</option>
</h:panelGroup>
<h:panelGroup rendered="#{date.value ne searchBean.weeksOffset}">
<option value="#{date.value}">#{date.label}</option>
</h:panelGroup>
</ui:repeat>
</select>
</div>
<div style="margin-top:8px;float:left;">
<p:button id="searchAgainButton" value="Search Again"/>
<script type="text/javascript">
//<![CDATA[
$(function(){
// Replace the Search Again button with a clone whose type is submit.
var oldButton = $('#searchAgainButton');
var newButton = oldButton.clone(true);
newButton.attr("type","submit");
newButton.attr("id","searchAgainButtonClone");
newButton.removeAttr("onclick");
newButton.insertBefore(oldButton);
oldButton.remove();
newButton.attr("id","searchAgainButton");
});
//]]>
</script>
</div>
<input type="hidden" id="ocLng" name="lng" value="#{searchBean.longitude}"/>
<input type="hidden" id="ocLat" name="lat" value="#{searchBean.latitude}"/>
</form>
<script>
// Ensure the form fields are set to the current values. (Webkit bug workaround.)
$(function(){
$('#ocRangeKm').val('#{searchBean.rangeKm}');
$('#ocAddress').val('#{searchBean.address}');
$('#ocGender').val('#{searchBean.gender}');
$('#ocLanguage').val('#{searchBean.spokenLanguageId}');
$('#ocService').val('#{searchBean.serviceId}');
$('#ocStartDate').val('#{searchBean.weeksOffset}');
});
</script>
</oc:context-menu>
</oc:context-menu-container>
</ui:define>
<ui:define name="content">
<div id="ocSearchResultsHeader" class="fixed">
<div style="margin-left:10px;">
<h3 style="margin:8px 0 4px 0;">#{searchBean.searchResultsTitle}</h3>
<span class="help">Click a time to book #{searchBean.service.indefiniteArticle} #{searchBean.service.name}</span>
</div>
</div>
<div class="ocSearch_resultSet">
<h:form>
<h:commandLink value="Foobar" action="#{util.currentPageAction}"/>
</h:form>
<search:result resultSet="#{searchBean.results}" startDate="#{searchBean.startDate}"/>
</div>
</ui:define>
</ui:composition>
</h:body>
</html>
The underlying bean, searchBean, is request scoped just like the contrived example.
Update: If I remove the <search:result/> composite component instance, it now works. That's completely unexpected. Similarly, if I leave the component instance there and strip out the body of the component itself, it works. So there's something in the component that interferes with something else. Weird. I'll see if I can figure out what it is.
Update: This looks like a bug. If I replace the composite component with this:
<ui:repeat value="#{searchBean.results} var="item" varStatus="itemStatus">
<h:outputText value="#{item.mapMarker}"/>
<br/>
</ui:repeat>
it also fails, just as it does with the composite component.
Similarly, this fails:
<h:dataTable value="#{searchBean.results}" var="item">
<h:column>
<h:outputText value="#{item.mapMarker}"/>
<br/>
</h:column>
</h:dataTable>
In my particular case, there are three results, so I can iterate over them manually as such:
<ui:param name="results" value="#{searchBean.results}"/>
<br/>
<h:outputText value="#{results.get(0).mapMarker}"/>
<br/>
<h:outputText value="#{results.get(1).mapMarker}"/>
<br/>
<h:outputText value="#{results.get(2).mapMarker}"/>
<br/>
and it works.
So there's something about iterating over the results that is screwing with the <h:commandLink/>.
What on earth could be going wrong? Yet another Mojarra bug where a simple use case fails?
Final update: Narrowed down the problem with contrived examples and moved the question here.
This is a doosey of a bug and I can't figure out whether it's JDK7, Mojarra, the EJB container, GlassFish in general or just a bad mix of two or more of these.
Consider the following snippet from SearchBean:
public List<NormalizedSearchResult> getResults()
{
return searchEjb.findByLocation(getRangeKm(),
getLongitude(),
getLatitude(),
gender,
getSpokenLanguageId(),
getServiceId(),
1,
99,
getStartDate().toDateMidnight().toDate(),
7);
}
public List<NormalizedSearchResult> getResults2()
{
float lng = longitude;
float lat = latitude;
return searchEjb.findByLocation(getRangeKm(),
lng,
lat,
gender,
getSpokenLanguageId(),
getServiceId(),
1,
99,
getStartDate().toDateMidnight().toDate(),
7);
}
public List<NormalizedSearchResult> getResults3()
{
float lng = getLongitude();
float lat = getLatitude();
return searchEjb.findByLocation(getRangeKm(),
lng,
lat,
gender,
getSpokenLanguageId(),
getServiceId(),
1,
99,
getStartDate().toDateMidnight().toDate(),
7);
}
public List<NormalizedSearchResult> getResults4()
{
float lng = longitude;
float lat = latitude;
return searchEjb.findByLocation(getRangeKm(),
138.5999594f,
-34.9286212f,
gender,
getSpokenLanguageId(),
getServiceId(),
1,
99,
getStartDate().toDateMidnight().toDate(),
7);
}
public List<NormalizedSearchResult> getResults5()
{
float lng = 138.5999594f;
float lat = -34.9286212f;
return searchEjb.findByLocation(getRangeKm(),
lng,
lat,
gender,
getSpokenLanguageId(),
getServiceId(),
1,
99,
getStartDate().toDateMidnight().toDate(),
7);
}
public Float getLongitude()
{
return longitude;
}
public void setLongitude(Float longitude)
{
this.longitude = longitude;
}
public Float getLatitude()
{
return latitude;
}
public void setLatitude()
{
this.latitude = latitude;
}
private Float longitude;
private Float latitude;
Either of these snippets, when included in search.xhtml, cause includeViewParams=true to fail on the abovementioned <h:commandLink/>:
<ui:repeat value="#{searchBean.results}"/>
<ui:repeat value="#{searchBean.results2}"/>
<ui:repeat value="#{searchBean.results3}"/>
<ui:repeat value="#{searchBean.results4}"/>
However, this one doesn't have the same undesirable effect:
<ui:repeat value="#{searchBean.results5}"/>
Nor does this:
<ui:param name="results" value="#{pageBean.results}"/>
<h:outputText value="#{results.get(0).mapMarker}"/>
<br/>
<h:outputText value="#{results.get(1).mapMarker}"/>
<br/>
<h:outputText value="#{results.get(2).mapMarker}"/>
<br/>
And of course, includeViewParams=true works when none of these xhtml snippets are used.
I then changed the type of the longitude and latitude private variables from Float to float and no longer had these failures for any of the above cases.
WTF?! Seriously?
How could anyone possibly imagine that unboxing view parameters during the earlier stages of rendering the view would break includeViewParams=true?
Comments at JAVASERVERFACES-2260.
I have not been able to find a solution to this problem and my post to the Seam forum has gone unanswered. I am hope someone here can help.
I am a noob working with Seam, so I am sure I am just doing something stupid. Any help anyone can give me would be greatly appreciated... I have wasted hours and gotten nowhere. I used the jboss tools to generate a seam project in eclipse. The tool took pre-created JPA entities and created a basic webapp. My first step was to add a registration page so that I can create some users and login using database authentication (I set this up, but will test it once the registration page works). I used the seam-booking example to guide me (basically integrating the form stuff plus additional fields into the view of the seam-gen app). When I test the registration page, I get NullPointerExceptions for all of the injected fields. I have looked through the entire seam-booking example, scoured the web looking at examples, and quickly read through some sections of a book and I do not see where there is any additional configuration information needed. What in the world am I doing wrong? Please help!!!
I am using JBoss Server (community edition) 5.1.0GA and Seam 2.2.0GA.
If you need any more information than what I am posting, please let me know. Thanks to all ahead of time for your help!!
Stateful EJB:
#Stateful
#Scope(EVENT)
#Name("register")
public class RegisterAction implements Register {
#In
private User user;
#PersistenceContext
private EntityManager entityManager;
#In
private FacesMessages facesMessages;
private String verify = null;
private boolean registered = false;
public void registerUser() {
if (user.getPassword().equals(verify)) {
List existing = entityManager
.createQuery(
"select u.userName from User u where u.userName=#{user.userName}")
.getResultList();
if (existing.size() == 0) {
entityManager.persist(user);
facesMessages
.add("Successfully registered as #{user.userName}");
registered = true;
} else {
facesMessages.addToControl("userName",
"Username #{user.userName} already exists");
}
} else {
facesMessages.addToControl("verify", "Re-enter your password");
verify = null;
}
}
public void invalid() {
facesMessages.add("Please try again");
}
public boolean isRegistered() {
return registered;
}
public String getVerify() {
return verify;
}
public void setVerify(String verify) {
this.verify = verify;
}
#Remove
#Destroy
public void destroy() {
}
}
EJB local interface:
#Local
public interface Register
{
public void registerUser();
public void invalid();
public String getVerify();
public void setVerify(String verify);
public boolean isRegistered();
public void destroy();
}
XHTML of registratin page:
<ui:define name="body">
<rich:panel>
<f:facet name="header">Register</f:facet>
<h:form id="registration">
<fieldset><s:decorate id="firstNameDecorate"
template="layout/edit.xhtml">
<ui:define name="label">First Name:</ui:define>
<h:inputText id="firstName" value="#{user.firstName}"
required="true">
<a:support id="onblur" event="onblur" reRender="firstNameDecorate" />
</h:inputText>
</s:decorate> <s:decorate id="lastNameDecorate" template="layout/edit.xhtml">
<ui:define name="label">Last Name:</ui:define>
<h:inputText id="lastName" value="#{user.lastName}" required="true">
<a:support id="onblur" event="onblur" reRender="lastNameDecorate" />
</h:inputText>
</s:decorate> <s:decorate id="emailDecorate" template="layout/edit.xhtml">
<ui:define name="label">Email:</ui:define>
<h:inputText id="emailAddress" value="#{user.emailAddress}"
required="true">
<a:support id="onblur" event="onblur" reRender="emailDecorate" />
</h:inputText>
</s:decorate> <s:decorate id="usernameDecorate" template="layout/edit.xhtml">
<ui:define name="label">Username:</ui:define>
<h:inputText id="username" value="#{user.userName}" required="true">
<a:support id="onblur" event="onblur" reRender="usernameDecorate" />
</h:inputText>
</s:decorate> <s:decorate id="passwordDecorate" template="layout/edit.xhtml">
<ui:define name="label">Password:</ui:define>
<h:inputSecret id="password" value="#{user.password}"
required="true" />
</s:decorate> <s:decorate id="verifyDecorate" template="layout/edit.xhtml">
<ui:define name="label">Verify Password:</ui:define>
<h:inputSecret id="verify" value="#{register.verify}"
required="true" />
</s:decorate>
<div class="buttonBox"><h:commandButton id="register"
value="Register" action="#{register.registerUser}" /> <s:button
id="cancel" value="Cancel" view="/index.xhtml" /></div>
</fieldset>
</h:form>
</rich:panel>
</ui:define>
</ui:composition>
Template XHTML (Registration page uses this):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<f:view xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a="http://richfaces.org/a4j"
xmlns:s="http://jboss.com/products/seam/taglib"
contentType="text/html">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>MyApp</title>
<link rel="shortcut icon" href="#{request.contextPath}/favicon.ico"/>
<a:loadStyle src="resource:///stylesheet/theme.xcss"/>
<a:loadStyle src="/stylesheet/theme.css"/>
<ui:insert name="head"/>
</head>
<body>
<ui:include src="menu.xhtml">
<ui:param name="projectName" value="MyApp"/>
</ui:include>
<div class="body">
<h:messages id="messages" globalOnly="true" styleClass="message"
errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg"
rendered="#{showGlobalMessages != 'false'}"/>
<ui:insert name="body"/>
</div>
<div class="footer">
<p>Powered by Seam #{org.jboss.seam.version} and RichFaces. Generated by seam-gen.</p>
<s:fragment rendered="#{init.debug}">
<a:log hotkey="D"/>
<p style="margin-top: -0.5em;">
Conversation: id = #{conversation.id}, #{conversation.longRunning ? 'long running' : 'temporary'}#{conversation.nested ? ', nested, parent id = '.concat(conversation.parentId) : ''}
#{' - '}
Ajax4jsf Log (Ctrl+Shift+D)
#{' - '}
<s:link id="debugConsole" view="/debug.xhtml" value="Debug console" target="debugConsole"/>
#{' - '}
<s:link id="resetSession" view="/home.xhtml" action="#{org.jboss.seam.web.session.invalidate}" propagation="none" value="Terminate session"/>
</p>
</s:fragment>
</div>
</body>
</html>
</f:view>
Seam Components.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:persistence="http://jboss.com/products/seam/persistence"
xmlns:drools="http://jboss.com/products/seam/drools"
xmlns:bpm="http://jboss.com/products/seam/bpm"
xmlns:security="http://jboss.com/products/seam/security"
xmlns:mail="http://jboss.com/products/seam/mail"
xmlns:web="http://jboss.com/products/seam/web"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.2.xsd
http://jboss.com/products/seam/persistence http://jboss.com/products/seam/persistence-2.2.xsd
http://jboss.com/products/seam/drools http://jboss.com/products/seam/drools-2.2.xsd
http://jboss.com/products/seam/bpm http://jboss.com/products/seam/bpm-2.2.xsd
http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.2.xsd
http://jboss.com/products/seam/mail http://jboss.com/products/seam/mail-2.2.xsd
http://jboss.com/products/seam/web http://jboss.com/products/seam/web-2.2.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">
<core:init debug="true" jndi-pattern="#jndiPattern#"/>
<core:manager concurrent-request-timeout="500"
conversation-timeout="120000"
conversation-id-parameter="cid"
parent-conversation-id-parameter="pid"/>
<!-- Make sure this URL pattern is the same as that used by the Faces Servlet -->
<web:hot-deploy-filter url-pattern="*.seam"/>
<persistence:managed-persistence-context name="entityManager" auto-create="true"
persistence-unit-jndi-name="java:/MyAppEntityManagerFactory"/>
<drools:rule-base name="securityRules">
<drools:rule-files>
<value>/security.drl</value>
</drools:rule-files>
</drools:rule-base>
<security:rule-based-permission-resolver security-rules="#{securityRules}"/>
<security:identity-manager identity-store="#{jpaIdentityStore}" />
<security:jpa-identity-store
entity-manager="#{entityManager}" user-class="my.app.path.dao.profiles.User"
role-class="my.app.path.dao.profiles.Role" />
<event type="org.jboss.seam.security.notLoggedIn">
<action execute="#{redirect.captureCurrentView}"/>
</event>
<event type="org.jboss.seam.security.loginSuccessful">
<action execute="#{redirect.returnToCapturedView}"/>
</event>
<mail:mail-session host="localhost" port="25"/>
</components>
A quick answer as I'm on the rush:
To address the Seam question first, is "User" a Seam component that will be auto-created or is there a factory method to create one? Annotating a field with #In is just one half of what's required, you still need the other end which supplies the value.
In the bigger picture:
presuming User is an entity, having it as a Seam component is not a good practice (way too much overhead caused by Seam).
your stateful bean is scoped as an EVENT. This is unlikely to be your desire, the EVENT scope in Seam is the same as a request for a servlet.
See if you can get a copy of "Seam in Action", it explains the fundamentals very well.