2
votes

I'm trying to create a simple Struts 2 JSR 286 Portlet, running on WebSphere Portal 7. I'm able to display a simple JSP that contains a link which calls an action and displays another JSP which accepts input. That works fine.

I start to run into problems, however, when I try to use a redirectAction. I don't see any error messages, but the redirect doesn't seem to work. The Portlet just shows a blank page.

In debugging this I noticed that the doView method of my Portlet class is never called, which seems very suspicious.

If anyone has experience developing Struts 2 Portlets on WebSphere Portal, I would appreciate some help in checking that my config files are correct. Have I missed something?

Here are the details:

WebSphere Portal 7.0.0.2
WebSphere Application Server 7.0.0.25
RAD 8.0.4
Struts 2.3.14.2
Windows 7

portlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app id="com.ibm.demo.jsr286.TopUpPortlet.72594d5fe3" 
version="2.0" 
xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
<portlet>
    <description xml:lang="EN">Demo JSR 286 Struts Portlet</description>
    <portlet-name>Demo Portlet</portlet-name>
    <display-name>Demo Portlet</display-name>

    <!-- DemoPortlet extends org.apache.struts2.portlet.dispatcher.Jsr286Dispatcher -->
    <portlet-class>com.demo.jsr286.DemoPortlet</portlet-class>

    <init-param>
        <name>viewNamespace</name>
        <value>/view</value>
    </init-param>

    <init-param>
        <name>defaultViewAction</name>
        <value>index</value>
    </init-param>

    <expiration-cache>0</expiration-cache>

    <supports>
        <mime-type>text/html</mime-type>
        <portlet-mode>view</portlet-mode>
    </supports>

    <supported-locale>en</supported-locale>

    <portlet-info>
        <title>Demo Portlet</title>
        <short-title>DemoPortlet</short-title>
        <keywords>Demo Portlet</keywords>
    </portlet-info>

</portlet>

<default-namespace>http://JSR286StrutsDemo/</default-namespace>
</portlet-app>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" 
xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

<display-name>JSR 286 Struts Demo</display-name>

<servlet id="Struts2PortletDispatcherServlet">
    <servlet-name>Struts2PortletDispatcherServlet</servlet-name>
    <servlet-class>org.apache.struts2.portlet.dispatcher.DispatcherServlet</servlet-class>
</servlet>

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
</welcome-file-list>

</web-app>

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<include file="struts-plugin.xml"/>

<package name="view" extends="struts-portlet-default" namespace="/view">

    <!-- This action works  -->     
    <action name="index">
        <result>/html/view/index.jsp</result>
    </action>

    <!-- This action works  -->
    <action name="startDemo">
        <result>/html/view/demo.jsp</result>
    </action>

            <!-- This action does not work  -->
    <action name="redirectToIndex">
        <result type="redirectAction">
            <param name="actionName">index</param>
            <param name="namespace">/view</param>
            <param name="portletMode">view</param>
        </result>
    </action>

</package>

</struts>

* Update *

I've narrowed the problem down slightly. It looks like the action is being interpreted as a file location rather than a struts action. So, when I call action "redirectToIndex" it tries to display a page called "/view/index.action". I verified this by creating a file with that path and sure enough, the contents of that file are displayed in the portlet.

I feel that I'm probably missing some configuration option, but I'm not sure what. Servlet filter maybe? Can anyone help?

1
So what is it? Redirect is not working or method is not getting called? BTW why are you including struts-plugin.xml file?Aleksandr M
It's both really. Redirect not working was the first issue, then I noticed that doView wasn't getting called when I was investigating. I'm including struts-plugin.xml because that's where the struts-portlet-default package is defined. Is that not correct?dgwatson
There is no need to include it by yourself, because it is already included. Try to give class attribute to your redirectToIndex action definition with your action class.Aleksandr M
Ok, I've removed the include and added a class attribute. I created a simple action class that prints a debug message to stdout then returns ActionSupport.SUCCESS. I see the debug message, but the overall behavior is the same.dgwatson
So method is executed. Are you seeing your /html/view/index.jsp page after that?Aleksandr M

1 Answers

1
votes

Actually you don't need doView method, because Jsr286Dispatcher is just a dispatcher. You can use actions like in ordinary Struts2 application.

From the documentation:

The portlet-class element is always org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher (or a subclass, if you have added some custom functionality). This is the portlet that acts as the dispatcher for the Struts 2 framework, and translates incoming user interaction to action requests that Struts 2 understands.

For jsr286 specification <portlet-class> should be org.apache.struts2.portlet.dispatcher.Jsr286Dispatcher and defaultViewAction init-param will call Struts2 action. And in struts.xml file, like usually, you can define action class + method to call.

So you need to define Jsr286Dispatcher as <portlet-class> and create action which you will use in struts.xml action definitions.

Also see this two links: http://struts.apache.org/development/2.x/docs/struts-2-portlet-tutorial.html and http://struts.apache.org/development/2.x/docs/portlet-plugin.html.