Class FrameworkServlet

java.lang.Object
jakarta.servlet.GenericServlet
jakarta.servlet.http.HttpServlet
org.springframework.web.servlet.HttpServletBean
org.springframework.web.servlet.FrameworkServlet
All Implemented Interfaces:
jakarta.servlet.Servlet, jakarta.servlet.ServletConfig, Serializable, Aware, ApplicationContextAware, EnvironmentAware, EnvironmentCapable
Direct Known Subclasses:
DispatcherServlet

public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware
Base servlet for Spring's web framework. Provides integration with a Spring application context, in a JavaBean-based overall solution.

This class offers the following functionality:

  • Manages a WebApplicationContext instance per servlet. The servlet's configuration is determined by beans in the servlet's namespace.
  • Publishes events on request processing, whether or not a request is successfully handled.

Subclasses must implement doService(HttpServletRequest, HttpServletResponse) to handle requests. Because this extends HttpServletBean rather than HttpServlet directly, bean properties are automatically mapped onto it. Subclasses can override initFrameworkServlet() for custom initialization.

Detects a "contextClass" parameter at the servlet init-param level, falling back to the default context class, XmlWebApplicationContext, if not found. Note that, with the default FrameworkServlet, a custom context class needs to implement the ConfigurableWebApplicationContext SPI.

Accepts an optional "contextInitializerClasses" servlet init-param that specifies one or more ApplicationContextInitializer classes. The managed web application context will be delegated to these initializers, allowing for additional programmatic configuration, for example, adding property sources or activating profiles against the context's environment. See also ContextLoader which supports a "contextInitializerClasses" context-param with identical semantics for the "root" web application context.

Passes a "contextConfigLocation" servlet init-param to the context instance, parsing it into potentially multiple file paths which can be separated by any number of commas and spaces, like "test-servlet.xml, myServlet.xml". If not explicitly specified, the context implementation is supposed to build a default location from the namespace of the servlet.

Note: In case of multiple config locations, later bean definitions will override ones defined in earlier loaded files, at least when using Spring's default ApplicationContext implementation. This can be leveraged to deliberately override certain bean definitions via an extra XML file.

The default namespace is "'servlet-name'-servlet", for example, "test-servlet" for a servlet-name "test" (leading to a "/WEB-INF/test-servlet.xml" default location with XmlWebApplicationContext). The namespace can also be set explicitly via the "namespace" servlet init-param.

FrameworkServlet may be injected with a web application context, rather than creating its own internally. This is useful in Servlet 3.0+ environments, which support programmatic registration of servlet instances. See FrameworkServlet(WebApplicationContext) Javadoc for details.

