public class DispatcherPortlet extends FrameworkPortlet
This portlet is very flexible: It can be used with just about any workflow, with the installation of the appropriate adapter classes. It offers the following functionality that distinguishes it from other request-driven portlet MVC frameworks:
HandlerMapping
implementation - pre-built or provided
as part of an application - to control the routing of requests to handler objects.
Default is a DefaultAnnotationHandlerMapping
.
HandlerMapping objects can be defined as beans in the portlet's application context,
implementing the HandlerMapping interface, overriding the default HandlerMapping if present.
HandlerMappings can be given any bean name (they are tested by type).
HandlerAdapter
; this allows for using any handler interface.
The default adapter is SimpleControllerHandlerAdapter
for Spring's Controller
interface.
A default AnnotationMethodHandlerAdapter
will be registered as well. HandlerAdapter objects can be added as beans in the
application context, overriding the default HandlerAdapter. Like HandlerMappings,
HandlerAdapters can be given any bean name (they are tested by type).
HandlerExceptionResolver
, for example mapping certain exceptions to
error pages. Default is none. Additional HandlerExceptionResolvers can be added
through the application context. HandlerExceptionResolver can be given any
bean name (they are tested by type).
ViewResolver
implementation, resolving symbolic view names into View objects. Default is
InternalResourceViewResolver
.
ViewResolver objects can be added as beans in the application context,
overriding the default ViewResolver. ViewResolvers can be given any bean name
(they are tested by type).
PortletMultipartResolver
implementation.
An implementations for Jakarta Commons FileUpload is included:
CommonsPortletMultipartResolver
.
The MultipartResolver bean name is "portletMultipartResolver"; default is none.
NOTE: The @RequestMapping
annotation will only be processed
if a corresponding HandlerMapping
(for type level annotations)
and/or HandlerAdapter
(for method level annotations)
is present in the dispatcher. This is the case by default.
However, if you are defining custom HandlerMappings
or
HandlerAdapters
, then you need to make sure that a
corresponding custom DefaultAnnotationHandlerMapping
and/or AnnotationMethodHandlerAdapter
is defined as well
- provided that you intend to use @RequestMapping
.
A web application can define any number of DispatcherPortlets.
Each portlet will operate in its own namespace, loading its own application
context with mappings, handlers, etc. Only the root application context
as loaded by ContextLoaderListener
,
if any, will be shared.
Thanks to Rainer Schmitz, Nick Lothian and Eric Dalquist for their suggestions!
Controller
,
ViewRendererServlet
,
ContextLoaderListener
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
ACTION_EXCEPTION_RENDER_PARAMETER
This render parameter is used to indicate forward to the render phase
that an exception occurred during the action phase.
|
static java.lang.String |
ACTION_EXCEPTION_SESSION_ATTRIBUTE
Unlike the Servlet version of this class, we have to deal with the
two-phase nature of the portlet request.
|
private static java.lang.String |
DEFAULT_STRATEGIES_PATH
Name of the class path resource (relative to the DispatcherPortlet class)
that defines DispatcherPortet's default strategy names.
|
static java.lang.String |
DEFAULT_VIEW_RENDERER_URL
Default URL to ViewRendererServlet.
|
private static java.util.Properties |
defaultStrategies |
private boolean |
detectAllHandlerAdapters
Detect all HandlerAdapters or just expect "handlerAdapter" bean?
|
private boolean |
detectAllHandlerExceptionResolvers
Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean?
|
private boolean |
detectAllHandlerMappings
Detect all HandlerMappings or just expect "handlerMapping" bean?
|
private boolean |
detectAllViewResolvers
Detect all ViewResolvers or just expect "viewResolver" bean?
|
private boolean |
forwardActionException
Whether exceptions thrown during doAction should be forwarded to doRender
|
private boolean |
forwardEventException
Whether exceptions thrown during doEvent should be forwarded to doRender
|
static java.lang.String |
HANDLER_ADAPTER_BEAN_NAME
Well-known name for the HandlerAdapter object in the bean factory for this namespace.
|
static java.lang.String |
HANDLER_EXCEPTION_RESOLVER_BEAN_NAME
Well-known name for the HandlerExceptionResolver object in the bean factory for this
namespace.
|
static java.lang.String |
HANDLER_MAPPING_BEAN_NAME
Well-known name for the HandlerMapping object in the bean factory for this namespace.
|
private java.util.List<HandlerAdapter> |
handlerAdapters
List of HandlerAdapters used by this portlet
|
private java.util.List<HandlerExceptionResolver> |
handlerExceptionResolvers
List of HandlerExceptionResolvers used by this portlet
|
private java.util.List<HandlerMapping> |
handlerMappings
List of HandlerMappings used by this portlet
|
static java.lang.String |
MULTIPART_RESOLVER_BEAN_NAME
Well-known name for the PortletMultipartResolver object in the bean factory for this namespace.
|
private PortletMultipartResolver |
multipartResolver
MultipartResolver used by this portlet
|
static java.lang.String |
PAGE_NOT_FOUND_LOG_CATEGORY
Log category to use when no mapped handler is found for a request.
|
protected static Log |
pageNotFoundLogger
Additional logger to use when no mapped handler is found for a request.
|
static java.lang.String |
VIEW_RESOLVER_BEAN_NAME
Well-known name for the ViewResolver object in the bean factory for this namespace.
|
private java.lang.String |
viewRendererUrl
URL that points to the ViewRendererServlet
|
private java.util.List<ViewResolver> |
viewResolvers
List of ViewResolvers used by this portlet
|
DEFAULT_CONTEXT_CLASS, DEFAULT_NAMESPACE_SUFFIX, DEFAULT_USERINFO_ATTRIBUTE_NAMES, PORTLET_CONTEXT_PREFIX
logger
Constructor and Description |
---|
DispatcherPortlet() |
Modifier and Type | Method and Description |
---|---|
protected ActionRequest |
checkMultipart(ActionRequest request)
Convert the request into a multipart request, and make multipart resolver available.
|
protected java.lang.Object |
createDefaultStrategy(ApplicationContext context,
java.lang.Class<?> clazz)
Create a default strategy.
|
protected void |
doActionService(ActionRequest request,
ActionResponse response)
Processes the actual dispatching to the handler for action requests.
|
protected void |
doEventService(EventRequest request,
EventResponse response)
Processes the actual dispatching to the handler for event requests.
|
protected void |
doRender(View view,
java.util.Map model,
PortletRequest request,
MimeResponse response)
Actually render the given view.
|
protected void |
doRenderService(RenderRequest request,
RenderResponse response)
Processes the actual dispatching to the handler for render requests.
|
protected void |
doResourceService(ResourceRequest request,
ResourceResponse response)
Processes the actual dispatching to the handler for resource requests.
|
protected void |
exposeActionException(PortletRequest request,
StateAwareResponse response,
java.lang.Exception ex)
Expose the given action exception to the given response.
|
protected <T> java.util.List<T> |
getDefaultStrategies(ApplicationContext context,
java.lang.Class<T> strategyInterface)
Create a List of default strategy objects for the given strategy interface.
|
protected <T> T |
getDefaultStrategy(ApplicationContext context,
java.lang.Class<T> strategyInterface)
Return the default strategy object for the given strategy interface.
|
protected HandlerExecutionChain |
getHandler(PortletRequest request)
Return the HandlerExecutionChain for this request.
|
protected HandlerAdapter |
getHandlerAdapter(java.lang.Object handler)
Return the HandlerAdapter for this handler object.
|
PortletMultipartResolver |
getMultipartResolver()
Obtain this portlet's PortletMultipartResolver, if any.
|
private void |
initHandlerAdapters(ApplicationContext context)
Initialize the HandlerAdapters used by this class.
|
private void |
initHandlerExceptionResolvers(ApplicationContext context)
Initialize the HandlerExceptionResolver used by this class.
|
private void |
initHandlerMappings(ApplicationContext context)
Initialize the HandlerMappings used by this class.
|
private void |
initMultipartResolver(ApplicationContext context)
Initialize the PortletMultipartResolver used by this class.
|
protected void |
initStrategies(ApplicationContext context)
Refresh the strategy objects that this portlet uses.
|
private void |
initViewResolvers(ApplicationContext context)
Initialize the ViewResolvers used by this class.
|
protected void |
noHandlerFound(PortletRequest request,
PortletResponse response)
No handler found -> throw appropriate exception.
|
void |
onRefresh(ApplicationContext context)
This implementation calls
initStrategies(org.springframework.context.ApplicationContext) . |
protected ModelAndView |
processHandlerException(RenderRequest request,
RenderResponse response,
java.lang.Object handler,
java.lang.Exception ex)
Determine an error ModelAndView via the registered HandlerExceptionResolvers.
|
protected ModelAndView |
processHandlerException(ResourceRequest request,
ResourceResponse response,
java.lang.Object handler,
java.lang.Exception ex)
Determine an error ModelAndView via the registered HandlerExceptionResolvers.
|
protected void |
render(ModelAndView mv,
PortletRequest request,
MimeResponse response)
Render the given ModelAndView.
|
protected View |
resolveViewName(java.lang.String viewName,
java.util.Map model,
PortletRequest request)
Resolve the given view name into a View object (to be rendered).
|
void |
setDetectAllHandlerAdapters(boolean detectAllHandlerAdapters)
Set whether to detect all HandlerAdapter beans in this portlet's context.
|
void |
setDetectAllHandlerExceptionResolvers(boolean detectAllHandlerExceptionResolvers)
Set whether to detect all HandlerExceptionResolver beans in this portlet's context.
|
void |
setDetectAllHandlerMappings(boolean detectAllHandlerMappings)
Set whether to detect all HandlerMapping beans in this portlet's context.
|
void |
setDetectAllViewResolvers(boolean detectAllViewResolvers)
Set whether to detect all ViewResolver beans in this portlet's context.
|
void |
setForwardActionException(boolean forwardActionException)
Set whether to forward exceptions thrown during the action phase
to the render phase via a session attribute.
|
void |
setForwardEventException(boolean forwardEventException)
Set whether to forward exceptions thrown during the event phase
to the render phase via a session attribute.
|
void |
setViewRendererUrl(java.lang.String viewRendererUrl)
Set the URL to the ViewRendererServlet.
|
private void |
triggerAfterActionCompletion(HandlerExecutionChain mappedHandler,
int interceptorIndex,
ActionRequest request,
ActionResponse response,
java.lang.Exception ex)
Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
|
private void |
triggerAfterEventCompletion(HandlerExecutionChain mappedHandler,
int interceptorIndex,
EventRequest request,
EventResponse response,
java.lang.Exception ex)
Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
|
private void |
triggerAfterRenderCompletion(HandlerExecutionChain mappedHandler,
int interceptorIndex,
RenderRequest request,
RenderResponse response,
java.lang.Exception ex)
Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
|
private void |
triggerAfterResourceCompletion(HandlerExecutionChain mappedHandler,
int interceptorIndex,
ResourceRequest request,
ResourceResponse response,
java.lang.Exception ex)
Trigger afterCompletion callbacks on the mapped HandlerInterceptors.
|
buildLocaleContext, createPortletApplicationContext, destroy, doDispatch, getContextClass, getContextConfigLocation, getNamespace, getPortletApplicationContext, getPortletContextAttributeName, getTitle, getUsernameForRequest, initFrameworkPortlet, initPortletApplicationContext, initPortletBean, onApplicationEvent, postProcessPortletApplicationContext, processAction, processEvent, processRequest, refresh, serveResource, setContextClass, setContextConfigLocation, setNamespace, setPublishContext, setPublishEvents, setThreadContextInheritable, setUserinfoUsernameAttributes
addRequiredProperty, createEnvironment, getEnvironment, getPortletContext, getPortletName, init, initBeanWrapper, setEnvironment
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
onApplicationEvent
public static final java.lang.String MULTIPART_RESOLVER_BEAN_NAME
public static final java.lang.String HANDLER_MAPPING_BEAN_NAME
public static final java.lang.String HANDLER_ADAPTER_BEAN_NAME
public static final java.lang.String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME
public static final java.lang.String VIEW_RESOLVER_BEAN_NAME
public static final java.lang.String DEFAULT_VIEW_RENDERER_URL
org.springframework.web.view
package.public static final java.lang.String ACTION_EXCEPTION_SESSION_ATTRIBUTE
public static final java.lang.String ACTION_EXCEPTION_RENDER_PARAMETER
public static final java.lang.String PAGE_NOT_FOUND_LOG_CATEGORY
private static final java.lang.String DEFAULT_STRATEGIES_PATH
protected static final Log pageNotFoundLogger
private static final java.util.Properties defaultStrategies
private boolean detectAllHandlerMappings
private boolean detectAllHandlerAdapters
private boolean detectAllHandlerExceptionResolvers
private boolean detectAllViewResolvers
private boolean forwardActionException
private boolean forwardEventException
private java.lang.String viewRendererUrl
private PortletMultipartResolver multipartResolver
private java.util.List<HandlerMapping> handlerMappings
private java.util.List<HandlerAdapter> handlerAdapters
private java.util.List<HandlerExceptionResolver> handlerExceptionResolvers
private java.util.List<ViewResolver> viewResolvers
public void setDetectAllHandlerMappings(boolean detectAllHandlerMappings)
Default is true. Turn this off if you want this portlet to use a single HandlerMapping, despite multiple HandlerMapping beans being defined in the context.
public void setDetectAllHandlerAdapters(boolean detectAllHandlerAdapters)
Default is "true". Turn this off if you want this portlet to use a single HandlerAdapter, despite multiple HandlerAdapter beans being defined in the context.
public void setDetectAllHandlerExceptionResolvers(boolean detectAllHandlerExceptionResolvers)
Default is true. Turn this off if you want this portlet to use a single HandlerExceptionResolver, despite multiple HandlerExceptionResolver beans being defined in the context.
public void setDetectAllViewResolvers(boolean detectAllViewResolvers)
Default is true. Turn this off if you want this portlet to use a single ViewResolver, despite multiple ViewResolver beans being defined in the context.
public void setForwardActionException(boolean forwardActionException)
Default is true. Turn this off if you want the portlet container to provide immediate exception handling for action requests.
#exposeActionException(javax.portlet.PortletRequest, javax.portlet.StateAwareResponse, Exception)
public void setForwardEventException(boolean forwardEventException)
Default is false. Turn this on if you want the DispatcherPortlet
to forward the exception to the render phase, similar to what it does
for action exceptions
by default.
public void setViewRendererUrl(java.lang.String viewRendererUrl)
public void onRefresh(ApplicationContext context)
initStrategies(org.springframework.context.ApplicationContext)
.onRefresh
in class FrameworkPortlet
context
- the current Portlet ApplicationContextFrameworkPortlet.refresh()
protected void initStrategies(ApplicationContext context)
May be overridden in subclasses in order to initialize further strategy objects.
private void initMultipartResolver(ApplicationContext context)
If no valid bean is defined with the given name in the BeanFactory for this namespace, no multipart handling is provided.
private void initHandlerMappings(ApplicationContext context)
If no HandlerMapping beans are defined in the BeanFactory for this namespace, we default to PortletModeHandlerMapping.
private void initHandlerAdapters(ApplicationContext context)
If no HandlerAdapter beans are defined in the BeanFactory for this namespace, we default to SimpleControllerHandlerAdapter.
private void initHandlerExceptionResolvers(ApplicationContext context)
If no bean is defined with the given name in the BeanFactory for this namespace, we default to no exception resolver.
private void initViewResolvers(ApplicationContext context)
If no ViewResolver beans are defined in the BeanFactory for this namespace, we default to InternalResourceViewResolver.
protected <T> T getDefaultStrategy(ApplicationContext context, java.lang.Class<T> strategyInterface)
The default implementation delegates to getDefaultStrategies(org.springframework.context.ApplicationContext, java.lang.Class<T>)
,
expecting a single object in the list.
context
- the current Portlet ApplicationContextstrategyInterface
- the strategy interfacegetDefaultStrategies(org.springframework.context.ApplicationContext, java.lang.Class<T>)
protected <T> java.util.List<T> getDefaultStrategies(ApplicationContext context, java.lang.Class<T> strategyInterface)
The default implementation uses the "DispatcherPortlet.properties" file (in the same package as the DispatcherPortlet class) to determine the class names. It instantiates the strategy objects and satisifies ApplicationContextAware if necessary.
context
- the current Portlet ApplicationContextstrategyInterface
- the strategy interfaceprotected java.lang.Object createDefaultStrategy(ApplicationContext context, java.lang.Class<?> clazz)
The default implementation uses
AutowireCapableBeanFactory.createBean(java.lang.Class<T>)
.
context
- the current Portlet ApplicationContextclazz
- the strategy implementation class to instantiateApplicationContext.getAutowireCapableBeanFactory()
public PortletMultipartResolver getMultipartResolver()
null
if none (indicating that no multipart support is available)protected void doActionService(ActionRequest request, ActionResponse response) throws java.lang.Exception
The handler will be obtained by applying the portlet's HandlerMappings in order. The HandlerAdapter will be obtained by querying the portlet's installed HandlerAdapters to find the first that supports the handler class.
doActionService
in class FrameworkPortlet
request
- current portlet action requestresponse
- current portlet Action responsejava.lang.Exception
- in case of any kind of processing failurejavax.portlet.GenericPortlet#processAction
protected void doRenderService(RenderRequest request, RenderResponse response) throws java.lang.Exception
The handler will be obtained by applying the portlet's HandlerMappings in order. The HandlerAdapter will be obtained by querying the portlet's installed HandlerAdapters to find the first that supports the handler class.
doRenderService
in class FrameworkPortlet
request
- current portlet render requestresponse
- current portlet render responsejava.lang.Exception
- in case of any kind of processing failurejavax.portlet.GenericPortlet#doDispatch
protected void doResourceService(ResourceRequest request, ResourceResponse response) throws java.lang.Exception
The handler will be obtained by applying the portlet's HandlerMappings in order. The HandlerAdapter will be obtained by querying the portlet's installed HandlerAdapters to find the first that supports the handler class.
doResourceService
in class FrameworkPortlet
request
- current portlet render requestresponse
- current portlet render responsejava.lang.Exception
- in case of any kind of processing failurejavax.portlet.GenericPortlet#serveResource
protected void doEventService(EventRequest request, EventResponse response) throws java.lang.Exception
The handler will be obtained by applying the portlet's HandlerMappings in order. The HandlerAdapter will be obtained by querying the portlet's installed HandlerAdapters to find the first that supports the handler class.
doEventService
in class FrameworkPortlet
request
- current portlet action requestresponse
- current portlet Action responsejava.lang.Exception
- in case of any kind of processing failurejavax.portlet.GenericPortlet#processEvent
protected ActionRequest checkMultipart(ActionRequest request) throws MultipartException
request
- current HTTP requestMultipartException
protected HandlerExecutionChain getHandler(PortletRequest request) throws java.lang.Exception
request
- current portlet requestjava.lang.Exception
protected void noHandlerFound(PortletRequest request, PortletResponse response) throws java.lang.Exception
request
- current portlet requestresponse
- current portlet responsejava.lang.Exception
- if preparing the response failedprotected HandlerAdapter getHandlerAdapter(java.lang.Object handler) throws PortletException
handler
- the handler object to find an adapter forPortletException
- if no HandlerAdapter can be found for the handler.
This is a fatal error.protected void exposeActionException(PortletRequest request, StateAwareResponse response, java.lang.Exception ex)
request
- current portlet requestresponse
- current portlet responseex
- the action exception (may also come from an event phase)protected void render(ModelAndView mv, PortletRequest request, MimeResponse response) throws java.lang.Exception
mv
- the ModelAndView to renderrequest
- current portlet render requestresponse
- current portlet render responsejava.lang.Exception
- if there's a problem rendering the viewprotected View resolveViewName(java.lang.String viewName, java.util.Map model, PortletRequest request) throws java.lang.Exception
Default implementations asks all ViewResolvers of this dispatcher. Can be overridden for custom resolution strategies, potentially based on specific model attributes or request parameters.
viewName
- the name of the view to resolvemodel
- the model to be passed to the viewrequest
- current portlet render requestjava.lang.Exception
- if the view cannot be resolved
(typically in case of problems creating an actual View object)ViewResolver.resolveViewName(java.lang.String, java.util.Locale)
protected void doRender(View view, java.util.Map model, PortletRequest request, MimeResponse response) throws java.lang.Exception
The default implementation delegates to
ViewRendererServlet
.
view
- the View to rendermodel
- the associated modelrequest
- current portlet render requestresponse
- current portlet render responsejava.lang.Exception
- if there's a problem rendering the viewprotected ModelAndView processHandlerException(RenderRequest request, RenderResponse response, java.lang.Object handler, java.lang.Exception ex) throws java.lang.Exception
request
- current portlet requestresponse
- current portlet responsehandler
- the executed handler, or null if none chosen at the time of
the exception (for example, if multipart resolution failed)ex
- the exception that got thrown during handler executionjava.lang.Exception
- if no error ModelAndView foundprotected ModelAndView processHandlerException(ResourceRequest request, ResourceResponse response, java.lang.Object handler, java.lang.Exception ex) throws java.lang.Exception
request
- current portlet requestresponse
- current portlet responsehandler
- the executed handler, or null if none chosen at the time of
the exception (for example, if multipart resolution failed)ex
- the exception that got thrown during handler executionjava.lang.Exception
- if no error ModelAndView foundprivate void triggerAfterActionCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex, ActionRequest request, ActionResponse response, java.lang.Exception ex) throws java.lang.Exception
mappedHandler
- the mapped HandlerExecutionChaininterceptorIndex
- index of last interceptor that successfully completedex
- Exception thrown on handler execution, or null if nonejava.lang.Exception
HandlerInterceptor.afterRenderCompletion(RenderRequest, RenderResponse, java.lang.Object, java.lang.Exception)
private void triggerAfterRenderCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex, RenderRequest request, RenderResponse response, java.lang.Exception ex) throws java.lang.Exception
mappedHandler
- the mapped HandlerExecutionChaininterceptorIndex
- index of last interceptor that successfully completedex
- Exception thrown on handler execution, or null if nonejava.lang.Exception
HandlerInterceptor.afterRenderCompletion(RenderRequest, RenderResponse, java.lang.Object, java.lang.Exception)
private void triggerAfterResourceCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex, ResourceRequest request, ResourceResponse response, java.lang.Exception ex) throws java.lang.Exception
mappedHandler
- the mapped HandlerExecutionChaininterceptorIndex
- index of last interceptor that successfully completedex
- Exception thrown on handler execution, or null if nonejava.lang.Exception
HandlerInterceptor.afterRenderCompletion(RenderRequest, RenderResponse, java.lang.Object, java.lang.Exception)
private void triggerAfterEventCompletion(HandlerExecutionChain mappedHandler, int interceptorIndex, EventRequest request, EventResponse response, java.lang.Exception ex) throws java.lang.Exception
mappedHandler
- the mapped HandlerExecutionChaininterceptorIndex
- index of last interceptor that successfully completedex
- Exception thrown on handler execution, or null if nonejava.lang.Exception
HandlerInterceptor.afterRenderCompletion(RenderRequest, RenderResponse, java.lang.Object, java.lang.Exception)