JSF do not execute the bean - jsf

im trying to learn JSF, but something i lost, cuz this button is not showing the message in eclipse console
the JAVA BEAN:
package beans;
public class protocoloBean {
public void incluirProtocolo() {
System.out.println("MSG");
}
}
the xhtml:
<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>
</h:head>
<h:body>
<h:button value="Protocolar"
action="#{protocoloBean.incluirProtocolo()}"></h:button>
</h:body>
</html>
and the faces-config:
<?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">
<managed-bean>
<managed-bean-name>protocoloBean</managed-bean-name>
<managed-bean-class>beans.protocoloBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<application/>
</faces-config>
what im doing wrong ? or i lost :(

Your JSF code is wrong. You're trying to fire an action using <h:button> when you need/want to use <h:commandButton>. <h:button> is intended for navigation purposes only. See here for a difference between them: Difference between h:button and h:commandButton
You should update your code to:
<h:body>
<ui:remove>
<h:button value="Protocolar"
action="#{protocoloBean.incluirProtocolo()}"></h:button>
</ui:remove>
<!--
Note that h:commandButton MUST ALWAYS be inside a h:form
Otherwise, the action won't fire
-->
<h:form>
<h:commandButton value="Protocolar"
action="#{protocoloBean.incluirProtocolo}" />
</h:form>
</h:body>
After updating your code, the log message will be printed as expected.
Since you're learning JSF 2.2, I would suggest start using JSF 2 features like barely using the faces-config.xml file for managed bean definitions. You could improve your code to this:
#ManagedBean
#SessionScoped
public class ProtocoloBean {
public void incluirProtocolo() {
System.out.println("MSG");
}
}
And your 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">
</faces-config>
* Yes, it is empty :).
Since you're new to JSF, I would recommend start declaring your beans as #RequestScoped or #ViewScoped instead of #SessionScoped. You cn read more info about this here: How to choose the right bean scope?

two mistakes in your code:
the first character of your class name should be Captialized. You should use "ProtocoloBean" insteads of "protocoloBean"
Action attribute is used for redirect page, the method type must be String instead of void. If you just want to execute some code, then you should use "actionListener" rather than "action", in this case your method return type can be void, but make sure (ActionEvent action) is defined as your method input argument

Related

JSF bean action method return string test