Author:
Rod Johnson, Juergen Hoeller, Sam Brannen, Chris Beams, Rossen Stoyanchev, Phillip Webb
See Also:
  • Field Details

    • DEFAULT_NAMESPACE_SUFFIX

      public static final String DEFAULT_NAMESPACE_SUFFIX
      Suffix for WebApplicationContext namespaces. If a servlet of this class is given the name "test" in a context, the namespace used by the servlet will resolve to "test-servlet".
      See Also:
    • DEFAULT_CONTEXT_CLASS

      public static final Class<?> DEFAULT_CONTEXT_CLASS
      Default context class for FrameworkServlet.
      See Also:
    • SERVLET_CONTEXT_PREFIX

      public static final String SERVLET_CONTEXT_PREFIX
      Prefix for the ServletContext attribute for the WebApplicationContext. The completion is the servlet name.
  • Constructor Details

  • Method Details

    • setContextAttribute

      public void setContextAttribute(@Nullable String contextAttribute)
      Set the name of the ServletContext attribute which should be used to retrieve the WebApplicationContext that this servlet is supposed to use.
    • getContextAttribute

      public @Nullable String getContextAttribute()
      Return the name of the ServletContext attribute which should be used to retrieve the WebApplicationContext that this servlet is supposed to use.
    • setContextClass

      public void setContextClass(Class<?> contextClass)
      Set a custom context class. This class must be of type WebApplicationContext.

      When using the default FrameworkServlet implementation, the context class must also implement the ConfigurableWebApplicationContext interface.

      See Also:
    • getContextClass

      public Class<?> getContextClass()
      Return the custom context class.
    • setContextId

      public void setContextId(@Nullable String contextId)
      Specify a custom WebApplicationContext id, to be used as serialization id for the underlying BeanFactory.
    • getContextId

      public @Nullable String getContextId()
      Return the custom WebApplicationContext id, if any.
    • setNamespace

      public void setNamespace(String namespace)
      Set a custom namespace for this servlet, to be used for building a default context config location.
    • getNamespace

      public String getNamespace()
      Return the namespace for this servlet, falling back to default scheme if no custom namespace was set: for example, "test-servlet" for a servlet named "test".
    • setContextConfigLocation

      public void setContextConfigLocation(@Nullable String contextConfigLocation)
      Set the context config location explicitly, instead of relying on the default location built from the namespace. This location string can consist of multiple locations separated by any number of commas and spaces.
    • getContextConfigLocation

      public @Nullable String getContextConfigLocation()
      Return the explicit context config location, if any.
    • setContextInitializers

      public void setContextInitializers(ApplicationContextInitializer<?> @Nullable ... initializers)
      Specify which ApplicationContextInitializer instances should be used to initialize the application context used by this FrameworkServlet.
      See Also:
    • setContextInitializerClasses

      public void setContextInitializerClasses(String contextInitializerClasses)
      Specify the set of fully-qualified ApplicationContextInitializer class names, per the optional "contextInitializerClasses" servlet init-param.
      See Also:
    • setPublishContext

      public void setPublishContext(boolean publishContext)
      Set whether to publish this servlet's context as a ServletContext attribute, available to all objects in the web container. Default is "true".

      This is especially handy during testing, although it is debatable whether it's good practice to let other application objects access the context this way.

    • setPublishEvents

      public void setPublishEvents(boolean publishEvents)
      Set whether this servlet should publish a ServletRequestHandledEvent at the end of each request. Default is "true"; can be turned off for a slight performance improvement, provided that no ApplicationListeners rely on such events.
      See Also:
    • setThreadContextInheritable

      public void setThreadContextInheritable(boolean threadContextInheritable)
      Set whether to expose the LocaleContext and RequestAttributes as inheritable for child threads (using an InheritableThreadLocal).

      Default is "false", to avoid side effects on spawned background threads. Switch this to "true" to enable inheritance for custom child threads which are spawned during request processing and only used for this request (that is, ending after their initial task, without reuse of the thread).

      WARNING: Do not use inheritance for child threads if you are accessing a thread pool which is configured to potentially add new threads on demand (for example, a JDK ThreadPoolExecutor), since this will expose the inherited context to such a pooled thread.

    • setDispatchOptionsRequest

      public void setDispatchOptionsRequest(boolean dispatchOptionsRequest)
      Set whether this servlet should dispatch an HTTP OPTIONS request to the doService(HttpServletRequest, HttpServletResponse) method.

      Default in the FrameworkServlet is "false", applying HttpServlet's default behavior (i.e.enumerating all standard HTTP request methods as a response to the OPTIONS request). Note however that as of 4.3 the DispatcherServlet sets this property to "true" by default due to its built-in support for OPTIONS.

      Turn this flag on if you prefer OPTIONS requests to go through the regular dispatching chain, just like other HTTP requests. This usually means that your controllers will receive those requests; make sure that those endpoints are actually able to handle an OPTIONS request.

      Note that HttpServlet's default OPTIONS processing will be applied in any case if your controllers happen to not set the 'Allow' header (as required for an OPTIONS response).

    • setDispatchTraceRequest

      public void setDispatchTraceRequest(boolean dispatchTraceRequest)
      Set whether this servlet should dispatch an HTTP TRACE request to the doService(HttpServletRequest, HttpServletResponse) method.

      Default is "false", applying HttpServlet's default behavior (i.e. reflecting the message received back to the client).

      Turn this flag on if you prefer TRACE requests to go through the regular dispatching chain, just like other HTTP requests. This usually means that your controllers will receive those requests; make sure that those endpoints are actually able to handle a TRACE request.

      Note that HttpServlet's default TRACE processing will be applied in any case if your controllers happen to not generate a response of content type 'message/http' (as required for a TRACE response).

    • setEnableLoggingRequestDetails

      public void setEnableLoggingRequestDetails(boolean enable)
      Whether to log request params at DEBUG level, and headers at TRACE level. Both may contain sensitive information.

      By default set to false so that request details are not shown.

      Parameters:
      enable - whether to enable or not
      Since:
      5.1
    • isEnableLoggingRequestDetails

      public boolean isEnableLoggingRequestDetails()
      Whether logging of potentially sensitive, request details at DEBUG and TRACE level is allowed.
      Since:
      5.1
    • setApplicationContext

      public void setApplicationContext(ApplicationContext applicationContext)
      Called by Spring via ApplicationContextAware to inject the current application context. This method allows FrameworkServlets to be registered as Spring beans inside an existing WebApplicationContext rather than finding a bootstrapped context.

      Primarily added to support use in embedded servlet containers.

      Specified by:
      setApplicationContext in interface ApplicationContextAware
      Parameters:
      applicationContext - the ApplicationContext object to be used by this object
      Since:
      4.0
      See Also:
    • initServletBean

      protected final void initServletBean() throws jakarta.servlet.ServletException
      Overridden method of HttpServletBean, invoked after any bean properties have been set. Creates this servlet's WebApplicationContext.
      Overrides:
      initServletBean in class HttpServletBean
      Throws:
      jakarta.servlet.ServletException - if subclass initialization fails
    • initWebApplicationContext

      protected WebApplicationContext initWebApplicationContext()
      Initialize and publish the WebApplicationContext for this servlet.

      Delegates to createWebApplicationContext(ApplicationContext) for actual creation of the context. Can be overridden in subclasses.

      Returns:
      the WebApplicationContext instance
      See Also:
    • findWebApplicationContext

      protected @Nullable WebApplicationContext findWebApplicationContext()
      Retrieve a WebApplicationContext from the ServletContext attribute with the configured name. The WebApplicationContext must have already been loaded and stored in the ServletContext before this servlet gets initialized (or invoked).

      Subclasses may override this method to provide a different WebApplicationContext retrieval strategy.

      Returns:
      the WebApplicationContext for this servlet, or null if not found
      See Also:
    • createWebApplicationContext

      protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent)
      Instantiate the WebApplicationContext for this servlet, either a default XmlWebApplicationContext or a custom context class, if set.

      This implementation expects custom contexts to implement the ConfigurableWebApplicationContext interface. Can be overridden in subclasses.

      Do not forget to register this servlet instance as application listener on the created context (for triggering its callback), and to call ConfigurableApplicationContext.refresh() before returning the context instance.

      Parameters:
      parent - the parent ApplicationContext to use, or null if none
      Returns:
      the WebApplicationContext for this servlet
      See Also:
    • configureAndRefreshWebApplicationContext

      protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac)
    • createWebApplicationContext

      protected WebApplicationContext createWebApplicationContext(@Nullable WebApplicationContext parent)
      Instantiate the WebApplicationContext for this servlet, either a default XmlWebApplicationContext or a custom context class, if set. Delegates to #createWebApplicationContext(ApplicationContext).
      Parameters:
      parent - the parent WebApplicationContext to use, or null if none
      Returns:
      the WebApplicationContext for this servlet
      See Also:
    • postProcessWebApplicationContext

      protected void postProcessWebApplicationContext(ConfigurableWebApplicationContext wac)
      Post-process the given WebApplicationContext before it is refreshed and activated as context for this servlet.

      The default implementation is empty. refresh() will be called automatically after this method returns.

      Note that this method is designed to allow subclasses to modify the application context, while initWebApplicationContext() is designed to allow end-users to modify the context through the use of ApplicationContextInitializers.

      Parameters:
      wac - the configured WebApplicationContext (not refreshed yet)
      See Also:
    • applyInitializers

      protected void applyInitializers(ConfigurableApplicationContext wac)
      Delegate the WebApplicationContext before it is refreshed to any ApplicationContextInitializer instances specified by the "contextInitializerClasses" servlet init-param.

      See also postProcessWebApplicationContext(ConfigurableWebApplicationContext), which is designed to allow subclasses (as opposed to end-users) to modify the application context, and is called immediately before this method.

      Parameters:
      wac - the configured WebApplicationContext (not refreshed yet)
      See Also:
    • getServletContextAttributeName

      public String getServletContextAttributeName()
      Return the ServletContext attribute name for this servlet's WebApplicationContext.

      The default implementation returns SERVLET_CONTEXT_PREFIX + servlet name.

      See Also:
    • getWebApplicationContext

      public final @Nullable WebApplicationContext getWebApplicationContext()
      Return this servlet's WebApplicationContext.
    • initFrameworkServlet

      protected void initFrameworkServlet() throws jakarta.servlet.ServletException
      This method will be invoked after any bean properties have been set and the WebApplicationContext has been loaded. The default implementation is empty; subclasses may override this method to perform any initialization they require.
      Throws:
      jakarta.servlet.ServletException - in case of an initialization exception
    • refresh

      public void refresh()
      Refresh this servlet's application context, as well as the dependent state of the servlet.
      See Also:
    • onApplicationEvent

      public void onApplicationEvent(ContextRefreshedEvent event)
      Callback that receives refresh events from this servlet's WebApplicationContext.

      The default implementation calls onRefresh(ApplicationContext), triggering a refresh of this servlet's context-dependent state.

      Parameters:
      event - the incoming ApplicationContext event
    • onRefresh

      protected void onRefresh(ApplicationContext context)
      Template method which can be overridden to add servlet-specific refresh work. Called after successful context refresh.

      This implementation is empty.

      Parameters:
      context - the current WebApplicationContext
      See Also:
    • destroy

      public void destroy()
      Close the WebApplicationContext of this servlet.
      Specified by:
      destroy in interface jakarta.servlet.Servlet
      Overrides:
      destroy in class jakarta.servlet.GenericServlet
      See Also:
    • service

      protected void service(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Override the parent class implementation in order to intercept requests using PATCH or non-standard HTTP methods (WebDAV).
      Overrides:
      service in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
    • doGet

      protected final void doGet(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Delegate GET requests to processRequest/doService.

      Will also be invoked by HttpServlet's default implementation of doHead, with a NoBodyResponse that just captures the content length.

      Overrides:
      doGet in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
      See Also:
    • doPost

      protected final void doPost(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doPost in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
      See Also:
    • doPut

      protected final void doPut(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doPut in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
      See Also:
    • doDelete

      protected final void doDelete(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Overrides:
      doDelete in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
      See Also:
    • doOptions

      protected void doOptions(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Delegate OPTIONS requests to processRequest(HttpServletRequest, HttpServletResponse), if desired.

      Applies HttpServlet's standard OPTIONS processing otherwise, and also if there is still no 'Allow' header set after dispatching.

      Overrides:
      doOptions in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
      See Also:
    • doTrace

      protected void doTrace(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Delegate TRACE requests to processRequest(HttpServletRequest, HttpServletResponse), if desired.

      Applies HttpServlet's standard TRACE processing otherwise.

      Overrides:
      doTrace in class jakarta.servlet.http.HttpServlet
      Throws:
      jakarta.servlet.ServletException
      IOException
      See Also:
    • processRequest

      protected final void processRequest(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws jakarta.servlet.ServletException, IOException
      Process this request, publishing an event regardless of the outcome.

      The actual event handling is performed by the abstract doService(HttpServletRequest, HttpServletResponse) template method.

      Throws:
      jakarta.servlet.ServletException
      IOException
    • buildLocaleContext

      protected @Nullable LocaleContext buildLocaleContext(jakarta.servlet.http.HttpServletRequest request)
      Build a LocaleContext for the given request, exposing the request's primary locale as current locale.
      Parameters:
      request - current HTTP request
      Returns:
      the corresponding LocaleContext, or null if none to bind
      See Also:
    • buildRequestAttributes

      protected @Nullable ServletRequestAttributes buildRequestAttributes(jakarta.servlet.http.HttpServletRequest request, @Nullable jakarta.servlet.http.HttpServletResponse response, @Nullable RequestAttributes previousAttributes)
      Build ServletRequestAttributes for the given request (potentially also holding a reference to the response), taking pre-bound attributes (and their type) into consideration.
      Parameters:
      request - current HTTP request
      response - current HTTP response
      previousAttributes - pre-bound RequestAttributes instance, if any
      Returns:
      the ServletRequestAttributes to bind, or null to preserve the previously bound instance (or not binding any, if none bound before)
      See Also:
    • getUsernameForRequest

      protected @Nullable String getUsernameForRequest(jakarta.servlet.http.HttpServletRequest request)
      Determine the username for the given request.

      The default implementation takes the name of the UserPrincipal, if any. Can be overridden in subclasses.

      Parameters:
      request - current HTTP request
      Returns:
      the username, or null if none found
      See Also:
      • HttpServletRequest.getUserPrincipal()
    • doService

      protected abstract void doService(jakarta.servlet.http.HttpServletRequest request, jakarta.servlet.http.HttpServletResponse response) throws Exception
      Subclasses must implement this method to do the work of request handling, receiving a centralized callback for GET, POST, PUT and DELETE.

      The contract is essentially the same as that for the commonly overridden doGet or doPost methods of HttpServlet.

      This class intercepts calls to ensure that exception handling and event publication takes place.

      Parameters:
      request - current HTTP request
      response - current HTTP response
      Throws:
      Exception - in case of any kind of processing failure
      See Also:
      • HttpServlet.doGet(HttpServletRequest, HttpServletResponse)
      • HttpServlet.doPost(HttpServletRequest, HttpServletResponse)