Как условно изменить исходный JSP для портлета JSR-168? - PullRequest
1 голос
/ 01 февраля 2012

У меня есть приложение с портлетами 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 Ответ

1 голос
/ 01 февраля 2012

Это не должно включать перенаправление, так же как и изменение 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);
}
...