I tried to understand from this question the difference between returning null and "" in JSF action, but couldn't experience in real.
Below is the quote form the OP
From what I understand, when a JSF action returns "" (empty String)
the user stays on the current page but the view is refreshed. However,
when the action returns null the user still stays on the current page
but the old view is reused
I am in a confusion of understanding the difference between returning "", null and "viewid?faces-redirect=true" from a JSF Backing bean. I tried to understand the difference with a small example, but I couldn't experience the actual difference. Below are the code snippets of my example.
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_2_5.xsd" version="2.5">
<display-name>Jsf Questions</display-name>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jspx</param-value>
</context-param>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/jsfintroapp/*</url-pattern>
</servlet-mapping>
</web-app>
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
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_1_2.xsd">
<managed-bean>
<managed-bean-name>userLogin</managed-bean-name>
<managed-bean-class>com.srk.beans.UserLogin</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<navigation-rule>
<description>Contains list of all navigation rules here</description>
<from-view-id>/*</from-view-id>
<navigation-case>
<display-name>WELCOME</display-name>
<from-outcome>welcome</from-outcome>
<to-view-id>/geek_examples/authorized_user.jspx</to-view-id>
</navigation-case>
</faces-config>
My managed bean is a request scoped bean, as declared above.
UserLogin.java (Backing bean) code snippet
public String saveData() {
//String returnString = "";//Case 1 : works - user stays on the same page
//String returnString = null;//Case 2: works - user stays on the same page
// Case 3:
String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();
LOG.debug("view id = "+ viewId);
String returnString = "?faces-redirect=true";//viewId+
LOG.debug("return string = "+ returnString);
LOG.debug("Username = "+ getName() + " password = "+ getPassword());
return returnString;
}
login.jspx
<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">
<f:view>
<head>
<title>JSF Question</title>
</head>
<body>
<h:form>
<h3>User Name and Password</h3>
<table>
<tr>
<td><h:outputLabel value="Name"/></td>
<td><h:inputText value="#{userLogin.name}"/></td>
</tr>
<tr>
<td><h:outputLabel value="Password"/></td>
<td><h:inputText value="#{userLogin.password}"/></td>
</tr>
<tr>
<td><h:commandButton value="Sign In" action="#{userLogin.saveData}"/></td>
</tr>
</table>
</h:form>
</body>
</f:view>
</html>
Libraries used in this example
I tried to access the login.jspx page, entered values in the fields of form and clicked on Sign In. I can always see the same page, no matter what I return there in my saveData() method which is not showing any difference in behavior, Can somebody throw some light with respect to this concept?
As answered in that answer, returning null or void will reuse the same JSF view, including all view scoped beans attached to it.
JSF 1.2, however, has no concept of a "view scoped bean". This was introduced in JSF 2.0. Moreover, you've a request scoped bean. It'll always be recreated on every request, regardless of how you navigate. So it's not really noticeable by looking at how the bean behaves. It's only noticeable if you manually mimic the JSF 2.0 view scope by putting an attribute in the UIViewRoot and then checking in the constructor of the request scoped bean if it's still present.
If you have used a JSF 2.x view scoped bean, you'd have noticed that it's recreated (i.e. it's (post)constructor is invoked again) when you navigate using a non-null outcome. See also a.o. How to choose the right bean scope?
And, the ?faces-redirect=true query string is also JSF 2.x specific and not recognized by JSF 1.x. In JSF 1.x, to achieve the same effect, either add <redirect/> to the <navigation-case>, or use ExternalContext#redirect().
public void saveData() throws IOException {
// ...
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
String url = ec.getRequestContextPath() + "/login.jsf";
ec.redirect(url);
}
Which navigation approach to choose is elaborated in this related question: How to navigate in JSF? How to make URL reflect current page (and not previous one). Generally, in UX and SEO perspective, using POST for page-to-page navigation is bad practice. Always use GET for that or perform a redirect after POST.
In any case, when developing with JSF 1.x, you should not be looking at JSF 2.x targeted answers/resources. It'll only lead to confusion because many things are done differently (better!) in JSF 2.x. JSF 2.x exist more than 5 years already and JSF 1.x was EOL for nearly as long. It doesn't make sense to keep working on dead technology. Consider migrating.

Where to place configuration properties files in a JSP web application?

I read this Where to place and how to read configuration resource files in servlet based application? and more but i dont have a java class, i only have xhtml page to get messages from property. I put properties fcile into webcontent, src, package in src, meta inf but none of them worked.
the xhtml page:
<?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:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>#{msgs.windowTitle}</title>
</head>
<body>
<h:form>
<h:panelGrid columns="2" columnsClasses="evenColumns, oddColumns">
#{msgs.namePrompt}
<h:inputText/>
#{msgs.PasswordPrompt}
<h:inputSecret id="password" />
#{msgs.ConfirmPasswordPrompt}
<h:inputSecret id="passwordConfirm"/>
</h:panelGrid>
<h:commandButton type="button" value="Submit" onclick="checkPassword(this.form)" />
</h:form>
</body>
</html>
facesconfig:
<?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">
<application>
<message-bundle>messages</message-bundle>
</application>
</faces-config>
checkPassword.js (i put in webcontent, i couldnot have time for to find where to put js, i first want to find out properties)
/**
*
*/
function checkPassword(form){
var password = form[form.id+":passwordConfirm"].value;
var passwordConfirm = form[form.id+":password"].value;
if(password==passwordConfirm){
form.submit();
}
else{
alert("Wrong");
}
}
I use eclipse kepler jsf 2.2. Apache tomcat 7.0.54
When i run, it only shows input texts, not title or other texts. What can be the reason?
I changed also a lot of times name of file. Messages, msgs, messages and declaration but still did not work.
try to put this inside faces-config:
<application>
<resource-bundle>
// try to put inside main/java/resources
<base-name>com.x.messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
and then for especial bundle you can specify a bundle for view:
f:loadBundle basename="com.x.messages" var="msg"/>
There are three things you can do for i18n in JSF:
In this case the file messages.properties must be placed in a package called: src/your/package/name/ . Change this to your needs.
Define the message files in faces-context.xml:
<locale-config>
<default-locale>en</default-locale>
<supported-locale>de</supported-locale>
<supported-locale>cn</supported-locale>
</locale-config>
<resource-bundle>
<base-name>your.package.name.messages</base-name>
<var>msgs</var>
</resource-bundle>
Or use the format-taglib to load the bundle:
<f:loadBundle basename="your.package.name.messages" var="msgs" />
Or create a bean yourselft using the ResourceBundle class.

JSF 1.2 : Can I create reusable component inside JSF view

