icefaces 2 - navigation rules problem

0

hej, probuje przerobic do icefaces2 bardzo prosta rzecz:
mianowicie - mam zwykla tabelke z uzytkownikami, w niej tez przyciski jakies typu "show details". to jest dostepne dla niezalogowanego uzytkownika. jak sie zaloguje, to wlasnie ma przycisk typu "remove" jeszcze dodatkowo. Wszystko fajnie, ale jak sie zaloguje i klikne na "remove" to on jakby traci info o tym ze jestem zalogowana, i opcja "remove" sie chowa. mniej wiecej to wyglada tak:
stad mam uzytkownikow:

@ManagedBean(name="usersList")
@ViewScoped
public class UsersList implements Serializable{
  private ArrayList<UserBean> usersBeanList;

  public ArrayList<UserBean> getUsersBeanList(){
  //odpowiedni kod
}

}
 

autoryzacja:

@ManagedBean(name="auth")

public class Authorization implements Serializable{
     private boolean logged;
   private boolean authFails = true;

public String login() {

      String result = "auth-false";
   //odpowiedni kod, jak sie zalogoujesz to ustawiane sa:
             logged = true;
            result = "auth-true";
            authFails = false;
  
return result;

}
}
 

no i faces-config:

   <navigation-rule>
      <from-view-id>*</from-view-id>
      <navigation-case>
         <from-outcome>users</from-outcome>
         <to-view-id>/users.xhtml</to-view-id>
         <redirect />
      </navigation-case>
   </navigation-rule>

   <navigation-rule>
      <from-view-id>/users.jsf</from-view-id>
      <navigation-case>
         <from-action>#{usersList.login}</from-action>
         <from-outcome>login</from-outcome>
         <to-view-id>/login.jsf</to-view-id>
      </navigation-case>
   </navigation-rule>

   <navigation-rule>
      <from-view-id>*</from-view-id>
      <navigation-case>
          <from-action>#{auth.login}</from-action>
         <from-outcome>auth-true</from-outcome>
         <to-view-id>/users.xhtml</to-view-id>
      </navigation-case>
   </navigation-rule>

   <navigation-rule>
      <from-view-id>*</from-view-id>
      <navigation-case>
         <from-action>#{auth.login}</from-action>
         <from-outcome>auth-false</from-outcome>
         <to-view-id>/login.xhtml</to-view-id>
      </navigation-case>
   </navigation-rule>
 

no i jak przychodzi auth-true to przechodzi mi znow do users.xhtml, tylko ze teraz mam wiecej opcji, ale wlasnie jak tam cos klikne to on traci info ze jest zalogowany i te opcje znikaja. users.xhtml:

   <ice:form>
         <div align="left">
            <h:panelGrid columns="2"  cellpadding="0" cellspacing="0">
               <f:facet name="header">
                  <ice:outputText value="Logging:" rendered="#{auth.logged==false}"/>
               </f:facet>
               <ice:commandButton id="login" value="login" action="#{usersList.login}" rendered="#{auth.logged==false}"/>
               <ice:commandButton id="logout" value="logout" action="#{auth.logout}" rendered="#{auth.logged==true}"/>
            </h:panelGrid>
         </div>
         <br/>

         <ice:dataTable cellpadding="0" cellspacing="0" border="1"
                        rendered="#{usersList.usersBeanListSize != 0}"
                        value="#{usersList.usersBeanList}"
                        columnClasses="columnsColumn"
                        var="item"
                        rows="#{usersList.usersBeanListSize}">
            <ice:column style="width:130px; height:15px;" >
               <f:facet name="header" >
                  <ice:outputText value="User" />
               </f:facet>
               <ice:outputText value="#{item.name}"
                               rendered="#{item.edit==false}"/>
               <br/>
               <ice:outputText value="#{item.surname} "
                               style="width:120px; height:15px;"
                               rendered="#{item.showAdditionalInfo==true
                                           and item.edit==false}"/>

               <ice:outputText value="#{item.email} "
                               style="width:120px; height:15px;"
                               rendered="#{item.showAdditionalInfo==true
                                           and item.edit==false}"/>

            </ice:column>

            <ice:column style="width:220px; height:15px;">
               <f:facet name="header">
                  <ice:outputText value="Additional info"/>
               </f:facet>
               <div align="center">
                  <ice:commandButton id="show_info" value="show info"
                                     action="#{item.setShowAdditionalInfo}"
                                     rendered="#{item.showAdditionalInfo==false}"/>
                  <ice:commandButton id="hide_info" value="hide info"
                                     action="#{item.unsetShowAdditionalInfo}"
                                     rendered="#{item.showAdditionalInfo==true}"/>
               </div>
            </ice:column>

            <ice:column style="width:220px; height:15px;" rendered="#{auth.logged==true}">
               <f:facet name="header">
                  <ice:outputText value="Actions"/>
               </f:facet>
               <div align="center">
                  <ice:commandButton id="remove_user" value="remove" actionListener="#{usersList.removeUser}">
                     <f:attribute name="userBean" value="#{item}"/>
                  </ice:commandButton>
               </div>
            </ice:column>
         </ice:dataTable>


      </ice:form>

