Liferay預設提供的基於Struts Action擴充的PortletAction是不支援多分發命令的,也就是我們一般常用的DispatchAction。但在我們日常基於Struts處理的操作中,已經大量的沿用了DispatchAction處理方式,採用“cmd=queryall”諸如此類的方式。
本文就來給大家講解如何通過擴充,讓Liferay實現對多分發命令Action的支援。 首先讓我們來看看Liferay是如何處理的: 在portlet.xml中,我們一般會配置如下:
<portlet-class>com.liferay.portlet.StrutsPortlet</portlet-class>
<init-param>
<name>view-action</name>
<value>/ext/reports/view_reports</value>
</init-param> 這樣Liferay面對一個Portlet請求的時候,會根據請求model來執行Portlet的doView或doEdit方式。當執行doView的時候就會請求其view-action所配置的Action URL所代表的Action來處理。 其處理流程大致是:
Portlet類——〉RequestProcessor——〉StrutsAction處理類。
我們可以通過兩種擴充方案來實現對多分發的支援:
方案(一):擴充Liferay的StrutsPortlet類,並寫一個DispatchPortletAction類,這樣不用擴充RequestProcessor實現。
方案(二):擴充RequestProcessor 與,並寫一個DispatchPortletAction類,這樣可以直接使用Liferay所提供的StrutsPortlet類。對於 RequestProcessor的擴充,在通過portal.properties檔案中通過配置 “struts.portlet.request.processor”屬性來設定。 接下來就兩種方案做分別的詳細講解(本篇先講方案一):
方案(一) 首先讓我們寫一個DispatchPortletAction 類,此類可以通過擴充Liferay本身的PortletAction實現,也可以通過擴充Struts本身的DispatchAction實現。本人是選擇後一種方式,這樣擴充的代碼量較少,都不要自己寫execute方式,直接使用基類的即可。對於DispatchPortletAction 主要擴充dispatchMethod和getMethodName方法。注意在getMechodName方法中,還追加了從 request.getAttribute(parameter)擷取方法名稱,並注意unspecified方法,這個是在沒有指明存取方法的時候預設執行的,所以開發人員在後續寫自己的Action一定要實現這個。
public class DispatchPortletAction extends DispatchAction ...{
protected ActionForward dispatchMethod(ActionMapping mapping,
ActionForm form, HttpServletRequest request,
HttpServletResponse response, String name) throws Exception ...{
PortletConfig portletConfig = (PortletConfig) request
.getAttribute(WebKeys.JAVAX_PORTLET_CONFIG);
RenderRequest renderRequest = (RenderRequest) request
.getAttribute(WebKeys.JAVAX_PORTLET_REQUEST);
RenderResponse renderResponse = (RenderResponse) request
.getAttribute(WebKeys.JAVAX_PORTLET_RESPONSE);
if (name == null) ...{
return this.unspecified(mapping, form, portletConfig,
renderRequest, renderResponse);
}
Method method = null;
try ...{
method = getMethod(name);
} catch (NoSuchMethodException e) ...{
String message = messages.getMessage("dispatch.method",
mapping.getPath(), name);
log.error(message, e);
String userMsg = messages.getMessage("dispatch.method.user",
mapping.getPath());
throw new NoSuchMethodException(userMsg);
}
ActionForward forward = null;
try ...{
Object args[] = ...{ mapping, form, portletConfig, renderRequest,
renderResponse };
forward = (ActionForward) method.invoke(this, args);
} catch (ClassCastException e) ...{
String message = messages.getMessage("dispatch.return",
mapping.getPath(), name);
log.error(message, e);
throw e;
} catch (IllegalAccessException e) ...{
String message = messages.getMessage("dispatch.error",
mapping.getPath(), name);
log.error(message, e);
throw e;
} catch (InvocationTargetException e) ...{
Throwable t = e.getTargetException();
if (t instanceof Exception) ...{
throw ((Exception) t);
} else ...{
String message = messages.getMessage("dispatch.error",
mapping.getPath(), name);
log.error(message, e);
throw new ServletException(t);
}
}
return (forward);
}
protected String getMethodName(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response,
String parameter) throws Exception ...{
String methodName = request.getParameter(parameter);
if (methodName == null || methodName.length() == 0) ...{
methodName = (String) request.getAttribute(parameter);
}
return methodName;
}
public ActionForward unspecified(ActionMapping mapping, ActionForm form,
PortletConfig config, RenderRequest req, RenderResponse res)
throws Exception ...{