Is possible to something like this in jsf?
<ui:composition>
<x:reusableCode id="editScreen">InnerHtml ... </x:reusableCode>
code...
<x:use component="editScreen"/>
</ui:composition
I know I can create my own component and register it in jsf tagLib, but I need reusable HTML only in on jsf view file.
In Facelets 1.x you can create a tag file for this purpose.
Here's a basic kickoff example. Create /WEB-INF/tags/some.xhtml:
<ui:composition
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<h:outputText value="#{foo}" />
</ui:composition>
Define it in /WEB-INF/my.taglib.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://example.com/jsf/facelets</namespace>
<tag>
<tag-name>some</tag-name>
<source>/WEB-INF/tags/some.xhtml</source>
</tag>
</facelet-taglib>
Register it in /WEB-INF/web.xml:
<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>
(note, when you have multiple, use semicolon ; to separate them)
Finally just declare it in your main page templates.
<ui:composition
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:my="http://example.com/jsf/facelets"
>
<my:some foo="value1" />
<my:some foo="value2" />
<my:some foo="value3" />
</ui:composition>
A more advanced example can be found here: How to make a grid of JSF composite component? Note: JSF 2.0 targeted, but with minor changes based on above example it works as good on Facelets 1.x.

How to see message.properties in a Jar using JSF?

Using: JSF 1.2, Facelets 1.1.15, GateIn 3.1 GA, Richfaces 3.3.3
I have some common .xhtml and backing bean in a JAR that our portlets can see. I did this by overriding ResourceResolver as described in other posts:
http://ocpsoft.com/opensource/create-common-facelets-jar/
How to use Facelets composition with files from another context
The portlets can load the XHTML and use the backing bean.
Here is my problem: I cannot get the xhtml to substitute the messages defined in messages_en.properties. I have tried moving the properties file outside of the JAR and placing directly in /lib folder. I have also tried putting a / in front of the name to try to get the resolver to find it. I have also put it in the components folder.
The common jar info is: I hava a my-portlet-common-resources.jar which resides in server/my-portal/lib. The jar is structured like so:
com/portlet/common/CustomResourceResolver.class
com/portlet/common/FilterCreateBean.class - backing bean for the common popup
messages_en.properties
faces-config.xml
META-INF/components/commonPopups.xhtml
META-INF/faces-config.xml - declares the FilterBean
META-INF/Manifest.mf
faces-config.xml contents:
<?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_1_2.xsd"
version="1.2">
<application>
<locale-config>
<default-locale>en</default-locale>
</locale-config>
<message-bundle>/messages_en.properties</message-bundle>
</application>
<managed-bean>
<managed-bean-name>FilterCreateBean</managed-bean-name>
<managed-bean-class>com.portlet.common.FilterCreateBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
Include the messages in commonPopups.xhtml (partial snip):
<ui:composition 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"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<a4j:loadBundle basename="messages" var="msgs"/>
<rich:panel style="border-style:none;" id="addNewChainPanel">
<rich:modalPanel id="modalNewChainPanel" autosized="true">
<f:facet name="header"><h:outputText value="#{msgs['filterset.modal.new.title']}" /></f:facet>
</ui:composition>
This should work. Perhaps you already have a messages*.properties file in the classpath root of your main webapp. This one has then precedence in classloading. You need to put it in a more specific package. Put the JAR's one in for example the com/portlet/common folder so that it becomes member of the com.portlet.common package. This way it'll be available by:
<a4j:loadBundle basename="com.portlet.common.messages" var="msgs"/>
Unrelated to the concrete problem, the <message-bundle> entry in faces-config.xml has a completely different purpose. It's supposed to override JSF default validation/conversion messages which are returned by JSF default validators/converters. It is not intended to provide localized content. There you use the <resource-bundle> entry or <xxx:loadBundle> tag for. I'd remove that entry from the faces-config.xml.

simple JSF commandButton not hitting the action

I have the simplest little JSF example (JSF2 with GlassFish) and I can't figure out why the command button is not hitting the action method. This is what I have ... when I click the button, nothing happens.
What am I doing wrong?
testForm.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:form>
<h:messages />
<p/>
<h:inputText />
<p/>
<h:commandButton value="test1" action="#{testController.action1}" />
</h:form>
</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">
<managed-bean>
<managed-bean-name>testController</managed-bean-name>
<managed-bean-class>com.app.controller.TestController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
TestController.java
package com.app.controller;
public class TestController {
public String action1() {
return "testPage2";
}
}
Eureka! After rebuilding the Eclipse project from scratch I realize what I did wrong. Apache MyFaces is in the project path and the app is being deployed on GlassFish which has it's own JSF implementation. The two JSF implementations don't want to play nicely together.
What a pain. And, you know, I made this exact same mistake once before. Eclipse should warn you about this or there should be some error reported in the GlassFish log or the h:messages tag.
1)For JSF2.0, Its not required to configure managed bean in Facesconfig.xml.
2)can use #managedban annotation.
package com.app.controller;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
#ManagedBean(name = "testController")
#SessionScoped
public class TestController {
public String action1() {
return "testPage2";
}
/** Constructor, getters and setters*/
}

Resources