Problem w korzystaniu z Ajaxa Primefaces, setter nie jest wywoływany.

0

Witam,

Mam mały problem podczas korzystania z JSF - Primefaces pierwszy przykład ze strony primefaces poniżej, sparwił mi wiele kłopotów i do dnia dzisiejszego nie znam sposobu by działał poprawnie. Mianowicie nie jest wywoływany setter i zmienna firstname nie jest ustawiany i nie znam przyczyny tego dziwnego przypadku:

 
	<h:form id="form" prependId="false">

		<p:panel header="New Person">
			<h:panelGrid columns="3">
				<p:inputText id="firstname" value="#{personBean.firstname}" />
				<p:commandButton value="Start" update="display" />
				<h:outputText id="display" value="#{personBean.firstname}" />
			</h:panelGrid>
		</p:panel>

	</h:form>

Tutaj mam Beana:

@ManagedBean
@RequestScoped
public class PersonBean implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

    private String firstname;
    
    
  
    public String getFirstname() {
            return firstname;
    }
    public void setFirstname(String firstname) {
            this.firstname = firstname;
    }

}

Z tego co zauważyłem podczas debugowania kodu, wchodzi mi do gettera ale settera ni jak nie wywołuje. stosowałem już różnych sposobów np atrybutu ajaxlistener, znacznika <p:ajax> i wszędzie jest tak samo setter nie jest wywoływany i pole firstname ciągle jest nullem. Próbowałem też ustawić @ViewScoped ale to też nie pomogło. Czy ktoś zna przyczynę tego dziwnego działania?

0

A jak zrobisz SessionScoped? Bo przecież RequestScoped oznacza że po przeładowaniu strony dane ci "znikną"

0

To samo się dzieje. Raz mi tylko wszedł w settera i oczywiście dalej pole było nullem gdy napisałem tak jak poniżej:

 
@ManagedBean
@SessionScoped
public class PersonBean implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@ManagedProperty(value="firstname")
    private String firstname;
    
    
    private String surname;
  
    public String getFirstname() {
            return firstname;
    }
    public void setFirstname(String firstname) {
            this.firstname = firstname;
    }

    
}

0

Trudno mi w to uwierzyć ;] Możesz gdzieś wrzucić fragment projektu tak żeby można było sobie to odpalić lokalnie i zobaczyć?

0

Oczywiście na mejla mogę Ci podesłać - nie ma problemu.

0

nie uzywalem primeface ale przyczyna moze byc bardzo prosta. Przy wykonywaniu ajaxu wybrane komponenty sa wykonywane w JSF Lifecycle. Ty, nie zdefiniowales takich i nie bedzie wykonany zaden setter na komponent typu EditableValueHolder, co w twoim przypadku jest inputText.

<p:inputText id="firstname" value="#{personBean.firstname}" />
<p:commandButton value="Start" update="display" />
<h:outputText id="display" value="#{personBean.firstname}" />
  1. Zdefiniuj actionListener do commandButton
  2. zmien update="display" process="firstname"
    Nie wiem czy to w 100% zadziala, ale z nazewnictwa atrybutow wynika ze powinno. przeczytaj dokumentacje Primefaces -> commandButton i poprobuj.

W jsf bym to zrobil tak:

<h:commandButton >
    <f:ajax render="display" execute="@this firstname" />
</h:commandButton>

albo bardziej ogolniej (pewniej, bo w niektorych przypadkach moze niezadzialac. Implementacja Mojarry ma pare BUGs, np. jesli uzywasz commandButton w ui:repeat i to nie jest jedyny mi znany BUG)

<h:commandButton >
    <f:ajax render="@form" execute="@form" />
</h:commandButton>

Tylko te elementy z id co stoja w execute beda wykonane. Ty id dla input nie zdefiniowales w commanButton. Nic dziwnego wiec ze nie zostal setter wykonany.

Scope nie ma w tym nic najmniejszego do czynienia. ManagedBean ktory jest jako RequestScoped w JSF 2.0 definiowany jest juz po nastepnym wywolaniu ajax tworzony od nowa, a nie po przeladowaniu strony. Zeby temu zapobiedz, trzeba uzyc ViewScope.

0

