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.
01 | public static Object getManagedBean( final String beanName) { |
02 | FacesContext fc = FacesContext.getCurrentInstance(); |
06 | ELContext elContext = fc.getELContext(); |
07 | bean = elContext.getELResolver().getValue(elContext, null , beanName); |
08 | } catch (RuntimeException e) { |
09 | throw new FacesException(e.getMessage(), e); |
13 | throw new FacesException( "Managed bean with name '" + beanName |
14 | + "' was not found. Check your faces-config.xml or @ManagedBean annotation." ); |
Using:
2 | public class PersonBean { |
6 | PersonBean personBean = (PersonBean)FacesAccessor.getManagedBean( "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.
1 | public static void setValue2ValueExpression( final Object value, final String expression) { |
2 | FacesContext facesContext = FacesContext.getCurrentInstance(); |
3 | ELContext elContext = facesContext.getELContext(); |
5 | ValueExpression targetExpression = |
6 | facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object. class ); |
7 | targetExpression.setValue(elContext, value); |
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.
01 | UserSettings userSettings = (UserSettings) FacesAccessor.getManagedBean( "userSettings" ); |
04 | ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); |
05 | HttpSession session = (HttpSession) ec.getSession( false ); |
09 | ((HttpServletRequest) ec.getRequest()).getSession( true ); |
12 | FacesAccessor.setValue2ValueExpression(userSettings, "#{userSettings}" ); |
15 | ec.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.
1 | public static void mapVariable2ValueExpression( final String variable, final String expression) { |
2 | FacesContext facesContext = FacesContext.getCurrentInstance(); |
3 | ELContext elContext = facesContext.getELContext(); |
5 | ValueExpression targetExpression = |
6 | facesContext.getApplication().getExpressionFactory().createValueExpression(elContext, expression, Object. class ); |
7 | elContext.getVariableMapper().setVariable(variable, targetExpression); |
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.
1 | FacesAccessor.mapVariable2ValueExpression( "personBean" , "#{personsBean.person['Oleg']}" ); |
In a facelets page, say so, personDetail.xhtml, we can write:
6 | < h:inputText value = "#{personBean.name}" /> |
Note, the reference “personBean” was set in Java. This mapping can be also used in facelets in declarative way via ui:include / ui:param.
05 | < ui:include src = "personDetail.xhtml" > |
06 | < ui:param name = "personBean" value = "#{personsBean.person['Oleg']}" /> |
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.
01 | public static MethodExpression createMethodExpression(String valueExpression, |
02 | Class<?> expectedReturnType, |
03 | Class<?>[] expectedParamTypes) { |
04 | MethodExpression methodExpression = null ; |
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." ); |
14 | return methodExpression; |
17 | public static MethodExpressionActionListener createMethodActionListener(String valueExpression, |
18 | Class<?> expectedReturnType, |
19 | Class<?>[] expectedParamTypes) { |
20 | MethodExpressionActionListener actionListener = null ; |
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." ); |
29 | return actionListener; |
Using:
In one of my projects I have created PrimeFaces MenuModel with menu items programmatically.
01 | MenuItem mi = new MenuItem(); |
06 | mi.setActionExpression(FacesAccessor.createMethodExpression( |
07 | "#{navigationContext.setBreadcrumbSelection}" , String. class , new Class[] {})); |
09 | UIParameter param = new UIParameter(); |
13 | mi.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.