ViewParam vs @ManagedProperty (valeur = "# {param.id}")

97

Quelle est la différence entre définir des paramètres de vue comme ceci:

<f:metadata>
  <f:viewParam name="id" value="#{someBean.id}"/>
</f:metadata>

Et définissant la propriété dans le ManagedBean comme ceci:

@ManagedProperty(value = "#{param.id}")
private Integer id;
ehsun7b
la source

Réponses:

144

<f:viewParam>:

  • Définit la valeur pendant la phase de mise à jour des valeurs du modèle uniquement (car elle s'étend UIInput).

  • La valeur définie n'est pas disponible pendant @PostConstruct, vous avez donc besoin d'un <f:event type="preRenderView" listener="#{bean.init}" />élément supplémentaire à l'intérieur du <f:metadata>pour effectuer l'initialisation / le préchargement en fonction des valeurs définies. Depuis JSF 2.2, vous pouvez utiliser <f:viewAction>pour cela à la place.

  • Permet une conversion / validation imbriquée <f:converter>et <f:validator>plus fine. Même un <h:message>peut être attaché.

  • Peut être inclus en tant que chaîne de requête GET à l'aide de l' includeViewParamsattribut <h:link>ou du includeViewParams=trueparamètre de requête dans n'importe quelle URL.

  • Peut être utilisé sur un @RequestScopedbean, mais il nécessite que le bean soit @ViewScopedsi vous voulez que les paramètres de vue survivent aux échecs de validation causés par les formulaires inclus dans la vue, sinon vous devez conserver manuellement tous les paramètres de demande pour les demandes suivantes <f:param>dans la commande Composants.

Exemple :

<f:metadata>
    <f:viewParam id="user_id" name="id" value="#{bean.user}"
        required="true" requiredMessage="Invalid page access. Please use a link from within the system."
        converter="userConverter" converterMessage="Unknown user ID."
    />
</f:metadata>
<h:message for="user_id" />

avec

private User user;

et un @FacesConverter("userConverter"). L'appel de la page par http://example.com/context/user.xhtml?id=123 passera le idparamètre via le convertisseur et définira l' Userobjet comme propriété de bean.


@ManagedProperty:

  • Définit la valeur immédiatement après la construction du bean.

  • La valeur définie est disponible pendant @PostConstructlaquelle permet une initialisation / préchargement facile d'autres propriétés en fonction de la valeur définie.

  • Ne permet pas la conversion / validation déclarative en vue.

  • La propriété gérée de #{param}n'est pas autorisée sur les beans avec une portée plus large que la portée de la requête, le bean doit donc être @RequestScoped.

  • Si vous comptez sur la #{param}présence d'une propriété gérée dans les requêtes POST suivantes, vous devez l'inclure comme <f:param>dans les UICommandcomposants.

Exemple :

@ManagedProperty("#{param.id}")
private Long id;

private User user;

@EJB
private UserService userService;

@PostConstruct
public void init() {
    user = userService.find(id);
}

Mais vous devez gérer vous-même la validation chaque fois que userc'est nullen tripotant FacesContext#addMessage()ou quelque chose.


Vous pouvez les utiliser à la fois lorsque les deux @PostConstructet includeViewParamssont obligatoires. Vous ne pourrez plus appliquer de conversion / validation fine.


Voir également:

BalusC
la source
1
Il existe d'autres alternatives pour récupérer les paramètres de requête dans des cas exceptionnels: FacesContext.getCurrentInstance (). GetExternalContext (). GetRequestParameterMap (). Get ("nom_paramètre");
angelcervera
1
@angel: Uniquement lorsque le bean a une portée plus large que la portée de la requête, ce qui rend @ManagedPropertyimpossible un paramètre de requête.
BalusC
salut @BalusC Je me fie à la valeur de l'id récupérée de param.id en utilisant managedproperty sur un deuxième message. Comment puis-je l'inclure en utilisant f: param? merci beaucoup
sys_debug
1
@thufir: il est défini lors de la phase de mise à jour des valeurs du modèle. La postconstruct fonctionne bien avant cela, juste après la construction du bean et l'injection de dépendances. Il est disponible dans la méthode d'écoute qui est appelée par <f:event type="preRenderView">ou le prochain JSF 2.2 <f:viewAction>.
BalusC
6

2 autres différences:

  • @ManagedPropertyest utilisable uniquement avec des beans gérés par JSF, pas avec des beans gérés par CDI ( @Named);
    • <f:viewParam> fonctionne uniquement avec les paramètres des requêtes GET.
user1643352
la source
1
Par conséquent, vous pouvez utiliser l'annotation: org.omnifaces.cdi.Param
dforce