如何有条件地更改 JSR-168 portlet 的初始 JSP?

发布于 2025-01-01 09:47:49 字数 5978 浏览 6 评论 0原文

我有一个在 WebSphere Portal 6.0 上运行的 JSR-168 portlet 应用程序。
在应用程序的 portlet.xml 文件中,特定的 portlet 定义如下:

<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”,即呈现 portlet 时使用的初始 JSP。
我需要根据数据库查询的结果有条件地更改该参数的值。

我认为这可能涉及 MHFacesHibernatePortlet 类中某处的重定向。
这是正确的吗?我应该修改该类的什么方法?

编辑,包含两个类的更多信息和源代码...

我添加了下面的 MHFacesHibernatePortlet 类及其扩展的 MHFacesPortlet 类的代码。

在应用程序的 portlet.xml 文件中,多个 portlet 均配置为使用 MHFacesHibernatePortlet 类,但每个 portlet 使用不同的初始 JSP。上面的“个人 Portlet”只是一个示例。

我只需要有条件地更改某些 portlet 的初始 JSP,因此我有一些代码应该能够根据我想要更改的列表检查 JSP 名称,然后运行 ​​Hibernate 查询,然后更改 JSP仅在必要时命名。

我在 MHFacesPortlet.processAction 中看到它读取相关参数并在某些条件下将其传递给 request.getPortletSession().setAttribute() ,所以我尝试将我的代码在那里并更改 homeJsp 变量,但这不起作用。添加一些日志记录后,我发现当我转到包含这些 portlet 之一的页面时,甚至没有调用 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);
    }
}

I have a JSR-168 portlet application running on WebSphere Portal 6.0.
In the application's portlet.xml file, a specific portlet is defined as follows:

<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>

Note that it defines a parameter named "com.ibm.faces.portlet.page.view" with the value "/TEIndividual/TEIndividualView.jsp", which is the initial JSP used when the portlet is rendered.
I need to conditionally change the value of that parameter based on the result of a database query.

I think this might involve a redirect somewhere in the MHFacesHibernatePortlet class.
Is that correct, and what method of the class should I modify?

Edit, with more info and source code for two classes...

I've added code for the MHFacesHibernatePortlet class below, and also the MHFacesPortlet class which it extends.

In the application's portlet.xml file, multiple portlets are all configured to use the MHFacesHibernatePortlet class, but each portlet uses a different initial JSP. The "Individual Portlet" above is just one example.

I need to conditionally change the initial JSP only for some of the portlets, so I have some code that should be able to check the JSP name against a list of the ones I want to change, then run a Hibernate query, then change the JSP name only if necessary.

I saw in MHFacesPortlet.processAction that it reads the relevant parameter and passes it to request.getPortletSession().setAttribute() under some conditions, so I tried to put my code there and change the homeJsp variable, but that didn't work. After adding some logging I found that processAction isn't even called when I go to a page with one of these portlets.

Source for the MHFacesHibernatePortlet class:

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();
        }
    }
}

Source for the MHFacesPortlet class:

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);
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

树深时见影 2025-01-08 09:47:49

这不应涉及重定向,也不应涉及更改 portlet 分派到的 JSP。

正如我对您的问题的评论一样,查看 MHFacesHibernatePortlet 的源代码确实很有帮助。不过,至少在 MHFacesHibernatePortlet 中,您可以重写 init(PortletConfig config),然后有条件地更改所使用的 init 参数的值。这可以遵循在传入的 PortletConfig 周围添加过滤器的方法,如果使用相同的 com.ibm 调用,则覆盖该过滤器以返回 getInitParameter 的备用值.faces.portlet.page.view 键名 - 然后使用您的过滤器实现调用 super.init(...) 。但是,如果您需要向不同的 portlet 请求返回不同的 JSP,则此将不起作用,因为此 init 参数将用于 portlet 实例所服务的所有请求。

然而,更好的方法是查看自定义 portlet(或其父级之一)在何处引用此 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 portlet 页面

您可以使用 Faces 操作结果和导航规则更改 Faces portlet 中的页面。

如果您想在不使用 Faces 操作的情况下更改页面,您可以将 JSP 文件路径设置为以下会话属性之一:

...

例如,您可以创建 Faces portlet 的子类,并在 doView() 方法中设置会话属性,以在某些情况下更改页面:

public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
  如果 (...) {
    request.getPortletSession().setAttribute("com.ibm.faces.portlet.page.view", "/MyPage.jsp");
  }

  super.doView(请求,响应);
}

This shouldn't involve a redirect, as much as changing the JSP that the portlet dispatches to.

As I commented to your question, it would really be helpful to see the source of MHFacesHibernatePortlet. However, at a minimum, within MHFacesHibernatePortlet, you could override init(PortletConfig config), then conditionally change the value of the init parameter that is used. This could follow the approach of adding a filter around the passed-in PortletConfig that is overridden to return an alternate value for getInitParameter if called with the same com.ibm.faces.portlet.page.view key name - then calling super.init(...) with your filter implementation. However, this will not work if you need to return different JSPs to different portlet requests, as this init param will be used for all requests serviced by the portlet instance.

However, the better approach would be to see where the custom portlet (or one of its parents) is referring to this init param, and putting your custom logic there instead.


Update (following your updated comments):

For changing the initial (view) JSP, you need to override doView, not processAction. See http://publib.boulder.ibm.com/infocenter/radhelp/v6r0m1/index.jsp?topic=%2Fcom.ibm.etools.portal.doc%2Ftopics%2Ftnoactionmode.html for a specific example on how to accomplish this:

Changing a JSF portlet page without a JSF action

You can change a page in a Faces portlet using a Faces action outcome and the navigation rules.

If you want to change a page without using a Faces action, you can set a JSP file path to the one of the following session attributes:

...

For example, you can create a subclass of your Faces portlet and set the session attribute in the doView() method to change the page in some conditions:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文