2010-08-15 6 views
4

j'ai un composant composite:composant composite JSF2 jets PropertyNotFoundException pour la méthode d'action

<composite:interface> 
    <composite:attribute name="actionMethod" 
     method-signature="java.lang.String action()" required="true" /> 
</composite:interface> 

<composite:implementation> 
    <h:form> 
     <h:commandButton id="captureButton" value="#{msgs.capture}" 
      action="#{cc.attrs.actionMethod}" /> 
    </h:form> 
</composite:implementation> 

et une page qui appelle ce que le composant composite:

<ezcomp:captureTitle actionMethod="#{saveDecisionsBean.captureTitle}" /> 

et un haricot qui contient l'action:

@Named(value="saveDecisionsBean") 
@SessionScoped 
public class SaveDecisionsBean extends BackingBeanBase { 
    ... 
    public String captureTitle() { 
     ... 
    } 
} 

Maintenant, voici mon problème. Lorsque j'essaie d'exécuter ceci, il est dit que SaveDecisionsBean n'a pas de propriété captureTitle. Par conséquent, je dois ajouter une méthode SaveDecisionsBean#getCaptureTitle(). Quand je fais cela, ça fonctionne très bien. Pourquoi devrais-je définir cette méthode? Il est dit dans le <composite:attribute /> que c'est une méthode, et que c'est une action.

Voici le message d'erreur exact que je reçois:

javax.el.PropertyNotFoundException: /index.xhtml @54,86 
    actionMethod="#{saveDecisionsBean.captureTitle}": 
    The class 'com.example.persistence.SaveDecisionsBean_$$_javassist_209' 
    does not have the property 'captureTitle'. 

(Pour des raisons de référencement:. Autres implémentations peuvent afficher le nom de la classe WeldClientProxy)

+0

comme commentaire, vous ne devez pas écrire @Named (valeur = "saveDecisionsBean") si c'est le même nom de la classe – Dejell

+0

Il le fait par défaut dans NetBeans. –

+0

En aparté, si ce qui précède aurait fonctionné, alors on pourrait aussi utiliser '', donc sans la 'méthode-signature'. Même problème cependant. – Arjan

Répondre

9

