001: /*
002: * Copyright 2002-2006 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.web.servlet.mvc;
018:
019: import javax.servlet.http.HttpServletRequest;
020: import javax.servlet.http.HttpServletResponse;
021:
022: import org.springframework.web.servlet.ModelAndView;
023:
024: /**
025: * Base Controller interface, representing a component that receives
026: * <code>HttpServletRequest</code> and <code>HttpServletResponse</code>
027: * instances just like a <code>HttpServlet</code> but is able to
028: * participate in an MVC workflow. Controllers are comparable to the
029: * notion of a Struts <code>Action</code>.
030: *
031: * <p>Any implementation of the Controller interface should be a
032: * <i>reusable, thread-safe</i> class, capable of handling multiple
033: * HTTP requests throughout the lifecycle of an application. To be able to
034: * configure a Controller easily, Controller implementations are encouraged
035: * to be (and usually are) JavaBeans.
036: * </p>
037: *
038: * <p><b><a name="workflow">Workflow</a></b></p>
039: *
040: * <p>
041: * After a <cde>DispatcherServlet</code> has received a request and has
042: * done its work to resolve locales, themes and suchlike, it then tries
043: * to resolve a Controller, using a
044: * {@link org.springframework.web.servlet.HandlerMapping HandlerMapping}.
045: * When a Controller has been found to handle the request, the
046: * {@link #handleRequest(HttpServletRequest, HttpServletResponse) handleRequest}
047: * method of the located Controller will be invoked; the located Controller
048: * is then responsible for handling the actual request and - if applicable -
049: * returning an appropriate
050: * {@link org.springframework.web.servlet.ModelAndView ModelAndView}.
051: * So actually, this method is the main entrypoint for the
052: * {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet}
053: * which delegates requests to controllers. This method - and also this interface -
054: * should preferrably not be implemented by custom controllers <i>directly</i>, since
055: * abstract controller also provided by this package already provide a lot of
056: * functionality for typical use cases in web applications. A few examples of
057: * those controllers:
058: * {@link AbstractController AbstractController},
059: * {@link AbstractCommandController AbstractCommandController},
060: * {@link SimpleFormController SimpleFormController}.</p>
061: *
062: * <p>So basically any <i>direct</i> implementation of the Controller interface
063: * just handles HttpServletRequests and should return a ModelAndView, to be further
064: * interpreted by the DispatcherServlet. Any additional functionality such as
065: * optional validation, form handling, etc should be obtained through extending
066: * one of the abstract controller classes mentioned above.</p>
067: *
068: * <p><b>Notes on design and testing</b></p>
069: *
070: * <p>The Controller interface is explicitly designed to operate on HttpServletRequest
071: * and HttpServletResponse objects, just like an HttpServlet. It does not aim to
072: * decouple itself from the Servlet API, in contrast to, for example, WebWork, JSF or Tapestry.
073: * Instead, the full power of the Servlet API is available, allowing Controllers to be
074: * general-purpose: a Controller is able to not only handle web user interface
075: * requests but also to process remoting protocols or to generate reports on demand.</p>
076: *
077: * <p>Controllers can easily be tested by passing in mock objects for the
078: * HttpServletRequest and HttpServletResponse objects as parameters to the
079: * {@link #handleRequest(HttpServletRequest, HttpServletResponse) handleRequest}
080: * method. As a convenience, Spring ships with a set of Servlet API mocks
081: * that are suitable for testing any kind of web components, but are particularly
082: * suitable for testing Spring web controllers. In contrast to a Struts Action,
083: * there is no need to mock the ActionServlet or any other infrastructure;
084: * HttpServletRequest and HttpServletResponse are sufficient.</p>
085: *
086: * <p>If Controllers need to be aware of specific environment references, they can
087: * choose to implement specific awareness interfaces, just like any other bean in a
088: * Spring (web) application context can do, for example:</p>
089: * <ul>
090: * <li><code>org.springframework.context.ApplicationContextAware</code></li>
091: * <li><code>org.springframework.context.ResourceLoaderAware</code></li>
092: * <li><code>org.springframework.web.context.ServletContextAware</code></li>
093: * </ul>
094: *
095: * <p>Such environment references can easily be passed in testing environments,
096: * through the corresponding setters defined in the respective awareness interfaces.
097: * In general, it is recommended to keep the dependencies as minimal as possible:
098: * for example, if all you need is resource loading, implement ResourceLoaderAware only.
099: * Alternatively, derive from the WebApplicationObjectSupport base class, which gives
100: * you all those references through convenient accessors - but requires an
101: * ApplicationContext reference on initialization.
102: *
103: * <p>Controllers can optionally implement the LastModified interface.
104: *
105: * @author Rod Johnson
106: * @author Juergen Hoeller
107: * @see LastModified
108: * @see SimpleControllerHandlerAdapter
109: * @see AbstractController
110: * @see AbstractCommandController
111: * @see SimpleFormController
112: * @see org.springframework.mock.web.MockHttpServletRequest
113: * @see org.springframework.mock.web.MockHttpServletResponse
114: * @see org.springframework.context.ApplicationContextAware
115: * @see org.springframework.context.ResourceLoaderAware
116: * @see org.springframework.web.context.ServletContextAware
117: * @see org.springframework.web.context.support.WebApplicationObjectSupport
118: */
119: public interface Controller {
120:
121: /**
122: * Process the request and return a ModelAndView object which the DispatcherServlet
123: * will render. A <code>null</code> return value is not an error: It indicates that
124: * this object completed request processing itself, thus there is no ModelAndView
125: * to render.
126: * @param request current HTTP request
127: * @param response current HTTP response
128: * @return a ModelAndView to render, or <code>null</code> if handled directly
129: * @throws Exception in case of errors
130: */
131: ModelAndView handleRequest(HttpServletRequest request,
132: HttpServletResponse response) throws Exception;
133:
134: }
|