копия моей статьи на Liveinternet.ru от 9 октября 2007
все порталы, удовлетворяющие спецификации JSR-168, предоставляют стандартный механизм доступа и модификации настроек портлетов, посредством реализации интерфейса javax.portlet.PortletPreferences. в данной заметке рассмотрим способ работы с настройками портлета, реализованного с помощью технологии JavaServer Faces.быстрое решение
основным интерфейсом связи с внешней средой для JSF технологии является класс javax.faces.context.FacesContext. параметры портлета, сведения о типе портального запроса, настройках режима и вида портлета храняться в классах-реализациях интерфейса портального запроса javax.portlet.PortletRequest. сведенья о пространстве имен портлета храняться в реализациях интерфейса портального ответа javax.portlet.PortletRespose. для связи всех этих классов и получения доступа к специфическим параметраметрам и установкам портлета реализуем утилитарный класс:
public final class PorletFacesUtils {
private PortletFacesUtils() {
}
public static PortletRequest getPortletRequest(FacesContext context) throws Exception {
Object request = context.getExternalContext().getRequest();
if (request instanceof PortletRequest) {
return (PortletRequest) request;
} else {
throws new Exception(“Portlet run outside the portal environment or portlet request class is not generic”);
}
}
public static PortletRequest getPortletResponse(FacesContext context) throws Exception {
Object response = context.getExternalContext().getResponse();
if (request instanceof PortletResponse) {
return (PortletResponse) response;
} else {
throws new Exception(“Portlet run outside the portal environment or portlet response class is not generic”);
}
}
public static PortletPreferences getPortletRequest(FacesContext context) throws Exception {
PortletRequest request = getPortletRequest(context);
return request.getPortletPreferences();
}
}
таким образом мы реализовали своеобразный мост между JSF-приложением и специфическими классами портальной среды. далее этот класс может быть использован для работы с параметрами и настройками портлета. также класс расширен для получения других классов, специфичных для портальной среды (например javax.portlet.PortletSession, javax.portlet.PortletContext и т.п.).
риски
некоторые фреймворки JSF компонентов (например ICEfaces) использую свои врапперы портальных запросов и ответов. эти врапперы могут не являться наследниками стандартных интерфейсов, а следовательно будут ошибочно обработаны утилитарным классом. в этом случае необходимо реализовать механизм адаптера портальной среды для конкретной реализации враппера. как это сделать, я расскажу ниже.
гибкое решение
реализация гибкого механизма доступа к компонентам портальной среды позволит существенно упростить переход между различными библиотеками JSF компонентов, реализациями порталов и спецификации JSF. за основу этого решения мы возьмем функциональность утилитарного класса.
вместо утилитарного класса опишем общий интерфейс адаптера портальной среды:
public interface PortletFacesAdapter extends Serializable {
PortletRequest getPortletRequest(FacesContext context);
PortletResponse getPortletResponse(FacesContext context);
PortletPreferences getPortletPreferences(FacesContext context);
}
перенесем функциональность утилитарного класса в реализацию интерфейса адаптера:
public class GenericPortletFacesAdapter {
public PortletRequest getPortletRequest(FacesContext context) throws Exception {
Object request = context.getExternalContext().getRequest();
if (request instanceof PortletRequest) {
return (PortletRequest) request;
} else {
throws new Exception(“Portlet run outside the portal environment or portlet request class is not generic”);
}
}
public PortletRequest getPortletResponse(FacesContext context) throws Exception {
Object response = context.getExternalContext().getResponse();
if (request instanceof PortletResponse) {
return (PortletResponse) response;
} else {
throws new Exception(“Portlet run outside the portal environment or portlet response class is not generic”);
}
}
public PortletPreferences getPortletRequest(FacesContext context) throws Exception {
PortletRequest request = getPortletRequest(context);
return request.getPortletPreferences();
}
}
теперь нам необходимо реализовать JSF managed bean, который будет поддерживать механизм адаптеров:
public class AdaptableBean implements Serializable {
private PortletAdapter adapter;
public PortletAdapter getAdapter() {
return adapter;
}
public void setPortletAdapter (PortletAdapter adapter) {
this.adapter = adapter;
}
}
фактически мы реализовали механизм полноценной работы JSF framework внутри портальной среды. осталось только проиллюстрировать его конфигурацию. итак реализуем простой класс JSF managed bean, который используется в портлете:
public class TestBean extends AdaptableBean {
}
и сконфигурируем портлет, для использования этим классом GenericPortletFacesAdapter адаптера:
<faces-config>
<managed-bean>
<managed-bean-name>portletAdapter</managed-bean-name>
<managed-bean-class>GenericPortletFacesAdapter</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>testBean</managed-bean-name>
<managed-bean-class>TestBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>adapter</property-name>
<value>portletAdapter</value>
</managed-property>
</managed-bean>
</faces-config>
ссылки
Java Portlet API
JavaServer Faces API
статья на английском языке