5 useful methods JSF developers should know

form: http://www.javacodegeeks.com/2012/04/5-useful-methods-jsf-developers-should.html

收藏一下。

The aim of this post is a summary about some handy methods for JSF developers they can use in their day-to-day work. An utility class is a good place to put all methods together. I would call such class FacesAccessor. The first method is probably the most used one. It returns managed bean by the given name. The bean must be registered either per faces-config.xml or annotation. Injection is good, but sometimes if beans are rare called, it’s not necessary to inject beans into each other.

01public static Object getManagedBean(final String beanName) {
02    FacesContext fc = FacesContext.getCurrentInstance();
03    Object bean;
04     
05    try {
06        ELContext elContext = fc.getELContext();
07        bean = elContext.getELResolver().getValue(elContext, null, beanName);
08    } catch (RuntimeException e) {
09        throw new FacesException(e.getMessage(), e);
10    }
11 
12    if (bean == null) {
13        throw new FacesException("Managed bean with name '" + beanName
14            + "' was not found. Check your faces-config.xml or @ManagedBean annotation.");
15    }
16 
17    return bean;
18}

Using:

1@ManagedBean
2public class PersonBean {
3    ...
4}
5 
6PersonBean personBean = (PersonBean)FacesAccessor.getManagedBean("personBean");
7 
8// do something with personBean

The second method is useful for JSF component developers and everyone who would like to evaluate the given value expression #{…} and sets the result to the given value.

1public static void setValue2ValueExpression(final Object value, final String expression) {
2    FacesContext facesContext = FacesContext.getCurrentInstance();
3    ELContext elContext = facesContext.getELContext();
4 
5    ValueExpression targetExpression =
6        facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object.class);
7    targetExpression.setValue(elContext, value);
8}

Using: 
I personally use this method for the “log off functionality”. After an user is logged off, he/she will see a special “logoff page”. The “logoff page” uses user settings (e.g. theme, language, etc.) from a sesion scoped bean. But this session scoped bean doesn’t exist more because the session was invalidated. What to do? Here is the code snippet from my logout method.

01UserSettings userSettings = (UserSettings) FacesAccessor.getManagedBean("userSettings");
02 
03// invalidate session
04ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
05HttpSession session = (HttpSession) ec.getSession(false);
06session.invalidate();
07 
08// create new session
09((HttpServletRequest) ec.getRequest()).getSession(true);
10 
11// restore last used user settings because login / logout pages reference "userSettings"
12FacesAccessor.setValue2ValueExpression(userSettings, "#{userSettings}");
13 
14// redirect to the specified logout page
15ec.redirect(ec.getRequestContextPath() + "/views/logout.jsf");

The third method maps a variable to the given value expression #{…}. It uses javax.el.VariableMapper to assign the expression to the specified variable, so that any reference to that variable will be replaced by the expression in EL evaluations.

1public static void mapVariable2ValueExpression(final String variable, final String expression) {
2    FacesContext facesContext = FacesContext.getCurrentInstance();
3    ELContext elContext = facesContext.getELContext();
4     
5    ValueExpression targetExpression =
6        facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object.class);
7    elContext.getVariableMapper().setVariable(variable, targetExpression);
8}

Using: 
Assume, “PersonBean” is a managed bean having “name” attribute and “PersonsBean” is a bean holding many instances of “PersonBean” (as array, collection or map). The following code allows to use “personBean” as a reference to a specific bean with “name” Oleg.

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

In a facelets page, say so, personDetail.xhtml, we can write:

2      xmlns:ui="http://java.sun.com/jsf/facelets"
3      xmlns:h="http://java.sun.com/jsf/html">
4<ui:composition>
5    ...
6    <h:inputText value="#{personBean.name}"/>
7    ...
8</ui:composition>
9</html>

Note, the reference “personBean” was set in Java. This mapping can be also used in facelets in declarative way via ui:include / ui:param.

02      xmlns:ui="http://java.sun.com/jsf/facelets">
03<ui:composition>
04    ...
05    <ui:include src="personDetail.xhtml">
06        <ui:param name="personBean" value="#{personsBean.person['Oleg']}"/>
07    </ui:include>
08    ...
09</ui:composition>
10</html>

The next two methods are used to create MethodExpression / MethodExpressionActionListener programmatically. They are handy if you use component binding via “binding” attribute or create some model classes in Java.

01public static MethodExpression createMethodExpression(String valueExpression,
02                                                      Class<?> expectedReturnType,
03                                                      Class<?>[] expectedParamTypes) {
04    MethodExpression methodExpression = null;
05    try {
06        FacesContext fc = FacesContext.getCurrentInstance();
07        ExpressionFactory factory = fc.getApplication().getExpressionFactory();
08        methodExpression = factory.
09            createMethodExpression(fc.getELContext(), valueExpression, expectedReturnType, expectedParamTypes);
10    } catch (Exception e) {
11        throw new FacesException("Method expression '" + valueExpression + "' could not be created.");
12    }
13     
14    return methodExpression;
15}
16 
17public static MethodExpressionActionListener createMethodActionListener(String valueExpression,
18                                                                        Class<?> expectedReturnType,
19                                                                        Class<?>[] expectedParamTypes) {
20    MethodExpressionActionListener actionListener = null;
21    try {
22        actionListener = new MethodExpressionActionListener(createMethodExpression(
23            valueExpression, expectedReturnType, expectedParamTypes));
24    } catch (Exception e) {
25        throw new FacesException("Method expression for ActionListener '" + valueExpression
26                          + "' could not be created.");
27    }
28 
29    return actionListener;
30}

Using: 
In one of my projects I have created PrimeFaces MenuModel with menu items programmatically.

01MenuItem mi = new MenuItem();
02mi.setAjax(true);
03mi.setValue(...);
04mi.setProcess(...);
05mi.setUpdate(...);
06mi.setActionExpression(FacesAccessor.createMethodExpression(
07    "#{navigationContext.setBreadcrumbSelection}", String.class, new Class[] {}));
08 
09UIParameter param = new UIParameter();
10param.setId(...);
11param.setName(...);
12param.setValue(...);
13mi.getChildren().add(param);

Do you have nice methods you want to share here? Tips / tricks are welcome.

Reference: 5 useful methods JSF developers should know from our JCG partner Oleg Varaksin at the Thoughts on software development blog.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值