Niestety ten poniższy przykład nie działa

 
	<h:form id="formTest">

		<h:panelGrid columns="4" cellpadding="5">
			<h:outputLabel for="name" value="Name:" style="font-weight:bold" />

			<h:inputText id="firstname" value="#{testBean.firstname}" />

			<h:commandButton value="Submit" process="firstname"  >
 				<f:ajax render="display" execute="@this firstname" />
 			</h:commandButton>
			<h:outputText value="#{testBean.firstname}" id="display" />
		</h:panelGrid>

	</h:form>

Natomiast zmieniając wartości w atrybutach elementu <f:ajax> na poniższe:

 
<f:ajax render="@form" execute="@form" />

pojawił mi się jeden warning:
2012-03-06 1325 com.sun.faces.renderkit.html_basic.HtmlBasicRenderer getForComponent
WARNING: Unable to find component with ID name in view.

Jedno mnie zastanawia na stronie primefaces jest przykład, który powinien działać, ponieważ symulacja na stronie działa prawidłowo a kod przedstawia się następująco:

 
<h:form>  
                              
    <h:panelGrid columns="4" cellpadding="5">  
        <h:outputLabel for="name" value="Name:" style="font-weight:bold"/>  
          
        <p:inputText id="name" value="#{pprBean.firstname}" />  
          
        <p:commandButton value="Submit" update="display"/>  
  
        <h:outputText value="#{pprBean.firstname}" id="display" />  
    </h:panelGrid>  
      
</h:form>  

Następnie podane są gettery i settery w Bean i to teoretycznie powinno działać bez zarzutu. Problem może tkwić w mojej konfiguracji, ponieważ używam dispatchera w springu, który ma zdefiniowane kontrolery oraz jak ma renderować jsf

 
	<bean id="indexController" class="pl.test.controller.IndexController" />
	<bean id="testController" class="pl.test.controller.TestController" />

	<bean id="urlMapping"
		class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
		<property name="mappings">
			<props>
				<prop key="/index.xhtml">indexController</prop>
				<prop key="/test.xhtml">testController</prop>
			</props>
		</property>
	</bean>

	<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="cache" value="false" />
		<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".xhtml" />
	</bean>

Może tu tkwi jakiś problem?

0

<h:outputLabel for="name" value="Name:" style="font-weight:bold" />
w atrybucie for stoi ID elementu do ktorego ten element definiujesz, dlatego pojawia cie sie warning.

nie ma takiego atrybutu process dla h:commandButton

to musi dzialac. Poprawny kod by wygladal tak:

 <h:panelGrid columns="4" cellpadding="5">
                        <h:outputLabel for="firstname" value="Name:" style="font-weight:bold" />
                        <h:inputText id="firstname" value="#{testBean.firstname}" />
                        <h:commandButton value="Submit" actionListener="#{testBean.executeAction}"  >
                                 <f:ajax render="display" execute="@this firstname" />
                         </h:commandButton>
                        <h:outputText value="#{testBean.firstname}" id="display" />
                </h:panelGrid>

TestBean.java

@ManagedBean
@ViewScoped
public class TestBean {
        private String firstname;
       public void executeAction(ActionEvent e){
	}

	public String getFirstname() {
		return firstname;
	}

	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}
}

Testowalem to jeszcze dla pewnosci i dziala.

ps. nie musisz uzywac w tym przypadku h:panelGrid komponentu. h:panelGrid buduje tabele i w kazda komorke td wstawia jak leci po kolei zawarte elementy. W twoim przypadku jest to jeden rzad skladajacy sie z inline elementow, wiec bez h:panelGrid beda obok siebie ustawione.

0

Niestety dalej nie wchodzi do settera i nie ustawia zmiennej, wykonywany jest tylko getter i na tym koniec. Coś musi być w plikach konfiguracyjnych nie tak, w pliku faces-config.xml mam:

 
	<application>
		<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
	</application>

