Как условно изменить исходный JSP для портлета JSR-168?
У меня есть приложение с портлетами JSR-168, работающее на WebSphere Portal 6.0.
В файле portlet.xml приложения определенный портлет определяется следующим образом:
<portlet>
<portlet-name>Individual Portlet</portlet-name>
<display-name>Individual Portlet</display-name>
<display-name xml:lang="en">
Individual Portlet
</display-name>
<portlet-class>
com.companyname.util.hibernate.MHFacesHibernatePortlet
</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/TEIndividual/TEIndividualView.jsp</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<resource-bundle>
resources.nl.IndividualPortletResource
</resource-bundle>
<portlet-info>
<title>Individual Portlet</title>
</portlet-info>
<portlet-preferences>
<preference>
<name>portletType</name>
<value>individual</value>
</preference>
<preference>
<name>wmmAttribSalesmanId</name>
<value>facsimileTelephoneNumber</value>
</preference>
</portlet-preferences>
</portlet>
Обратите внимание, что он определяет параметр с именем "com.ibm.faces.portlet.page.view" со значением "/TEIndividual/TEIndividualView.jsp", который является исходным JSP, используемым при визуализации портлета.
Мне нужно условно изменить значение этого параметра в зависимости от результата запроса к базе данных.
Я думаю, что это может включать перенаправление где-то в классе MHFacesHibernatePortlet.
Это правильно, и какой метод класса я должен изменить?
Редактировать, с дополнительной информацией и исходным кодом для двух классов...
Я добавил код для класса MHFacesHibernatePortlet ниже, а также класс MHFacesPortlet, который он расширяет.
В файле portlet.xml приложения все портлеты настроены на использование класса MHFacesHibernatePortlet, но каждый портлет использует свой собственный начальный JSP. Приведенный выше "Индивидуальный портлет" является лишь одним примером.
Мне нужно условно изменить исходный JSP только для некоторых портлетов, поэтому у меня есть некоторый код, который должен быть в состоянии проверить имя JSP по списку тех, которые я хочу изменить, затем выполнить запрос Hibernate, затем изменить JSP имя только при необходимости.
Я видел в MHFacesPortlet.processAction
что он читает соответствующий параметр и передает его request.getPortletSession().setAttribute()
при некоторых условиях, поэтому я попытался поместить туда свой код и изменить homeJsp
переменная, но это не сработало. После добавления некоторой регистрации я обнаружил, что processAction даже не вызывается, когда я захожу на страницу с одним из этих портлетов.
Исходный код для класса MHFacesHibernatePortlet:
package com.companyname.util.hibernate;
import java.io.IOException;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.companyname.util.portlet.MHFacesPortlet;
public class MHFacesHibernatePortlet extends MHFacesPortlet {
/*
* (non-Javadoc)
*
* @see com.ibm.faces.webapp.FacesGenericPortlet#doConfigure(javax.portlet.RenderRequest,
* javax.portlet.RenderResponse)
*/
public void doConfigure(RenderRequest arg0,RenderResponse arg1)
throws PortletException,IOException {
super.doConfigure(arg0,arg1);
try {
HibernateUtil.commitTransaction();
} finally {
HibernateUtil.closeSession();
}
}
/*
* (non-Javadoc)
*
* @see javax.portlet.GenericPortlet#doView(javax.portlet.RenderRequest,
* javax.portlet.RenderResponse)
*/
public void doView(RenderRequest arg0,RenderResponse arg1)
throws PortletException,IOException {
super.doView(arg0,arg1);
// Close and commit open hibernate transactions
try {
HibernateUtil.commitTransaction();
} finally {
HibernateUtil.closeSession();
}
}
}
Источник для класса MHFacesPortlet:
package com.companyname.util.portlet;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import com.ibm.faces.webapp.FacesGenericPortlet;
public class MHFacesPortlet extends FacesGenericPortlet {
private static final String FACES_CURRENT_PAGE_STUB="com.ibm.faces.portlet.page.";
/** parameter used to fire an extended action */
public static final String PARAMETER_EXTENDED_ACTION="extAction";
/** Action to reset view mode of the portlet */
public static final String ACTION_VIEW_MODE_RESET="viewReset";
public MHFacesPortlet() {
super();
}
/*
* (non-Javadoc)
*
* @see javax.portlet.Portlet#processAction(javax.portlet.ActionRequest,
* javax.portlet.ActionResponse)
*/
public void processAction(ActionRequest request,ActionResponse response)
throws PortletException {
// Check if we need to process an extended action
String extendedAction=(String)request
.getParameter(PARAMETER_EXTENDED_ACTION);
if (extendedAction!=null&&!extendedAction.equals("")) {
// Reset view mode
if (extendedAction.equals(ACTION_VIEW_MODE_RESET)) {
PortletMode portletMode=request.getPortletMode();
String modeString=null;
if (portletMode.equals(PortletMode.EDIT)) modeString="edit";
else if (portletMode.equals(PortletMode.VIEW)) modeString="view";
else if (portletMode.equals(PortletMode.HELP)) modeString="help";
else modeString=portletMode.toString();
String homeJsp=getPortletConfig().getInitParameter(
FACES_CURRENT_PAGE_STUB+modeString);
request.getPortletSession().setAttribute(
FACES_CURRENT_PAGE_STUB+modeString,homeJsp);
}
}
//delegate to ibm faces
super.processAction(request,response);
}
}
1 ответ
Это не должно включать перенаправление, а также изменение JSP, к которому отправляется портлет.
Как я прокомментировал ваш вопрос, было бы очень полезно увидеть источник MHFacesHibernatePortlet
, Однако, как минимум, в пределах MHFacesHibernatePortlet
Вы могли бы переопределить init(PortletConfig config)
, затем условно изменить значение параметра init, который используется. Это может следовать подходу добавления фильтра вокруг переданного PortletConfig
который переопределяется для возврата альтернативного значения для getInitParameter
если вызывается с тем же com.ibm.faces.portlet.page.view
Ключевое имя - затем звонит super.init(...)
с вашей реализацией фильтра. Однако это не будет работать, если вам нужно возвращать разные JSP для разных запросов портлета, так как этот параметр init будет использоваться для всех запросов, обслуживаемых экземпляром портлета.
Однако лучшим подходом было бы увидеть, где пользовательский портлет (или один из его родителей) ссылается на этот параметр init, и вместо этого поместить туда свою пользовательскую логику.
Обновление (после ваших обновленных комментариев):
Для изменения исходного (просмотра) JSP необходимо переопределить doView
не processAction
, См. http://publib.boulder.ibm.com/infocenter/radhelp/v6r0m1/index.jsp?topic=%2Fcom.ibm.etools.portal.doc%2Ftopics%2Ftnoactionmode.html для конкретного примера того, как выполнить это:
Изменение страницы портлета JSF без действия JSF
Вы можете изменить страницу в портлете Faces, используя результат действия Faces и правила навигации.
Если вы хотите изменить страницу без использования действия Faces, вы можете установить путь к файлу JSP к одному из следующих атрибутов сеанса:
...
Например, вы можете создать подкласс вашего портлета Faces и установить атрибут сеанса в
doView()
Способ изменения страницы в некоторых условиях:public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { if (...) { request.getPortletSession().setAttribute("com.ibm.faces.portlet.page.view", "/MyPage.jsp"); } super.doView(request, response); }