I am trying to get samples running of the book "Java EE 7 Development with WildFly". Now I face the following question/problem:
TheatreInfo.java:
#Model
public class TheatreInfo {
...
#Produces
#Named
public Collection<Seat> getSeats() {
return Lists.newArrayList(seats);
}
...
}
Seat.java:
#Dependent
#Named
public class Seat {
...
public String getName() {
return name;
}
...
}
index.xhtml:
<?xml version="1.0" encoding="UTF-8" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
template="/WEB-INF/templates/default.xhtml">
<ui:define name="content">
<h1>TicketBooker Machine</h1>
<h:form id="reg">
<h:panelGrid columns="1" border="1" styleClass="smoke">
<h:dataTable var="_seat" value="#{seats}" rendered="#{not empty seats}" styleClass="simpletablestyle">
...
</h:dataTable>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
beans.xml:
<beans 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/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all/annotated">
</beans>
This perfectly works - I see a table of seats in my web-brower - as long as I use bean-discovery-mode="all" in my beans.xml. As soon as I use bean-discovery-mode="annotated" in my beans.xml I don't see the table of seats anymore in my browser respectively I see an empty table but no error occurs.
In the book they use bean-discovery-mode="all" but I prefer to see which classes are managed beans an which are not. To use bean-discovery-mode="annotated" I had to add #Dependent to some classes but I have not been able to fix the issue with the names producer method. Can anyone help?
Hm, it runs if I use
#Named
#RequestScoped
public class TheatreInfo {
...
instread of
#Model
public class TheatreInfo {
...
Don't understand why, #Named and #RequestScoped is included in the #Model stereotype!? Does anyone know?
Thanks, Dominic
Related
This question already has an answer here:
Eclipse won't autocomplete bean methods in EL when I use javax.annotation.ManagedBean
(1 answer)
Closed 6 years ago.
Template Client.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:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<body>
<f:view contracts="#{themeSelector.themeName}">
<ui:composition template="/template.xhtml">
<ui:define name="top">
<h:form>
<h:outputLabel value="Theme" for="menu"></h:outputLabel>
<h:selectOneMenu id="menu" label="ThemeMenu" value="#{themeSelector.themeName}">
<f:selectItem itemLabel="Dark" itemValue="dark"></f:selectItem>
<f:selectItem itemLabel="Normal" itemValue="normal"></f:selectItem>
</h:selectOneMenu>
<h:message for="menu"></h:message>
<h:commandButton id="Submit" value="Submit" action="templateClient"></h:commandButton>
</h:form>
</ui:define>
</ui:composition>
</f:view>
</body>
</html>
ThemeSelector.java
package com.rshingha.example;
import javax.annotation.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
/**
*
* #author rshingha
*/
#ManagedBean
#RequestScoped
public class ThemeSelector {
private String themeName="dark";
public ThemeSelector()
{
}
public String getThemeName() {
return themeName;
}
public void setThemeName(String themeName) {
this.themeName = themeName;
}
}
Issue:
Following line in TemplateClient.xhtml
<f:view contracts="#{themeSelector.themeName}">
Here value of "contracts" attribute is not getting resolved, even when I am doing "Ctrl+click" on property name "themeName", its not going to that property in bean file
Interesting thing is when I am hardcoding value for "contracts" attribute then its working.
I also tried with #Named annotation , but same is happening in that case with one exception:
When I am doing "Ctrl+click" on property name "themeName", its navigating to that property in bean file
Please suggest anything , I am stuck
You got wrong import for #ManagedBean. Use this one javax.faces.bean.ManagedBean from JSF. If you want to use #Named (which is CDI technology) then you should also change imports for scopes, request scope would be javax.enterprise.context.RequestScoped.
How to define the max number of component trees in client mode? How to prevent calling #PostConstruct method?
I'm developing an application by JavaEE7 with glassfish 4.1.
If I remember correctly, when javax.faces.STATE_SAVING_METHOD is client, there is no limit of component tree.
But when I opened more than 25 tabs in Chrome and operate the first tab, that tab's managed bean will construct and call #PostConstruct method.
I think this behavior seems losing component tree to me.
The following is source code of my application.
test.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">
<ui:composition
template="/template/template.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
>
<h:panelGrid columns="5" cellpadding="5" >
<p:commandButton id="returnButton" value="return"
action="#{testEditBean.return()}"
immediate="true"
/>
</h:panelGrid>
</ui:composition>
testBean.java
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
#Named(value = "testBean")
#ViewScoped
public class TestBean implements Serializable {
#PostConstruct
public void index() {
}
public String doReturn() {
String ret = "/content/tmp/testSearch.xhtml";
return ret;
}
}
[postscript 2016/01/28]
I understand that a HTTP session stored view scoped beans (max 25) and view state only stored component tree.
This is my new question.
Unless we change mojjara 2.x to another JSF implementation, we couldn't open more than 25tabs?
"more than 25 tabs" contains this case that "an user open 2 tabs, and 23 transition occur in 2nd tab."
I'm exploring the Faces Flow feature in JSF 2.2 and I'm getting the following error Target Unreachable, identifier 'flowScope' resolved to null when I run the tutorial in this page: http://www.mastertheboss.com/javaee/jsf/faces-flow-tutorial
The sample seems to be really simple, it only have one flow with 3 facelets, with this structure:
The flow is called signup, so I have a folder called signup in inside my WebContent folder, and 3 facelets, one of them with the same name as the flow as starting node, and a configuration file called signup-flow.xml.
This is the content of the starting node (signiup.xhtml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>Signup account</title>
<meta http-equiv="Content-Type"
content="application/xhtml+xml; charset=UTF-8" />
</h:head>
<h:body>
<h:form id="form1" styleClass="form">
<h1>Signup Account</h1>
<p>Name <h:inputText id="name" value="#{flowScope.name}" /></p>
<p>Surname: <h:inputText id="surname" value="#{flowScope.surname}" /></p>
<p>Email: <h:inputText id="email" value="#{flowScope.email}" /></p>
<p><h:commandButton id="page2" value="next" action="signup2" /></p>
</h:form>
</h:body>
</html>
This is my SignupBean:
package com.jsf.flow;
import java.io.Serializable;
import javax.inject.Named;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.flow.FlowScoped;
#Named
#FlowScoped(value="signup")
public class SignupBean implements Serializable {
private static final long serialVersionUID = 8112971305468080981L;
private boolean licenseAccepted;
public SignupBean() {
}
public String getHomeAction() {
return "/index";
}
public boolean isLicenseAccepted() {
return licenseAccepted;
}
public void setLicenseAccepted(boolean licenseAccepted) {
this.licenseAccepted = licenseAccepted;
}
public String accept() {
if (this.licenseAccepted) {
return "signup3";
} else {
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "You have to read and accept the license!", "You have to read and accept the license!"));
return null;
}
}
}
And this is my signup-flow.xml:
<?xml version='1.0' encoding='UTF-8'?>
<faces-config
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"
version="2.2">
<flow-definition id="signup">
<flow-return id="homePage">
<from-outcome>#{signupBean.homeAction}</from-outcome>
</flow-return>
</flow-definition>
</faces-config>
I get the error when I click on the commandButton in the signup.xhtml, the code seems to be exactly the same as the one in the tutorial, I checked several posts with the same error but nothing seems to work for me.
This is the important part in the stack trace:
javax.el.PropertyNotFoundException: /signup/signup.xhtml #12,68 value="#{flowScope.name}": Target Unreachable, identifier 'flowScope' resolved to null
at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100)
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95)
Worth to mention that I'm using GlassFish 4.
Found the problem, I was trying to start the flow calling the initial node using a link, like this:
<h:link id="link1" styleClass="link" value="Link" outcome="/signup/signup.xhtml"></h:link>
Instead I replaced the link with a commandButton and in the action parameter I used the flow name, like this:
<h:commandButton id="start" value="Signup User" action="signup"/>
And now it's working.
When viewing this page with ?mode=test, the button doesn't work. It loads this page without ?mode=test, but h:panelGroup is rendered (because mode is set somewhere else). I use two methods of sending mode (h:inputHidden f:param) and to the server and nothing helps. View scoped bean is not available in CDI. What is the possible solution to this?
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">
<f:view>
<f:metadata>
<f:viewParam name="mode" value="#{test.mode}" />
</f:metadata>
<h:panelGroup layout="block" rendered="#{test.mode.equals('test')}">
<h:form>
<h:inputHidden value="#{test.mode}" />
<h:commandButton value="Run a method" action="#{test.method}">
<f:param name="mode" value="#{test.mode}" />
</h:commandButton>
</h:form>
</h:panelGroup>
<h:messages />
</f:view>
</html>
Java
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named("test")
#RequestScoped
public class TestBean {
private String mode;
public void method() {
System.out.print(mode);
}
public String getMode() {
return mode;
}
public void setMode(String mode) {
this.mode = mode;
}
}
You've got a wide range of possibilities. The easiest one for you is not to bind the view parameter to the backing bean, just keep it bound to the view:
test.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<f:view>
<f:metadata>
<f:viewParam name="mode" value="#{mode}" />
</f:metadata>
<h:form rendered="#{mode eq 'test'}">
<h:commandButton value="Run a method" action="#{test.method(mode)}" />
</h:form>
<h:messages />
</f:view>
</html>
Test.java
#Named
#RequestScoped
public class Test {
public void method(String mode) {
System.out.print(mode);
}
}
If you however would like to switch to #ViewScoped, CDI compatible annotation is now available in JSF 2.2 version. The namespaces you're using suggest you do use that version, so go with it. For JSF prior versions, there's also the chance to do it with custom Omnifaces' annotation.
See also:
Omnifaces #ViewScoped annotation
#ViewScoped in CDI with JSF 2.2
Differences between EL 2.1 and 2.2
I am new to JSF, Java EE and am having abit of a problem with a small test case I am trying out with Faces.xml, JSF and ManagedBeans..
I have a managedBean called beanManager.java and in it, I have two fields(name and testname) and a method called testcase1() that just returns a string. Now, in the frontpage.xhtml, I have an input text box that gets a name from a user and once the user clicks the submit button, the testcase1() method is called and all it does is just set the testname field of the BeanManager.java class with the user's input but for some reasons-obviously why I am sending this message- when the user enter's the name and hits the search button the page navigates to the displaypage.xhtml and the page displays nothing. It is supposed to show the name entered by the user but it is blank. I was advised to use #SessionScoped instead of #RequestScoped but the problem now is that when I deploy my Java EE application on glassfish, i get the following error:
Exception Occurred :Error occurred during deployment: Exception while loading the app :
java.lang.IllegalStateException: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException:
javax.servlet.ServletException: com.sun.enterprise.container.common.spi.util.InjectionException:
Error creating managed object for class: class org.jboss.weld.servlet.WeldListener
Below are my files..
BeanManager.java
import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
#ManagedBean(name = "user")
#SessionScoped
public class BeanManager {
private String name = "";
private String testname = "";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String testcase1(){
setTestname(this.name);
return "test1";
}
public String getTestname() {
return testname;
}
public void setTestname(String testname) {
this.testname = testname;
}
}
frontpage.xhtml
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="WEB-INF/templates/origin.xhtml">
<ui:define name="content">
<f:view>
<h:form>
<h:panelGrid>
<h:inputText value="#{user.name}" required = "true"/>
</h:panelGrid>
<h:commandButton
action="#{user.testcase1()}"
value="Search"></h:commandButton>
</h:form>
</f:view>
</ui:define>
</ui:composition>
</html>
displaypage.xhtml
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/WEB-INF/templates/origin.xhtml">
<ui:define name="content">
<h:panelGrid>
<h:outputText value="#{user.testname}"/>
<h:commandButton id="back" value="GoBack" action="frontpage"/>
</h:panelGrid>
</ui:define>
</ui:composition>
</html>
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">
<navigation-rule>
<from-view-id>/frontpage.xhtml</from-view-id>
<navigation-case>
<from-action>#{user.testcase1()}</from-action>
<from-outcome>test1</from-outcome>
<to-view-id>/displaypage.xhtml</to-view-id>
<redirect/>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/displaypage.xhtml</from-view-id>
<navigation-case>
<from-outcome>GoBack</from-outcome>
<to-view-id>/frontpage.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
You can't use the CDI annotation javax.enterprise.context.SessionScoped with the JSF javax.faces.bean.ManagedBean. You either go pure JSF with
javax.faces.bean.ManagedBean(naming) and javax.faces.bean.SessionScoped (scoping)
OR Pure CDI
javax.inject.Named (naming) and javax.enterprise.context.SessionScoped(scoping)
Related:
Java EE 6 #javax.annotation.ManagedBean vs. #javax.inject.Named vs. #javax.faces.ManagedBean