J'ai rencontré le même problème et j'ai découvert que c'était dû au fait que ma méthode d'action avait lancé IllegalArgumentException. En attendant, cela a été signalé comme un bug: Composite action method throws PropertyNotFoundException when method throws any exception. La partie délicate (au moins pour moi) était que mon application fonctionnait bien jusqu'à ce que je déplace une partie du code dans un composant composite (CC). Avant que mon application n'atteigne l'IAE et affiche un message d'erreur gentil mais en utilisant CC, la validation de JSF (ou n'importe quoi ...) l'attrape d'abord et produit ce message d'erreur plutôt confus.

J'ai vérifié cela en utilisant une version modifiée du code de test fourni par BalusC (voir ci-dessous). La page de test affiche deux composants de bouton d'entrée &. Si vous entrez quelque chose dans le champ de texte (en dehors de "panique" (sans guillemets)), la version CC et la version "inline" fonctionnent toutes deux (regardez la sortie std). Si vous entrez "panique" dans la version "inline", vous remarquerez l'IAE comme prévu, mais si vous entrez la même chose dans la "version CC" supérieure, vous verrez l'exception PropertyNotFoundException à la place. Semble que JSF est confus par l'IAE et décide que l'attribut doit être une propriété et pas une méthode d'action après tout ... Je ne sais pas si c'est un bug ou une fonctionnalité. Est-ce que selon Spec, quelqu'un le sait?Donc, la conclusion ici est que vous ne pouvez pas utiliser les méthodes d'action dans CC avec des beans qui lancent des exceptions. Pour moi, cela signifie que je ne peux pas utiliser les composants composites. Triste!

Hope this helps ...

/resources/components/test.xhtml 

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:cc="http://java.sun.com/jsf/composite"> 
<cc:interface> 
    <cc:attribute name="text"/> 
    <cc:attribute name="action" method-signature="java.lang.String action()" required="true" /> 
</cc:interface> 
<cc:implementation> 
    <h:form> 
    <h:inputText value="#{cc.attrs.text}"/> 
    <h:commandButton value="submit" action="#{cc.attrs.action}" /> 
    </h:form> 
</cc:implementation> 

/test.xhtml 

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:cc="http://java.sun.com/jsf/composite/components"> 
<h:head> 
    <title>Test</title> 
</h:head> 
<h:body> 
    <!-- text and cmd-button as cc --> 
    <cc:test text="#{bean.text}" action="#{bean.submit}" /> 

    <hr/> 

    <!-- text and cmd-buuton inline --> 
    <h:form id="inline"> 
    <h:inputText value="#{bean.text}"/> 
    <h:commandButton value="submit2" action="#{bean.submit}" /> 
    </h:form> 
</h:body> 
</html> 

Et enfin Bean:

@ManagedBean 
@RequestScoped 
public class Bean { 

    private String text; 

    public String getText() { 
    return text; 
    } 

    public void setText(String text) { 
    this.text = text; 
    } 

    public String submit() { 
     if (text.equalsIgnoreCase("panic")){ 
      throw new IllegalArgumentException("Panic!"); 
     } 

     System.out.println(text); 

     return null; 
    } 
} 
+0

Bien sûr, vous pourriez ajouter un message Faces au lieu de lancer IAE: – Jorgen

+0

FacesContext. getCurrentInstance(). addMessage (null, nouveau FacesMessage ("Some error ...."); Mais cela casse la séparation des beans (comme de simples POJO) et JSF/Faces – Jorgen

+2

Vous avez entièrement raison! C'est certainement un bug. Je rapporterai ceci aux garçons de JSF – BalusC

1

Odd, je ne peux pas reproduire ce avec Mojarra 2.0.2. Peut-être qu'il y a quelque chose de plus dans le code qui entre en collision avec l'un ou l'autre? Ou vous n'utilisez pas le code que vous pensez utiliser?

Par souci d'exhaustivité, je vais inclure les extraits de test, je l'habitude d'essayer de reproduire ce problème:

/resources/components/test.xhtml

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:cc="http://java.sun.com/jsf/composite"> 
    <cc:interface> 
     <cc:attribute name="action" method-signature="java.lang.String action()" required="true" /> 
    </cc:interface> 
    <cc:implementation> 
     <h:form> 
      <h:commandButton value="submit" action="#{cc.attrs.action}" /> 
     </h:form> 
    </cc:implementation> 
</html> 

/test.xhtml

<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:cc="http://java.sun.com/jsf/composite/components"> 
    <h:head> 
     <title>Test</title> 
    </h:head> 
    <h:body> 
     <cc:test action="#{bean.submit}" /> 
    </h:body> 
</html> 

com.example.Bean

package com.example; 

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.RequestScoped; 

@ManagedBean 
@RequestScoped 
public class Bean { 

    public String submit() { 
     System.out.println("submit"); 
     return null; 
    } 

} 

Est-ce que ce qui précède fonctionne aussi pour vous?

+0

Cela fonctionne très bien pour moi, même en utilisant CDI. Je vais devoir regarder plus loin. –

+0

Peut-être un formulaire imbriqué? Voir aussi [cette réponse] (http://stackoverflow.com/questions/2118656/hcommandlink-is-not-being-invoked/2120183#2120183) pour d'autres indices. – BalusC

+0

Il n'y a certainement pas de formulaire imbriqué ... I ** do ** utilise CDI dans le bean (j'injecte 3 beans différents de deux portées différentes.) J'utilise aussi les paramètres de vue requis. Je n'imagine pas que cela serait dû au fait que les problèmes avec l'insaniation ou les paramètres d'affichage lanceraient des exceptions bien avant d'essayer d'appeler l'action –

Questions connexes