Urywek logów debug i trace, nie ma żadnych błędów:

 
2012-03-06 16:55:21,987 DEBUG [org.springframework.faces.support.RequestLoggingPhaseListener] - Entering JSF Phase: RESTORE_VIEW 1
2012-03-06 16:55:21,988 DEBUG [org.springframework.faces.mvc.JsfView] - Asking faces lifecycle to render
2012-03-06 16:55:21,988 DEBUG [org.springframework.faces.support.RequestLoggingPhaseListener] - Entering JSF Phase: RENDER_RESPONSE 6
2012-03-06 16:55:26,192 DEBUG [org.springframework.faces.mvc.JsfView] - View rendering complete
2012-03-06 16:55:26,192 DEBUG [org.springframework.web.servlet.DispatcherServlet] - Successfully completed request

Masz szczęście, że u Ciebie działa nie wiem co jest, że u mnie to nie działa. Mam jsf-api-2.1.7.jar i jsf-impl-2.1.7 próbowałem też z wersją 2.0.8 i to samo.

0

sprobuj zminimalizowac twoja aplikacje. Bez dodatkowych rzeczy. Usun te ustawienie el-resolver w faces-config.xml. Nigdy jeszcze mi sie nie zdazylo zebym musial to ustawiac. W moim testowym projekcie (server - tomcat 7) mam tylko dwie biblioteki JSF (jsf-api, jsf-impl), test.xhtml i pusty faces-config.xml. To wszystko.

0

@mwili el-resolver nic nie psuje, on tylko sprawia że można używać Springowych beanów tak samo jak managed beanów.

0

<el-resolwer> rzeczywiście niczego nie psuje, czy z nim czy bez niego to nie zmienia faktu, że nie wchodzi w settera i nie potrafię go zmusić, żeby wchodził. Problem może leżeć po stronie dispatchera, bo mam zdefiniowanego i pewnie po wejściu do kontrolera później dopiero do Beana może to powodować jakieś problemy. Nie mam innego pomysłu co może jeszcze powodować tutaj problem.

0

Problemem tego, że nie wchodzi do settera może być renderowanie strony przez klasy springowe:

 
	<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
		<property name="cache" value="false" />
		<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".xhtml" />
	</bean>

Zauważyłem, że w atrybucie action formularza dodawany jest prefix czyli "/WEB-INF/views/" przy kolejnym wywołaniu formularza ponownie dodawany jest prefix i to, że zmapowałem w web.xml ten prefix "/WEB-INF/views/" to już następne dodanie "/WEB-INF/views/WEB-INF/views/" jest błędem, który uniemożliwia poprawne działanie formularza. Czy może wie ktoś co jest tego przyczyną i czy może to mieć wpływ na brak wywołania settera właśnie to renderowanie?

0

Właściwie to chciałem się podzielić pewną refleksją na temat PrimeFaces. Otóż programowaniem zajmuje się od 12 lat i w ciągu tych 12 lat nigdy nie spotkałem softu o takiej ilości krytycznych błędów. Ilość błędów w PrimeFaces jest po prostu niewiarygodna. Wygląda na to, że twórca nawet nie zadaje sobie trudu aby przetestować własne dzieło. Mało tego, chwali się co trochę, że ilość wpisów na forum przekracza kolejne dziesiątki tysięcy wpisów. Ciekawe czy choć przez chwilę zastanowił się nad faktem, że ilość wpisów na forum świadczy o ilości problemów jakie mają programiści z jego dziełem. Na dodatek jest on arogancki i myśli, że stworzył najlepszy projekt świata. Z pewnością jest to produkt z największą ilością błędów na świecie. Totalny brak profesjonalizmu

0

W pracy uzywamy IceFaces i za czasow wersji 1.8.2 byl to jeden z najlepszych rozwiazan dopasowanych do naszych zastosowan. Tu wchodzily jeszcze wzgldedy strategiczne i polityczne w gre. IceFaces od wersji 3.0 to doslownie porazka. Placimy duzo kasy na support i do tego IceFaces od wersji 3.0 uzywa kodu od Primefaces. Chcemy przejsc na Primefaces i jak na razie na zadne powazne Bugi sie nie natknelismy (to byly proste testy). Mowie tu o najnowszej wersji Primefaces i nie o wersji 2.x, bo ona byla rzeczywscie z bledami.
Interesowalo by mnie bardzo z jakimi krytycznymi bledami spotkales sie w Primefaces 3.x ??

1 użytkowników online, w tym zalogowanych: 0, gości: 1