totalnie nie wiem co z tym.. pewnie problem jest jakis banalny, czegos nie ustawiam albo cos. czy ktos z Was moze ma jakis pomysl?

pzdr,
misty

0

pierwsze co sie w oczy rzuce jest to, ze w klasie Authorization nie jest scope zdefiniowany. Przypuszczam ze standarowo jest w takim przypadku request scope przypisany, co by tlumaczylo powod dlaczego informacje po zalogowaniu nie sa po zapytaniu dostepne. Jak tak klasa ma przechowywac informacje o zalogowaniu uzytkownika to nadaj jej scope session:

@SessionScoped
public class Authorization implements Serializable

zamiast
rendered="#{auth.logged==false}"
mozesz przeciez tez tak napisac:
rendered="#{auth.logged}"

no i co ma tresc tytulu watku do twojego problemu??

0

czesc,
dzieki za odpowiedz. wiesz, ja probowalam juz z :

 
@SessionScoped
public class Authorization implements Serializable

ale wtedy nie dziala mi przycisk, nie przechodzi do strony! czyli nie jest wywolywana regula nawigacji:

   <navigation-rule>
      <from-view-id>*</from-view-id>
      <navigation-case>
          <from-action>#{auth.login}</from-action>
         <from-outcome>auth-true</from-outcome>
         <to-view-id>/users.xhtml</to-view-id>
      </navigation-case>
   </navigation-rule> 

czyli po poprawnym wpisaniu loginu i hasla i kliknieciu w przycisk 'zaloguj' nic sie nie dzieje!!! co ciekawe, jak podam np zly login to jest wywolywane:

    <navigation-rule>
      <from-view-id>*</from-view-id>
      <navigation-case>
         <from-action>#{auth.login}</from-action>
         <from-outcome>auth-false</from-outcome>
         <to-view-id>/login.xhtml</to-view-id>
      </navigation-case>
   </navigation-rule>

tzn wiem ze jest, bo pokazuja sie moje info o bledzie logowania.. nie kumam totalnie czemu tak to jest.
no a jak wlasnie usune @SessionScoped to po kliknieciu w 'zaloguj' przechodzi mi do <to-view-id>/users.xhtml</to-view-id>

masz jakis pomysl na to?

          pzdr,
          misty
0

Nie mam teraz tyle czasu aby caly kod przeanalizowac, ale zauwazylem dwie rzeczy ktore moga pomoc:
1)
w faces-config wyrzuc from-action i zrob tak :

	
    <navigation-rule>
    	<from-view-id>*</from-view-id>
    	<navigation-case>
    	     <from-outcome>auth-true</from-outcome>
    		<to-view-id>/users.xhtml</to-view-id>
    		<redirect/>
    	</navigation-case>
    	<navigation-case>
    	     <from-outcome>auth-false</from-outcome>
    		<to-view-id>/login.xhtml</to-view-id>
    	</navigation-case>
    </navigation-rule>

