Статьи

5 полезных методов, которые должны знать разработчики JSF

Цель этого поста — краткий обзор некоторых удобных методов для разработчиков JSF, которые они могут использовать в своей повседневной работе. Служебный класс — хорошее место для объединения всех методов. Я бы назвал такой класс FacesAccessor. Первый метод, вероятно, самый используемый. Возвращает управляемый бин по указанному имени.

Компонент должен быть зарегистрирован либо в файле face-config.xml, либо в аннотации. Инъекция хороша, но иногда, если бобы называются редко, нет необходимости вводить бобы друг в друга.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
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;
}

С помощью:

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

Второй метод полезен для разработчиков компонентов JSF и всех, кто хотел бы оценить данное выражение значения # {…} и присваивает результат заданному значению.

1
2
3
4
5
6
7
8
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);
}

С помощью:
Я лично использую этот метод для «выхода из системы». После того как пользователь вышел из системы, он увидит специальную «страницу выхода». «Страница выхода из системы» использует пользовательские настройки (например, тема, язык и т. Д.) Из bean-объекта sesion. Но этот bean-объект сессионной области больше не существует, потому что сессия была признана недействительной. Что делать? Вот фрагмент кода из моего метода выхода из системы.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
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.

1
2
3
4
5
6
7
8
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», а «PersonsBean» — это компонент, содержащий много экземпляров «PersonBean» (в виде массива, коллекции или карты). Следующий код позволяет использовать «personBean» как ссылку на конкретный бин с «именем» Олега.

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

На странице Facelets, скажем так, personDetail.xhtml, мы можем написать:

1
2
3
4
5
6
7
8
9
      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. Это отображение может также использоваться в Facelets декларативным способом через ui: include / ui: param.

01
02
03
04
05
06
07
08
09
10
      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.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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 программными пунктами меню.

01
02
03
04
05
06
07
08
09
10
11
12
13
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 Олега Вараксина в блоге « Мысли о разработке программного обеспечения» .