JSF开发人员应该知道的5种有用方法

这篇文章的目的是总结一些JSF开发人员可以在日常工作中使用的便捷方法。 实用程序类是将所有方法放在一起的好地方。 我会称此类为FacesAccessor。 第一种方法可能是最常用的方法。 它以给定名称返回托管bean。

必须按faces-config.xml或注释注册该bean。 注入是好的,但是有时如果很少调用bean,则不必将bean相互注入。

public static Object getManagedBean(final String beanName) {
    FacesContext fc = FacesContext.getCurrentInstance();
    Object bean;
    
    try {
        ELContext elContext = fc.getELContext();
        bean = elContext.getELResolver().getValue(elContext, null, beanName);
    } catch (RuntimeException e) {
        throw new FacesException(e.getMessage(), e);
    }

    if (bean == null) {
        throw new FacesException("Managed bean with name '" + beanName
            + "' was not found. Check your faces-config.xml or @ManagedBean annotation.");
    }

    return bean;
}

使用:

@ManagedBean
public class PersonBean {
    ...
}

PersonBean personBean = (PersonBean)FacesAccessor.getManagedBean("personBean");

// do something with personBean

第二种方法对JSF组件开发人员以及所有想要评估给定值表达式#{…}并将结果设置为给定值的人都非常有用。

public static void setValue2ValueExpression(final Object value, final String expression) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();

    ValueExpression targetExpression = 
        facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object.class);
    targetExpression.setValue(elContext, value);
}

使用:
我个人将这种方法用于“注销功能”。 用户注销后,他/她将看到一个特殊的“注销页面”。 “注销页面”使用来自sesion作用域bean的用户设置(例如主题,语言等)。 但是由于会话无效,因此该会话作用域bean不再存在。 该怎么办? 这是我的注销方法中的代码片段。

UserSettings userSettings = (UserSettings) FacesAccessor.getManagedBean("userSettings");

// invalidate session
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
HttpSession session = (HttpSession) ec.getSession(false);
session.invalidate();

// create new session
((HttpServletRequest) ec.getRequest()).getSession(true);

// restore last used user settings because login / logout pages reference "userSettings"
FacesAccessor.setValue2ValueExpression(userSettings, "#{userSettings}");

// redirect to the specified logout page
ec.redirect(ec.getRequestContextPath() + "/views/logout.jsf");

第三种方法将变量映射到给定的值表达式#{…}。 它使用javax.el.VariableMapper将表达式分配给指定的变量,以便对该变量的任何引用都将被EL评估中的表达式替换。

public static void mapVariable2ValueExpression(final String variable, final String expression) {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ELContext elContext = facesContext.getELContext();
    
    ValueExpression targetExpression =
        facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object.class);
    elContext.getVariableMapper().setVariable(variable, targetExpression);
}

使用:
假设“ PersonBean”是一个具有“ name”属性的托管Bean,“ PersonsBean”是一个包含“ PersonBean”的许多实例(作为数组,集合或映射)的Bean。 以下代码允许将“ personBean”用作对具有“ name” Oleg的特定bean的引用。

FacesAccessor.mapVariable2ValueExpression("personBean", "#{personsBean.person['Oleg']}");

在facelets页面中,这样说一下personDetail.xhtml,我们可以编写:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html">
<ui:composition>
    ...
    <h:inputText value="#{personBean.name}"/>
    ...
</ui:composition>
</html>

注意,参考“ personBean”是在Java中设置的。 还可以通过ui:include / ui:param以声明的方式在facelet中使用此映射。

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition>
    ...
    <ui:include src="personDetail.xhtml">
        <ui:param name="personBean" value="#{personsBean.person['Oleg']}"/>
    </ui:include>
    ...
</ui:composition>
</html>

接下来的两个方法用于以编程方式创建MethodExpression / MethodExpressionActionListener。 如果您通过“ binding”属性使用组件绑定或在Java中创建一些模型类,则它们非常方便。

public static MethodExpression createMethodExpression(String valueExpression,
                                                      Class<?> expectedReturnType,
                                                      Class<?>[] expectedParamTypes) {
    MethodExpression methodExpression = null;
    try {
        FacesContext fc = FacesContext.getCurrentInstance();
        ExpressionFactory factory = fc.getApplication().getExpressionFactory();
        methodExpression = factory.
            createMethodExpression(fc.getELContext(), valueExpression, expectedReturnType, expectedParamTypes);
    } catch (Exception e) {
        throw new FacesException("Method expression '" + valueExpression + "' could not be created.");
    }
    
    return methodExpression;
}

public static MethodExpressionActionListener createMethodActionListener(String valueExpression,
                                                                        Class<?> expectedReturnType,
                                                                        Class<?>[] expectedParamTypes) {
    MethodExpressionActionListener actionListener = null;
    try {
        actionListener = new MethodExpressionActionListener(createMethodExpression(
            valueExpression, expectedReturnType, expectedParamTypes));
    } catch (Exception e) {
        throw new FacesException("Method expression for ActionListener '" + valueExpression
                          + "' could not be created.");
    }

    return actionListener;
}

使用:
在我的一个项目中,我以编程方式创建了带有菜单项的PrimeFaces MenuModel。

MenuItem mi = new MenuItem();
mi.setAjax(true);
mi.setValue(...);
mi.setProcess(...);
mi.setUpdate(...);
mi.setActionExpression(FacesAccessor.createMethodExpression(
    "#{navigationContext.setBreadcrumbSelection}", String.class, new Class[] {}));

UIParameter param = new UIParameter();
param.setId(...);
param.setName(...);
param.setValue(...);
mi.getChildren().add(param);

您想在这里分享什么好方法吗? 欢迎使用提示/技巧。

参考: 5种有用的方法JSF开发人员应该从我们的JCG合作伙伴 Oleg Varaksin的“软件开发思想”博客中了解到。


翻译自: https://www.javacodegeeks.com/2012/04/5-useful-methods-jsf-developers-should.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值