Primefaces - methods not listed in 'actionListener' - java

I'm using Primefaces 4.0. I have a method in the Bean class, and I want to call it in a commandButton. When using Primeface's commandButton, Eclipse (Kepler) code completes the bean's name, as expected, but does not list the methods. The method is called, but there's no code completion for it. If I use the default commandButton, all the methods are listed (including 'equals' and 'hashCode').
In short, I'm getting code completion for some parts of the Primefaces tags, but not everything.
EDIT:
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"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form>
<p:inputText value="#{testBean.name}" id="name" />
<p:commandButton value="Print name" actionListener="#{testBean.printName}" />
</h:form>
</h:body>
</html>
Bean
import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class TestBean implements Serializable {
private static final long serialVersionUID = -4705029823018566258L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void printName(){
System.out.println(name);
}
}

printName() isn't a Listener object. You need to have a Listener object handle the call and have the action done from there.
Here is some documentation to help you understand.
EDIT
This should work:
<p:commandButton>
<f:actionListener/>
</p:commandButton>
If you have included the tag library and have downloaded the JAR and placed it in your /WEB-INF/lib :
<%# taglib prefix="f" uri="http://java.sun.com/jsf/core"%>

Related

How to maintain a list of objects in Java Server Faces 2

I have a JSF2 application that should show a page where a number os items must be added in a list. The user wants to add those items, set some properties of them and finally persist them all together, in a single save operation.
The domain object that should be handled by this page looks like this:
public class Item {
private long id;
private String name;
private Item previous;
public Item() { }
public Item(Item previousItem) {
this.previous = previousItem;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Item getPrevious() {
return previous;
}
}
The ItemBean class looks like this:
#ManagedBean
public class ItemBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<Item> items = new ArrayList<Item>();
public List<Item> getItems() {
if(items.size()==0) {
items.add(new Item()); // adding the first item
}
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public void addItem(Item previousItem) {
Item newItem = new Item(previousItem);
items.add(newItem);
}
public void save() {
...
}
}
The view is a xhtml file that looks like this:
<?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" xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template="/templates/layout.xhtml">
<ui:define name="content">
<h2>Items</h2>
<fieldset>
<legend>Items being added</legend>
<ui:repeat value="#{itemBean.items}" var="item">
<div>
<h:outputLabel value="Item" for="name" />
<h:inputHidden value="#{item.id}" />
<h:inputText id="name" value="#{item.name}" />
<h:commandLink action="#{itemBean.addItem(item)}">Add</h:commandLink>
</div>
</ui:repeat>
</fieldset>
<div class="options">
<h:commandButton action="#{itemBean.save}" value="Save"/>
<div class="clear border-bottom"></div>
</div>
</ui:define>
</ui:composition>
</body>
</html>
Notice that in order to add a new item, the current one must be sent to satisfy business rules.
The problem is that I can add a second item with no problema, but when I click in the Add link next to the second item, the page is rerendered with one single item, just like it was in the beggining.
Unfortunatelly, I can't see what's missing to make it work, even after reading a lot of posts, pages and some book chapters.
Update 1
I was asked about the kind of scope used with this bean. It´s de default scope (#RequestScoped). I was trying to avoid using #SessionScoped for the sake of scalability, but in this particular case, I´m not sure I have a choice. Anyone with more experience could give me tip?
What is the scope of your ManagedBean ?
Since you didn't post any persistence code, I suppose the items List only exists througout your Bean's life. This means that if your Bean is #ViewScoped or #RequestScoped, your items cease to exist after you submit your form.
You need use an ajax component, something like:
<fieldset id="list">
<legend>Items being added</legend>
<ui:repeat value="#{itemBean.items}" var="item">
<div>
<h:outputLabel value="Item" for="name" />
<h:inputHidden value="#{item.id}" />
<h:inputText id="name" value="#{item.name}" />
<h:commandLink action="#{cargoBean.addItem(item)}">
<f:ajax render="list" />
Add
</h:commandLink>
</div>
</ui:repeat>
</fieldset>
I see no form in your xhtml page like :
<h:form>
<ui:repeat>
<h:inputBlabla/>
</ui:repeat>
</h:form>
A form is needed while using h:input fields.

How private fields accessible on jsp page in struts 2.x?

Hello every one I am working with struts 2.x and very new for this framework . I follow list of tutorials and steps and my application working properly but there is one thing which is not clear to me Like when I declare one private field in my action class and using struts tag that private field is accessible to the jsp page . So how it happen that is not understandable for me:
struts.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" namespace="/home" extends="struts-default">
<action name="message" class="com.csc.action.MessageAction">
<result name="hello">/hello.jsp</result>
<result name="bye">/bye.jsp</result>
</action>
<action name="add" class="com.csc.action.Mathaction">
<result name="success">/hello.jsp</result>
<result name="fail">/bye.jsp</result>
</action>
</package>
</struts>
MessageAction.java
package com.csc.action;
import com.csc.service.BussniessServ;
public class MessageAction {
private String result;
private String value;
private String fstvalue;
private String scndvalue;
public String getFstvalue() {
return fstvalue;
}
public void setFstvalue(String fstvalue) {
this.fstvalue = fstvalue;
}
public String getScndvalue() {
return scndvalue;
}
public void setScndvalue(String scndvalue) {
this.scndvalue = scndvalue;
}
// method which get value from input parameter
public String getValue() {
return value;
}
// method which show the value of input parameter
public void setValue(String value) {
this.value = value;
}
// method which run as default and execute
public String execute() {
BussniessServ serv = new BussniessServ();
setMessag(serv.Addition(fstvalue, scndvalue));
return "hello";
}
// method to show message on jsp page
public String getResult() {
return result;
}
// method for save message
public void setResult(String result) {
this.result = result;
}
}
Result.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<s:property value="result"/>
</body>
</html>
Struts uses reflection to find a method that returns that variable. For example, if you have a variable called result then Struts looks for a method called getResult() and calls it to obtain a value.
Also, if you want properties to be accessible in the JSP you have to make sure that you name these methods correctly. A property called "abc" would match the method getAbc() (unless it is a boolean, in which case would match the method isAbc() instead).
OGNL does not actually require accessors to be present, although this varies by version–earlier versions (~S2.0) required accessor methods. Later versions (~S2.1+) "helpfully" removed this restriction.
Public properties with private getters also works, although it's obviously pathological.
IMO it was a step backwards for data encapsulation.
It may be configurable in later/current versions of OGNL, I'm not sure.

Missing Resource in EL implementation: ???propertyNotReadable?

I'm using JSF2.1. I don't have any jars in my WEF-INF folder. My classpath is only referencing JSF2.1 and Java EE. I'm using JDK1.7.
I'm getting "Missing Resource in EL implementation: ???propertyNotReadable???" when trying to test out processing GET parameters using f:event type="preRenderComponent". Right now I'm just trying to do a simple test. My page has a lot on it, so I'm only showing the important parts here. The part I added is the <f:metadata> block. When I remove that block, the error goes away.
<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:c="http://java.sun.com/jsp/jstl/core">
<f:metadata>
<f:viewParam name="team" value="#{appBean.team}" />
<f:event type="preRenderComponent" listener="#{appBean.init}" />
</f:metadata>
In my backing bean, I have:
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
#ManagedBean
#ViewScoped
public class AppBean implements Serializable{
private static final long serialVersionUID = 1778234L;
private Long team;
public AppBean(){
}
public void init(){
if (team != null) System.out.println(team);
else System.out.println("team undefined");
}
public void setTeam(Long team){
this.team = team;
}
}
And the way I'm testing this out is to go to my url and add ?team=123 to the end. I'm expecting System.out to print 123. Any ideas on how to fix this error?
I figuered it out... I forgot to include:
public Long getTeam(){
return team;
}

JSF: invoke method if conversion fails

In JSF, how can I invoke method in case of conversion failing on any of input fields? I guess I can write my own converters and do all the stuff there, but isn't there a more simple way?
You could use a PreRenderViewEvent listener, and in that method check if validation has failed. This listener method will be called every time just before the view is rendered.
E.g.
Consider the following Facelet:
<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:body>
<h:messages/>
<f:event listener="#{onErrorBean.onPreRenderView}" type="preRenderView" />
<h:form>
<h:inputText value="#{onErrorBean.test}" label="test" required="true" />
<h:commandButton value="Submit" action="#{onErrorBean.onSuccess}" />
</h:form>
</h:body>
</html>
And the following backing bean:
#ViewScoped
#ManagedBean
public class OnErrorBean {
private String test;
public void onPreRenderView() {
if (FacesContext.getCurrentInstance().isValidationFailed()) {
onError();
}
}
public void onSuccess() {
System.out.println("Success!");
}
public void onError() {
System.out.println("Error!");
}
public String getTest() {
return test;
}
public void setTest(String test) {
this.test = test;
}
}
If you press the button without entering a value you'll see "Error!" being printed in your console, enter a value and you'll see "Success!".

how to move a variable's value from jsf's bean page (i.e, bean.java) to another java class?

how to move a variable's value from jsf's bean page (i.e, bean.java) to another java class? when i tried to do that, the value assinged to the variable in the second java class is NULL.,
I have used primefaces UI framework(something like jsf) and assigned every fields value in to a bean class. the value assigned to every variable in bean class is proper. but when i tried to move those values to another .java file. The scope of the variable dies, and the value is NULL. Check out my codings..
LOGIN.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"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h:head></h:head>
<h:body>
<p:panel header="Login" style="">
<h:form>
<h:panelGrid columns="2" cellpadding="2">
<h:outputText value="Username"></h:outputText>
<p:inputText id="userName" value="#{loginBean.userName}"></p:inputText>
<h:outputText value="Password"></h:outputText>
<p:password id="password" value="#{loginBean.password}"></p:password>
<p:commandButton value="Sign in" ajax="false" actionListener="#{loginBean.forward}"></p:commandButton>
</h:panelGrid>
</h:form>
</p:panel>
</h:body>
</html>
loginBean.java
package bean;
import receive.*;
public class loginBean {
public String userName;
public String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void forward()
{
System.out.println(getUserName());
receiveclass r=new receiveclass();
r.dbc();
}
}
receiveclass.java
package receive;
import bean.loginBean;
public class receiveclass {
loginBean lb=new loginBean();
public void dbc()
{
String s= lb.getUserName();
String p=lb.getPassword();
System.out.println(s);
System.out.println(p);
//System.out.println("hi");
}
}
output is,
if i give as admin, admin in text fields
i am receiving as
admin
null
null
You're manually creating the beans instead of letting JSF manage the beans. Manually created beans won't be used by JSF at all. You need to let JSF auto-create and manage those beans. You can access other JSF managed beans by injecting it as #ManagedProperty:
In your particular case, the following should work:
#ManagedBean
#RequestScoped
public class LoginBean {
private String userName;
private String password;
#ManagedProperty
private ReceiveClass receiveClass;
public void forward() {
receiveClass.dbc(this);
}
// Add/generate getters and setters.
}
with
#ManagedBean
#SessionScoped
public class ReceiveClass {
public void dbc(LoginBean loginBean) {
System.out.println(loginBean.getUserName());
}
}
(Note that I fixed the code to adhere the Java Naming Conventions properly. Class names ought to start with uppercase)
See also:
Communication in JSF 2.0 - Injecting managed beans in each other
in your receiveclass you create a completely new instance of loginBean. Values can only be null.
I do it this way: I created a Java class in which I have static functions like this one
public class JSFHelper
{
public static Object getMyObject(String objname, Class<?> classname )
{
FacesContext fCtx = FacesContext.getCurrentInstance();
ELContext elCtx = fCtx.getELContext();
ExpressionFactory ef = fCtx.getApplication().getExpressionFactory();
ValueExpression ve =
ef.createValueExpression(elCtx, "#{" + objname+ "}",classname);
return (Object) ve.getValue(elCtx);
}
}
If I need a value from another Bean it would look like this in your receiveclass:
public class receiveclass
{
public void dbc()
{
loginBean lb=(loginBean)JSFHelper.getMyObject("loginBean",loginBean.class);
String s= lb.getUserName();
String p=lb.getPassword();
System.out.println(s);
System.out.println(p);
//System.out.println("hi");
}
}

Categories