jestes pewny, ze strony powinny byc z rozszerzeniem .xhml ?? nie .jsf albo .iface ?
mappowanie musi byc zdefiniowane w web.xml

<ice:commandButton id="login" value="login" action="#{usersList.login}" rendered="#{auth.logged==false}"/>
nie powinno byc action="#{auth.login}" ??
usersList.login nie istnieje wiec do action bedzie po prostu wartosc NULL przypisana i nic nie bedzie sie dzialo.

  1. Uzywajac JSF 2.0 mozesz zupelnie zrezygnowac z navigation rules w facelet-config. W action zwroc po prostu rzadana strone, bez rozszerzenia:
public String login() {
 
      String result = "/login?faces-redirect=true";   // dobrze jest zrobic przekierowanie, aby przy odswierzeniu strony nie wysylac jeszcze raz danych
   //odpowiedni kod, jak sie zalogoujesz to ustawiane sa:
             logged = true;
            result = "/users?faces-redirect=true";
            authFails = false;
 
return result;
 
}

raz podajesz
<to-view-id>/login.jsf</to-view-id>

a raz
<to-view-id>/login.xhml</to-view-id>
co to ma byc?????

jedno to nazwa logiczna a druga fizyczna. Jak masz mapping ustawiony?

0

hej, dzieki za odpowiedz i przepraszam ze dopiero teraz odpisuje. Awiec-po kolei.

  1. Mapowanie w web.xml (mam to ze str icefaces)
    <!-- extension mapping -->
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
        <url-pattern>*.iface</url-pattern>
        <url-pattern>/icefaces/*</url-pattern>
    </servlet-mapping>
 
  1. Po Twoich poprawkach, moj faces-config wyglada teraz tak:
 <navigation-rule>
      <from-view-id>*</from-view-id>
      <navigation-case>
         <from-outcome>users</from-outcome>
         <to-view-id>/users.xhtml</to-view-id>
         <redirect />
      </navigation-case>
   </navigation-rule>

   <navigation-rule>
      <from-view-id>/users.jsf</from-view-id>
      <navigation-case>
         <from-action>#{usersList.login}</from-action>
         <from-outcome>login</from-outcome>
         <to-view-id>/login.jsf</to-view-id>
      </navigation-case>
   </navigation-rule>


    <navigation-rule>
            <from-view-id>*</from-view-id>
            <navigation-case>
                 <from-outcome>auth-true</from-outcome>
                    <to-view-id>/users.xhtml</to-view-id>
                    <redirect/>
            </navigation-case>
            <navigation-case>
                 <from-outcome>auth-false</from-outcome>
                    <to-view-id>/login.xhtml</to-view-id>
            </navigation-case>
    </navigation-rule>
 
  1. Klasy UsersList i Authorization
 
@ManagedBean(name="usersList")
@ViewScoped
public class UsersList implements Serializable{}

@ManagedBean(name="auth")
@SessionScoped
public class Authorization implements Serializable{}
  1. Sa 2 pliki z rozszerzeniem xhtml (tak jest na str icefaces):

users.xhtml - ktorego fragment kodu przedstawilam w poprzednim poscie oraz login.xhtml

 
      <ice:form>
         <ice:panelGrid columns="2" cellpadding="0" cellspacing="0">
            <f:facet name="header">
               <ice:outputLabel value="Logging:"></ice:outputLabel>
            </f:facet>
            <ice:outputLabel value="Login:" />
            <ice:inputText id="login" value="#{auth.login}" required="true"/>
            <ice:outputLabel value="Password:" />
            <ice:inputSecret id="password" value="#{auth.password}" required="true"/>
            <ice:commandButton value="Login" style="margin-left: 10px" action="#{auth.login}"/>
         </ice:panelGrid>
         <ice:messages style="color:red; font-size:12px;"/>
      </ice:form>

Wpierw widzmy to co jest w users.xhtml, jak klikamy tam na "zaloguj" to wywolywana jest metoda login w klasie UsersList ktora zwraca String "login". Zgodnie z regula nawigacji, zostaje przeniesiona do login.jsf. Tam mamy prosty formularz logowania i klikniecie na przycisk "zaloguj" powoduje wywolanie metody login z klasy Authorization - ktora zwraca String "auth-true" gdy sie udalo lub "auth-false" gdy nie. Reszte historii znasz :)
Generalnie ta zmiana w regulach nawigacji niestety nie pomogla.

jestes pewny, ze strony powinny byc z rozszerzeniem .xhml ?? nie .jsf albo .iface ?

no na str icefaces 2 opieraja sie teraz na tych xhtml.

"<to-view-id>/login.jsf</to-view-id>
a raz
<to-view-id>/login.xhml</to-view-id>
co to ma byc?????
jedno to nazwa logiczna a druga fizyczna"

Przyznam szczerze ze nie wiem jak powinno byc poprawnie i czy w sumie to robi roznice. Bo tak na prawde to ja nie mam pliku login.jsf tylko login.xhtml - tam mnie przekierowuje. Wiec chyba nie ma roznicy czy podam login.jsf (bo i tak pojde do xhtml) czy login.xhtml. Ale moze sie myle. Bede wdzieczna za wszystkie uwagi bo w icefaces (zwlaszcza 2) specem nie jestem.

Masz jakis nowy pomysl na to, czemu mi nie dziala przekierowanie po poprawnym zalogowaniu? Chcialabym uniknac zwracania strony w action. tj. chcialabym miec to zrobione za pomoca faces-config.

pzdr,
misty

0

wiesz co, znalazlam blad. i nie mial on nic wspolnego z regula nawigacji. Problem byl w metodzie login klasy Authorize. metoda ta miala mniej wiecej taka strukture:

 
   public String authorize() {

      String result = "auth-false";

  try{

//odpowiednia logika. jak uzytkownik podal dobre dane to ustawiam result="auth-true"

} catch(Exception e){
//exception
} finally{
//sprzatanie
}
 return result;
}

Zaczelam analizowac troche ten kod i wyszlo na to, ze on po finally sie nie wykonuje.. jak przenioslam "return result" do bloku finally to jest ok. i totalnie tego nie kumam!! dlaczego nie wykonywal sie kod po finally? Co bylo wtedy zwracane? W sumie to powinno byc zwracane "auth-true" (w przypadku poprawnych danych. bo to jest ustawiane w try). Jestes w stanie mi to wytlumaczyc? A takze-jesli masz jakies uwagi do tego co Ci przedstawilam z ifaces to chetnie wyslucham :)

pzdr,
misty

0

moze pokaz caly kod, bo ten co wkleilas to powinien sie wykonac. Masz racje, w navigation-rule wykona sie zarowno .xhtml jak i .jsf, mimo to trzymal bym sie konsekwentnie jednej rzeczy.
Co do uwag to

  • jak pisalem wczesniej, bym zrezygnowal z navigation-rules w faces-config
  • zamiast rendered="#{item.showAdditionalInfo==true}" wystarczy rendered="#{item.showAdditionalInfo}"
  • w miare mozliwosci (moje subiektywne zdanie) zrezygnowal z nazywania ManagedBean, czyli
    zamiast
    @ManagedBean(name="auth")
    public class Authorization

wystarczylo by
@ManagedBean
public class Authorization

w tym wypadku w ramach konwencji automatycznie bedzie name="authorization" nadane. Nazwa klasy pisana mala litera. Widac od razu w EL od jakiej Klasy pochodzi ManagedBean.

  • Authorization bym nazwal AuthorizationBean. Nie jest powiedziane ze tak trzeba robic, ale w duzym projekcie mozna sie potem szybko pogubic.

  • jesli tu nie uzywasz nawigacji
    <ice:commandButton id="show_info" value="show info" action="#{item.setShowAdditionalInfo}" rendered="#{item.showAdditionalInfo==false}"/>

to zamiast action uzyl bym actionListener

nazwa metody do action="#{item.setShowAdditionalInfo}" jest tez nie przejzysta. Dlaczego sie na zywa setShowAdditionalInfo() ??
takie metody sa typu void , a ta w action musi ci zwrocic string.

0

czesc :)

po pierwsze-dzieki za komentarze i uwagi! Jesli chodzi o ten kod autoryzacji-to zostawmy go na razie. Mam inna dziwna rzecz. Patrz-dodawanie uzytkownika, pare pol, wypelniam, dodaje a tu mi icefaces sypie:

java.io.NotSerializableException 

sypie mi to ze moja klasa (DbManager, ktora zawiera uchwyt do polaczenia z db). No dobra, zrobilam ja serializable (ale w sumie to czemu???). I sypnal o kolejna klase (DbProperties - klasa ktora czyta propertiesy, zawiera konfiguracje). No i ja zrobilam serializable (znow-po co?). i teraz mi sypnal:

 Caused by: java.io.NotSerializableException: org.postgresql.jdbc4.Jdbc4Connection 

lool. z tym to juz totalnie nie wiem co zrobic?

spotkales sie z czyms takim?

najdziwniejsze jest to, ze mam kod ktory dodaje/edytuje uzytkownikow i jest ok wszystko..

pzdr,
misty

0

hej,
poradzilam sobie z tym problemem. Wywolywalam nie ten PreparedStatement (mam klase ktora mi zwraca rozne PrepredStatementy) i pozniej sie zorientowalam-wywolalam poprawny i jest ok. Ale totalnie nie rozumiem dlaczego nie dostawalam SQLException tylko takie dziwne rzeczy:|

mniejsza o to.
mam jeszcze jedno pytanie, teraz juz prostsze. Jest maly formularz do dodawania uzytkownikow. Dodaje, uzytkownik sie zapisuje, formularz jest chowany. Jak znow klikne na "dodaj uzytkownika" (bo chce znow dodac), formularz sie pokazuje i.. pola sa wypelnione tymi danymi poprzednio dodanego uzytkownika. Jak moge to zrobic aby te pola sie czyscily?
od str icefaces to wyglada tak:

 
<ice:commandButton value="Add"
			rendered="#{auth.logged and !userBeanManager.add}"
			action="#{userBeanManager.setAddMode}" />

		<ice:panelGrid columns="2" style="width: 400px;" border="1"
			rendered="#{userBeanManager.add}">
			<ice:outputText value="Name" />
			<ice:inputText value="#{user.name}" />

			<ice:outputText value="Surname" />
			<ice:inputText value="#{user.surname}" />

			<ice:outputText value="Email" />
			<ice:inputText value="#{user.email}" />

			<ice:outputText value="phone" />
			<ice:inputText value="#{user.phone}" />

			<ice:outputText value="Birthdate" />
			<ice:inputText value="#{user.birthdate}" />
		</ice:panelGrid>

		<ice:commandButton value="Add new user"
			rendered="#{userBeanManager.add}"
			actionListener="#{userBeanManager.addNewUser}">
			<f:attribute name="addUserBean" value="#{user}" />
		</ice:commandButton>

user to jest managedBean:

 
@ManagedBean(name = "user")
@SessionScoped
public class UserBean implements Serializable {
//gettry i settery

}

Bede wdzieczna za kazda wskazowke.

pzdr :)
misty

0

Mozna zrobic to na wiele sposobow, nie wiem jak wyglada logika w twojej apliakacji. Jedna z mozliwosci bylo by

  • przeniesienie add i addNewUser() do klasy UserBean:
  • wyzucenia <f:attribute name="addUserBean" value="#{user}" />
    Po co komplikowac sobie nie potrzebnie?
 
@ManagedBean
@SessionScoped
public class UserBean implements Serializable {
   private List<User> users;
   private boolean add;
  // reszta pol
  public void addNewUser(ActionEvent e){
        //jakis validator i jesli jest ok to
        users.add(new User(this.email, this.name, this.surname,this.phone, this.birthdate));
        add = !add;
        clear(); // w zaleznosci od logiki programu mozna by bylo to tez przeniesc do setAddMode() 
  }
  public String setAddMode(){
     // cos tu sie robi miedzy innymi moze i to:
     add = !add;  // add jest tu zawsze true, mozna by tez zrobic add = false;
     return null;
  }
  private void clear(){
      
     //wyczyscic pola w UserBean np:
      this.email="";
      this.name="";
      this.surname="";
      this.phone=""; 
      this.birthdate="";
  }
}

jesli nie chcesz tego tam przenosic to mozesz dostac sie z klasy UserBeanManager do UseBean dzieki @ManagedProperty (zamiast definiowania f:attribute), chociaz uwazam ze rozwiazanie u gory jest przejrzysciejsze.

np:

public class UserBeanManager implements Serializable {
         @ManagedProperty(value="#{user}")
	 private UseBean user;

         public void addNewUser(ActionEvent e){
       
       // cos tu sie robi
          user.clear(); 
       }     
}

osobiscie przypisywal bym wartosci w EL do twojego modelu, czyli tak:

<ice:outputText value="phone" />
<ice:inputText value="#{userBean.user.phone}" />

Twoje Entity User ma juz tez getter i setter, wiec nie potrzebnie robic to samo w UserBean (chyba ze tak nie zrobilas)

<ice:outputText value="phone" />
<ice:inputText value="#{userBean.user.phone}" />
@ManagedBean
@SessionScoped
public class UserBean implements Serializable {
      private User user;

      public void addNewUser(ActionEvent e){
         //jesli przejdzie walidacje
         UserManager.save(user.copy());

          user = new User(); 
  }
}

przepisz to, nie kopiuj. Pisalem z glowy wiec moze byc jakas literowka.

0

czesc,
dzieki za odpowiedz. Sprawdze to wieczorem, mam nadzieje ze pomoze. Poki co-mam jeszcze pytanie nie do konca zwiazane ze formularzami, ale tez z icefaces. Robiles wykresy? Znalazlam stronke z przykladami, bardzo fajna:
http://facestutorials.icefaces.org/tutorial/outputChart-tutorial.html

ale totalnie nie kumam jak sie tam definiuje dane. tj masz dla tych wykresow zdefiniowane:

	private static final List data = new ArrayList(
			Arrays.asList(new double[][] { new double[] { 350, 50, 400 },
					new double[] { 45, 145, 50 }, new double[] { -36, 6, 98 },
					new double[] { 66, 166, 74 },
					new double[] { 145, 105, 55 }, new double[] { 80, 110, 4 },
					new double[] { 10, 90, 70 } }));

 

czym sa poszczegolne elementy? wezmy pierwszy:
new double[] { 350, 50, 400 },

tak jak podejrzalam na wykresie to "350" jest to wysokosc slupka czy tam polozenie (wysokosc) punktu-jednym slowem to jest Y. ale pozostale dwie wartosci, tj 50 i 400? Jak je pozamienialam na 0 to slupek mialam tak samo namalowany. Sprawdzilam dokumentacje, ale tam nic mi nie rozjasnilo, bo pisza:
**Data of the chart. The valud of this attribute can be defined on page or can be bound to the backing bean:
(e.g.) defining on page

<ice:outputChart type="pie2d" labels="pass, fail" data="70, 30" colors="green, red"/> dataset can be defined using the colon ":" <ice:outputChart type="barstacked" labels="pass, fail" data="70, 30, 10 : 10, 50, 70" colors="green, red"/>

This attribute's value has correlation with the labels and color attribute.
if the value bounded with backing bean:
double or 2d double array
List of double or 2d double array
**

nie kapuje.. czym sa te 2 pozostale wartosci? orientujesz sie moze cos w tym temacie?

pozdrawiam i jeszcze raz dzieki,
misty

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