diff --git a/spring-framework-reference/src/mvc.xml b/spring-framework-reference/src/mvc.xml
index 992a2361605..7c619b0bfe1 100644
--- a/spring-framework-reference/src/mvc.xml
+++ b/spring-framework-reference/src/mvc.xml
@@ -28,8 +28,8 @@
Some methods in the core classes of Spring Web MVC are marked
final. As a developer you cannot override these
- methods to supply your own behavior. This has not been done arbitrarily, but
- specifically with this principal in mind.
+ methods to supply your own behavior. This has not been done arbitrarily,
+ but specifically with this principal in mind.
For an explanation of this principle, refer to Expert
Spring Web MVC and Web Flow by Seth Ladd and others;
@@ -161,7 +161,7 @@
A JSP form tag library, introduced in Spring 2.0,
- that makes writing forms in JSP pages much easier. For
+ that makes writing forms in JSP pages much easier. For
information on the tag library descriptor, see the appendix entitled
@@ -281,9 +281,8 @@
WebApplicationContext, which inherits all
the beans already defined in the root
WebApplicationContext. These inherited
- beans can be overridden in the servlet-specific scope, and
- you can define new scope-specific beans local to a given servlet
- instance.
+ beans can be overridden in the servlet-specific scope, and you can define
+ new scope-specific beans local to a given servlet instance.
@@ -327,11 +326,12 @@
With the above servlet configuration in place, you
will need to have a file called /WEB-INF/golfing-servlet.xml in your application;
- this file will contain all of your Spring Web MVC-specific components
- (beans). You can change the exact location of this configuration file
- through a servlet initialization parameter (see below for details).
-
+ role="bold">golfing-servlet.xml in your
+ application; this file will contain all of your Spring Web MVC-specific
+ components (beans). You can change the exact location of this
+ configuration file through a servlet initialization parameter (see below
+ for details).
+
The WebApplicationContext is an
@@ -353,7 +353,7 @@
WebApplicationContext, just as you
configure any other bean. However, for most beans, sensible defaults are
provided so you initially do not need to configure them. These
- beans are described in the following table.
+ beans are described in the following table.
Special beans in the
@@ -397,7 +397,7 @@
- locale
+ locale
resolverA locale resolver
@@ -424,7 +424,7 @@
handler exception
resolvers
- Contains functionality to map exceptions to views or
+ Contains functionality to map exceptions to views or
implement other more complex exception handling code.
@@ -451,14 +451,17 @@
in the process to resolve the locale to use when processing the
request (rendering the view, preparing data, and so on). If you do not
need locale resolving, you do not need it.
-
+
The theme resolver is bound to the request to let elements such
as views determine which theme to use. If you do not use themes, you
can ignore it.
-
+
+
+
+
@@ -479,10 +482,11 @@
If a model is returned, the view is rendered. If no model is
- returned, (may be due to a preprocessor or postprocessor
- intercepting the request, perhaps for security reasons), no view is
- rendered, because the request could already have been fulfilled.
-
+ returned, (may be due to a preprocessor or postprocessor intercepting
+ the request, perhaps for security reasons), no view is rendered,
+ because the request could already have been fulfilled.
+
+
@@ -497,18 +501,19 @@
specified by the Servlet API. The process of determining the last
modification date for a specific request is straightforward: the
DispatcherServlet looks up an appropriate handler
- mapping and tests whether the handler that is found
- implements the
+ mapping and tests whether the handler that is found implements the
LastModified
interface. If so, the value of the long
getLastModified(request) method of the
LastModified interface is returned to the
client.
- You can customize individual DispatcherServlet
- instances by adding servlet initialization parameters (init-param elements)
- to the servlet declaration in the web.xml file. See the following table for the list
- of supported parameters.
+ You can customize individual
+ DispatcherServlet instances by adding servlet
+ initialization parameters (init-param elements) to the
+ servlet declaration in the web.xml file. See the
+ following table for the list of supported parameters.
+
@@ -588,7 +593,8 @@
PetClinic sample, a web application that leverages
the annotation support described in this section, in the context of
simple form processing. The PetClinic application
- resides in the org.springframework.samples.petclinic module.
+ resides in the org.springframework.samples.petclinic
+ module.
@@ -640,7 +646,7 @@ public class HelloWorldController {
for autodetection, aligned with Spring general support for detecting
component classes in the classpath and auto-registering bean definitions
for them.
-
+
To enable autodetection of such annotated controllers, you add
component scanning to your configuration. Use the
spring-context schema as shown in the following XML
@@ -670,14 +676,14 @@ public class HelloWorldController {
You use the @RequestMapping
annotation to map URLs such as /appointments onto
- an entire class or a particular handler method. Typically the class-level annotation
- maps a specific request path (or path pattern) onto a form controller,
- with additional method-level annotations narrowing the primary mapping
- for a specific HTTP method request method ("GET"/"POST") or specific
- HTTP request parameters.
+ an entire class or a particular handler method. Typically the
+ class-level annotation maps a specific request path (or path pattern)
+ onto a form controller, with additional method-level annotations
+ narrowing the primary mapping for a specific HTTP method request method
+ ("GET"/"POST") or specific HTTP request parameters.
- The following example shows a controller in a Spring MVC application
- that uses this annotation:
+ The following example shows a controller in a Spring MVC
+ application that uses this annotation:@Controller
@RequestMapping("/appointments")
@@ -818,15 +824,15 @@ public String findOwner(@PathVariable String ow
names can only be done if your code is compiled with debugging
enabled. If you do have not debugging enabled, you must specify the
name of the URI Template variable name in the @PathVariable annotation
- in order to bind the resolved value of the variable name to a
- method parameter. For example:
+ in order to bind the resolved value of the variable name to a method
+ parameter. For example:
@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String ownerId, Model model) {
// implementation omitted
}
-
- You can also use a controller method with the following
+
+ You can also use a controller method with the following
signature:@RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
@@ -847,8 +853,8 @@ public String findPet(@PathVariable String owne
}
- The following code snippet shows the usage of path variables on a
- relative path, so that the findPet() method
+ The following code snippet shows the usage of path variables on
+ a relative path, so that the findPet() method
will be invoked for /owners/42/pets/21, for
instance.
@@ -922,21 +928,22 @@ public class RelativePathUriTemplateController {
Similarly, path mappings can be narrowed down through header
conditions:
-
+
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping(value = "/pets", method = RequestMethod.POST, headers="content-type=text/*")
+ role="bold">headers="content-type=text/*")
public void addPet(Pet pet, @PathVariable String ownerId) {
// implementation omitted
}
}
- In the above example, the addPet() method is
- only invoked when the content-type matches the text/*
- pattern, for example, text/xml.
+ In the above example, the addPet()
+ method is only invoked when the content-type
+ matches the text/* pattern, for example,
+ text/xml.
@@ -946,8 +953,7 @@ public class RelativePathUriTemplateController {
@RequestMapping can have very flexible
signatures. They may have arguments of the following types, in
arbitrary order (except for validation results, which need to follow
- right after the corresponding command object, if desired):
-
+ right after the corresponding command object, if desired):
Request or response objects (Servlet API). Choose any
@@ -1110,10 +1116,10 @@ public class RelativePathUriTemplateController {
A String value that is interpreted
- as the logical view name, with the model implicitly determined through
- command objects and @ModelAttribute annotated
- reference data accessor methods. The handler method may also
- programmatically enrich the model by declaring a
+ as the logical view name, with the model implicitly determined
+ through command objects and @ModelAttribute
+ annotated reference data accessor methods. The handler method
+ may also programmatically enrich the model by declaring a
Model argument (see
above).
@@ -1293,8 +1299,8 @@ public String helloWorld() {
The above example will result in the text Hello
World being written to the HTTP response stream.
- As with @RequestBody, Spring converts
- the returned object to a response body by using an
+ As with @RequestBody, Spring
+ converts the returned object to a response body by using an
HttpMessageConverter. For more
information on these converters, see the previous section and Message Converters.
@@ -1312,10 +1318,10 @@ public String helloWorld() {
controller gets a reference to the object holding the data entered in
the form.
- You can also use @ModelAttribute at
- the method level to provide reference data for
- the model (see the populatePetTypes() method in
- the following example). For this usage the method signature can contain
+ You can also use @ModelAttribute at the
+ method level to provide reference data for the
+ model (see the populatePetTypes() method in the
+ following example). For this usage the method signature can contain
the same types as documented previously for the
@RequestMapping annotation.
@@ -1371,12 +1377,12 @@ public class EditPetForm {
The type-level @SessionAttributes
annotation declares session attributes used by a specific handler.
This will typically list the names of model attributes or types of
- model attributes which should be
- transparently stored in the session or some conversational storage,
- serving as form-backing beans between subsequent requests.
+ model attributes which should be transparently stored in the session
+ or some conversational storage, serving as form-backing beans between
+ subsequent requests.
- The following code snippet shows the usage of this
- annotation, specifying the model attribute name:
+ The following code snippet shows the usage of this annotation,
+ specifying the model attribute name:@Controller
@RequestMapping("/editPet.do")
@@ -1431,7 +1437,8 @@ Keep-Alive 300
The following code sample demonstrates how to get the value of
- the Accept-Encoding and Keep-Alive headers:
+ the Accept-Encoding and
+ Keep-Alive headers:@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,
@@ -1537,88 +1544,80 @@ public class MyFormController {
DefaultAnnotationHandlerMapping, which looks for
@RequestMapping annotations on
@Controllers. Typically, you do not need to
- override this default mapping, unless you need to override the default property values.
- These properties are:
+ override this default mapping, unless you need to override the default
+ property values. These properties are:
-
-
- interceptors
-
-
- List of interceptors to use.
- HandlerInterceptors are discussed in
- .
-
-
-
+
+
+ interceptors
+
+ List of interceptors to use.
+ HandlerInterceptors are discussed in
+ .
+
+
-
- defaultHandler
-
- Default handler to use, when this handler mapping does not result
- in a matching handler.
-
-
+
+ defaultHandler
+
+ Default handler to use, when this handler mapping does not
+ result in a matching handler.
+
+
-
- order
-
-
- Based on the value of the order property (see the
- org.springframework.core.Ordered
- interface), Spring sorts all handler mappings available in the context
- and applies the first matching handler.
-
-
-
+
+ order
+
+ Based on the value of the order property (see the
+ org.springframework.core.Ordered interface),
+ Spring sorts all handler mappings available in the context and
+ applies the first matching handler.
+
+
-
- alwaysUseFullPath
-
-
- If true , Spring uses the full path within the current
- servlet context to find an appropriate handler. If false
- (the default), the path within the current servlet mapping is used. For
- example, if a servlet is mapped using /testing/*
- and the alwaysUseFullPath property is set to true,
- /testing/viewPage.html is used, whereas if the
- property is set to false, /viewPage.html is used.
-
-
-
+
+ alwaysUseFullPath
+
+ If true , Spring uses the full path within
+ the current servlet context to find an appropriate handler. If
+ false (the default), the path within the current
+ servlet mapping is used. For example, if a servlet is mapped using
+ /testing/* and the
+ alwaysUseFullPath property is set to true,
+ /testing/viewPage.html is used, whereas if the
+ property is set to false, /viewPage.html is
+ used.
+
+
-
- urlDecode
-
-
- Defaults to true, as of Spring 2.5.
- If you prefer to compare encoded paths, set this flag to false.
- However, the HttpServletRequest always exposes the
- servlet path in decoded form. Be aware that the servlet path will not match when
- compared with encoded paths.
-
-
-
+
+ urlDecode
+
+ Defaults to true, as of Spring 2.5.
+ If you prefer to compare encoded paths, set this flag to
+ false. However, the
+ HttpServletRequest always exposes the
+ servlet path in decoded form. Be aware that the servlet path will
+ not match when compared with encoded paths.
+
+
-
- lazyInitHandlers
-
-
- Allows lazy initialization of singleton
- handlers (prototype handlers are always lazy-initialized).
- The default value is false.
-
-
-
-
+
+ lazyInitHandlers
+
+ Allows lazy initialization of singleton
+ handlers (prototype handlers are always lazy-initialized). The
+ default value is false.
+
+
+
-
-
- The alwaysUseFullPath, urlDecode, and
- lazyInitHandlers properties are only available to subclasses of
- org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.
-
-
+
+ The alwaysUseFullPath,
+ urlDecode, and lazyInitHandlers
+ properties are only available to subclasses of
+ org.springframework.web.servlet.handler.AbstractUrlHandlerMapping.
+ The following example shows how to override the default mapping and
add an interceptor:
@@ -1660,12 +1659,12 @@ public class MyFormController {
view) and does not continue executing the other interceptors and the
actual handler in the execution chain.
- The following example defines a handler mapping which maps
- all requests matching the URL patterns "/*.form" and "/*.view" to a particular
- controller, editAccountFormController.
- An interceptor has been added that intercepts these
- requests and reroutes the user to a specific page if the time is not
- between 9 a.m. and 6 p.m.
+ The following example defines a handler mapping which maps all
+ requests matching the URL patterns "/*.form" and "/*.view" to a
+ particular controller, editAccountFormController. An
+ interceptor has been added that intercepts these requests and reroutes
+ the user to a specific page if the time is not between 9 a.m. and 6
+ p.m.<beans>
<bean id="handlerMapping"
@@ -1757,13 +1756,13 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
ViewResolver interfaceAs discussed in , all handler
- methods in the Spring Web MVC controllers must resolve to a logical
- view name, either explicitly (e.g., by returning a String,
- View, or ModelAndView) or implicitly
- (i.e., based on conventions). Views in Spring are
- addressed by a logical view name and are resolved by a view resolver. Spring
- comes with quite a few view resolvers. This table lists most of them; a
- couple of examples follow.
+ methods in the Spring Web MVC controllers must resolve to a logical view
+ name, either explicitly (e.g., by returning a String,
+ View, or ModelAndView) or
+ implicitly (i.e., based on conventions). Views in Spring are addressed
+ by a logical view name and are resolved by a view resolver. Spring comes
+ with quite a few view resolvers. This table lists most of them; a couple
+ of examples follow.
View resolvers
@@ -1830,10 +1829,9 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
Convenient subclass of
UrlBasedViewResolver that supports
InternalResourceView (in effect, Servlets
- and JSPs) and subclasses such as
- JstlView and
- TilesView. You can specify the view class
- for all views generated by this resolver by using
+ and JSPs) and subclasses such as JstlView
+ and TilesView. You can specify the view
+ class for all views generated by this resolver by using
setViewClass(..). See the Javadocs for the
UrlBasedViewResolver class for
details.
@@ -1875,8 +1873,8 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
<property name="suffix" value=".jsp"/>
</bean>
- When returning test as a logical view name, this view
- resolver forwards the request to the
+ When returning test as a logical view name,
+ this view resolver forwards the request to the
RequestDispatcher that will send the request to
/WEB-INF/jsp/test.jsp.
@@ -1894,11 +1892,11 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
ResourceBundle identified by the basename, and
for each view it is supposed to resolve, it uses the value of the
property [viewname].(class) as the view class and the
- value of the property [viewname].url as the view url.
- Examples can be found in the next chapter which covers view technologies.
- As you can see, you can identify a parent view, from which all views in
- the properties file extend. This
- way you can specify a default view class, for example.
+ value of the property [viewname].url as the view url.
+ Examples can be found in the next chapter which covers view
+ technologies. As you can see, you can identify a parent view, from which
+ all views in the properties file extend. This way you can
+ specify a default view class, for example.
Subclasses of AbstractCachingViewResolver
@@ -1950,7 +1948,8 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
If a specific view resolver does not result in a view, Spring
examines the context for other view resolvers. If additional view
resolvers exist, Spring continues to inspect them. If
- they do not exist, Spring throws an Exception.
+ they do not exist, Spring throws an
+ Exception.The contract of a view resolver specifies that a view resolver
can return null to indicate the view could not be
@@ -1977,34 +1976,35 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
view name, which a view resolver resolves to a particular view
technology. For view technologies such as JSPs that are processed
through the Servlet or JSP engine, this resolution is usually handled
- through the combination of InternalResourceViewResolver and
- InternalResourceView, which
- issues an internal forward or include via the Servlet API's
+ through the combination of
+ InternalResourceViewResolver and
+ InternalResourceView, which issues an internal
+ forward or include via the Servlet API's
RequestDispatcher.forward(..) method or
RequestDispatcher.include() method. For other view
- technologies, such as Velocity, XSLT, and so on, the view itself
- writes the content directly to the response stream.
+ technologies, such as Velocity, XSLT, and so on, the view itself writes
+ the content directly to the response stream.
It is sometimes desirable to issue an HTTP redirect back to the
- client, before the view is rendered. This is desirable, for example, when
- one controller has been called with POSTed data, and
- the response is actually a delegation to another controller (for example
- on a successful form submission). In this case, a normal internal
- forward will mean that the other controller will also see the same
- POST data, which is potentially problematic if it can
- confuse it with other expected data. Another reason to perform a redirect
- before displaying the result is to eliminate the possibility
- of the user submitting the form data multiple times. In this scenario,
- the browser will first send an initial POST; it will
- then receive a response to redirect to a different URL; and finally
- the browser will perform a subsequent GET for the
- URL named in the redirect response. Thus, from the perspective of the
+ client, before the view is rendered. This is desirable, for example,
+ when one controller has been called with POSTed data,
+ and the response is actually a delegation to another controller (for
+ example on a successful form submission). In this case, a normal
+ internal forward will mean that the other controller will also see the
+ same POST data, which is potentially problematic if
+ it can confuse it with other expected data. Another reason to perform a
+ redirect before displaying the result is to eliminate the possibility of
+ the user submitting the form data multiple times. In this scenario, the
+ browser will first send an initial POST; it will then
+ receive a response to redirect to a different URL; and finally the
+ browser will perform a subsequent GET for the URL
+ named in the redirect response. Thus, from the perspective of the
browser, the current page does not reflect the result of a
- POST but rather of a GET. The
- end effect is that there is no way the user can accidentally
- re-POST the same data by performing a refresh. The refresh
- forces a GET of the result page, not a resend of the
- initial POST data.
+ POST but rather of a GET. The end
+ effect is that there is no way the user can accidentally
+ re-POST the same data by performing a refresh. The
+ refresh forces a GET of the result page, not a resend
+ of the initial POST data.
RedirectView
@@ -2020,10 +2020,10 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
The RedirectView issues an
HttpServletResponse.sendRedirect() call that
returns to the client browser as an HTTP redirect. All
- model attributes are exposed as HTTP query parameters. This means
- that the model must contain only objects (generally Strings or
- objects converted to a String representation), which can be readily converted to a
- textual HTTP query parameter.
+ model attributes are exposed as HTTP query parameters. This means that
+ the model must contain only objects (generally Strings or objects
+ converted to a String representation), which can be readily converted
+ to a textual HTTP query parameter.
If you use RedirectView and the view is
created by the controller itself, it is recommended that you configure
@@ -2038,19 +2038,19 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
While the use of RedirectView works fine,
if the controller itself creates the
- RedirectView, there is no avoiding the
- fact that the controller is aware that a redirection is happening.
- This is really suboptimal and couples things too tightly. The
- controller should not really care about how the response gets
- handled. In general it should operate only in terms of view names that
- have been injected into it.
+ RedirectView, there is no avoiding the fact
+ that the controller is aware that a redirection is happening. This is
+ really suboptimal and couples things too tightly. The controller
+ should not really care about how the response gets handled. In general
+ it should operate only in terms of view names that have been injected
+ into it.The special redirect: prefix allows you to
accomplish this. If a view name is returned that has the prefix
- redirect:, the UrlBasedViewResolver (and all
- subclasses) will recognize this as a special indication that a redirect is
- needed. The rest of the view name will be treated as the redirect
- URL.
+ redirect:, the
+ UrlBasedViewResolver (and all subclasses) will
+ recognize this as a special indication that a redirect is needed. The
+ rest of the view name will be treated as the redirect URL.
The net effect is the same as if the controller had returned a
RedirectView, but now the controller itself can
@@ -2082,9 +2082,9 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
multiple view resolvers, instead.)As with the redirect: prefix, if the view
- name with the forward: prefix is injected into the controller, the
- controller does not detect that anything special is happening in terms
- of handling the response.
+ name with the forward: prefix is injected into the
+ controller, the controller does not detect that anything special is
+ happening in terms of handling the response.
@@ -2099,10 +2099,9 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
- Use a distinct URI for each resource,
- typically by using a different file extension in the URI. For
- example, the URI
- http://www.example.com/users/fred.pdf requests a PDF
+ Use a distinct URI for each resource, typically by using a
+ different file extension in the URI. For example, the URI
+ http://www.example.com/users/fred.pdf requests a PDF
representation of the user fred, and
http://www.example.com/users/fred.xml requests an
XML representation.
@@ -2115,27 +2114,27 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
set the Accept HTTP request header to list the
media
types that it understands. For example, an HTTP request for
- http://www.example.com/users/fred with an
- Accept header set to application/pdf
- requests a PDF representation of the user fred, while
- http://www.example.com/users/fred with an
- Accept header set to text/xml
- requests an XML representation. This strategy is known as content
- negotiation.
+ http://www.example.com/users/fred with an
+ Accept header set to application/pdf
+ requests a PDF representation of the user fred, while
+ http://www.example.com/users/fred with an
+ Accept header set to text/xml
+ requests an XML representation. This strategy is known as content
+ negotiation.
- One issue with the Accept header is that it is
- impossible to set it in a web browser within HTML. For example, in Firefox, it is fixed
- to:
-
+ One issue with the Accept header is that it
+ is impossible to set it in a web browser within HTML. For example, in
+ Firefox, it is fixed to:Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8For this reason it is common to see the use of a distinct URI
- for each representation when developing browser based web applications.
+ for each representation when developing browser based web
+ applications.
To support multiple representations of a resource, Spring provides
@@ -2154,20 +2153,21 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
ViewResolvers. The first
View in the list that has a compatible
Content-Type returns the representation to the
- client. If a compatible view cannot be supplied by the
- ViewResolver chain, then the list of views specified
- through the DefaultViews property will be consulted. This
- latter option is appropriate for singleton Views that
- can render an appropriate representation of the current resource regardless
- of the logical view name. The Accept header may include
- wildcards, for example text/*, in which case a View whose
+ client. If a compatible view cannot be supplied by the
+ ViewResolver chain, then the list of views
+ specified through the DefaultViews property will be
+ consulted. This latter option is appropriate for singleton
+ Views that can render an appropriate
+ representation of the current resource regardless of the logical view
+ name. The Accept header may include wildcards, for
+ example text/*, in which case a View whose
Context-Type was text/xml is a compatible match.
- To support the resolution of a view based on a file extension,
- use the ContentNegotiatingViewResolver bean
- property mediaTypes to specify a mapping of file
- extensions to media types. For more information on the algorithm used to
- determine the request media type, refer to the API documentation for
+ To support the resolution of a view based on a file extension, use
+ the ContentNegotiatingViewResolver bean property
+ mediaTypes to specify a mapping of file extensions to
+ media types. For more information on the algorithm used to determine the
+ request media type, refer to the API documentation for
ContentNegotiatingViewResolver.Here is an example configuration of a
@@ -2190,10 +2190,10 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
</bean>
</list>
</property>
- <property name="defaultViews">
- <list>
- <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
- </list>
+ <property name="defaultViews">
+ <list>
+ <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
+ </list>
</property>
</bean>
@@ -2212,25 +2212,29 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
feed. For more information on creating an Atom Feed representation, see
the section Atom Views.
- In the above configuration, if a request is made with an .html
- extension, the view resolver looks for a view that matches the text/html
- media type. The InternalResourceViewResolver
- provides the matching view for text/html. If the request is made with
- the file extension .atom, the view resolver looks for a view that
- matches the application/atom+xml media type. This view is provided by
- the BeanNameViewResolver that maps to the
- SampleContentAtomView if the view name returned
- is content. If the request is made with the file extension
- .json, the MappingJacksonJsonView instance from
- the DefaultViews list will be selected regardless of the view name.
- Alternatively, client requests can be made without a file extension but with the
- Accept header set to the preferred media-type, and the same resolution
- of request to views would occur.
+ In the above configuration, if a request is made with an
+ .html extension, the view resolver looks for a view
+ that matches the text/html media type. The
+ InternalResourceViewResolver provides the
+ matching view for text/html. If the request is made
+ with the file extension .atom, the view resolver
+ looks for a view that matches the
+ application/atom+xml media type. This view is
+ provided by the BeanNameViewResolver that maps to
+ the SampleContentAtomView if the view name
+ returned is content. If the request is made with
+ the file extension .json, the
+ MappingJacksonJsonView instance from the
+ DefaultViews list will be selected regardless of the
+ view name. Alternatively, client requests can be made without a file
+ extension but with the Accept header set to the
+ preferred media-type, and the same resolution of request to views would
+ occur.If ContentNegotiatingViewResolver's list
- of ViewResolvers is not configured explicitly, it automatically
- uses any ViewResolvers defined in the application context.
+ of ViewResolvers is not configured explicitly, it automatically uses
+ any ViewResolvers defined in the application context.The corresponding controller code that returns an Atom RSS feed
@@ -2287,8 +2291,8 @@ public class ContentController {
This locale resolver inspects the
accept-language header in the request that was sent
- by the client (e.g., a web browser). Usually this header field contains the
- locale of the client's operating system.
+ by the client (e.g., a web browser). Usually this header field contains
+ the locale of the client's operating system.
@@ -2298,7 +2302,8 @@ public class ContentController {
might exist on the client to see if a locale is specified. If so, it
uses the specified locale. Using the properties of this locale resolver,
you can specify the name of the cookie as well as the maximum age. Find
- below an example of defining a CookieLocaleResolver.
+ below an example of defining a
+ CookieLocaleResolver.
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
@@ -2355,8 +2360,8 @@ public class ContentController {
/Limits the visibility of the cookie to a certain part of
- your site. When cookiePath is specified, the cookie will only
- be visible to that path and the paths below it.
+ your site. When cookiePath is specified, the cookie will only be
+ visible to that path and the paths below it.
@@ -2415,21 +2420,22 @@ public class ContentController {
Overview of themes
- You can apply Spring Web MVC framework themes to set the overall look-and-feel
- of your application, thereby enhancing user experience. A theme is a
- collection of static resources, typically style sheets and images, that
- affect the visual style of the application.
+ You can apply Spring Web MVC framework themes to set the overall
+ look-and-feel of your application, thereby enhancing user experience. A
+ theme is a collection of static resources, typically style sheets and
+ images, that affect the visual style of the application.Defining themes
- To use themes in your web application, you must set up an implementation of the
- org.springframework.ui.context.ThemeSource interface.
- The WebApplicationContext interface extends
- ThemeSource but delegates its
- responsibilities to a dedicated implementation. By default the delegate
- will be an
+ To use themes in your web application, you must set up an
+ implementation of the
+ org.springframework.ui.context.ThemeSource
+ interface. The WebApplicationContext
+ interface extends ThemeSource but
+ delegates its responsibilities to a dedicated implementation. By default
+ the delegate will be an
org.springframework.ui.context.support.ResourceBundleThemeSource
implementation that loads properties files from the root of the
classpath. To use a custom ThemeSource
@@ -2525,15 +2531,16 @@ background=/themes/cool/img/coolBg.jpgCookieThemeResolver
- The selected theme is stored in a cookie on the client.
+ The selected theme is stored in a cookie on the
+ client.
Spring also provides a
- ThemeChangeInterceptor that allows theme
- changes on every request with a simple request parameter.
+ ThemeChangeInterceptor that allows theme changes
+ on every request with a simple request parameter.
@@ -2546,13 +2553,10 @@ background=/themes/cool/img/coolBg.jpg
Spring's built-in multipart support handles file uploads in web
applications. You enable this multipart support with pluggable
MultipartResolver objects, defined in the
- org.springframework.web.multipart package. Out
- of the box, Spring provides a
- MultipartResolver for use with
- Commons FileUpload (). How
- uploading files is supported will be described in the rest of this
- chapter.
+ org.springframework.web.multipart package. Spring
+ provides a MultipartResolver for use with
+
+ Commons FileUpload).
By default, Spring does no multipart handling, because some
developers want to handle multiparts themselves. You enable Spring
@@ -2590,7 +2594,7 @@ background=/themes/cool/img/coolBg.jpg
current HttpServletRequest into a
MultipartHttpServletRequest that supports
multipart file uploads. Using the
- MultipartHttpServletRequest you can get
+ MultipartHttpServletRequest, you can get
information about the multiparts contained by this request and actually
get access to the multipart files themselves in your controllers.
@@ -2599,10 +2603,10 @@ background=/themes/cool/img/coolBg.jpg
Handling a file upload in a formAfter the MultipartResolver completes its
- job, the request is processed like any other. To use it,
- you create a form with an upload field (see immediately below) that will
- allow the user to upload a form. Then let Spring bind the file onto your
- form (backing object).
+ job, the request is processed like any other. First, create a form with
+ a file input that will allow the user to upload a form. The encoding
+ attribute (enctype="multipart/form-data") lets the
+ browser know how to encode the form as multipart request:
<html>
<head>
@@ -2610,189 +2614,54 @@ background=/themes/cool/img/coolBg.jpg
</head>
<body>
<h1>Please upload a file</h1>
- <form method="post" action="upload.form" enctype="multipart/form-data">
+ <form method="post" action="/form" enctype="multipart/form-data">
+ <input type="text" name="name"/>
<input type="file" name="file"/>
<input type="submit"/>
</form>
</body>
</html>
- As you can see, we've created a field named after the property of
- the bean that holds the byte[]. The
- encoding attribute (enctype="multipart/form-data")
- lets the browser know how to encode the multipart fields.
+ The next step is to create a controller that handles the file
+ upload.This controller is very similar to a normal annotated
+ @Controllers, except that we use
+ MultipartHttpServletRequest or
+ MultipartFile in the method parameters:
+ @Controller
+public class FileUpoadController {
- As with any property that is not automatically convertible
- to a string or primitive type, you must register a custom editor with
- the ServletRequestDatabinder to be able to put
- binary data in your objects. Two editors can handle files and set the
- results on an object. A StringMultipartEditor can
- convert files to Strings (using a user-defined character set), and a
- ByteArrayMultipartEditor converts files to byte
- arrays. They function just as the
- CustomDateEditor does.
+ @RequestMapping(value = "/form", method = RequestMethod.POST)
+ public String handleFormUpload(@RequestParam("name") String name,
+ @RequestParam("file") MultipartFile file) {
- So, to be able to upload files using an HTML form, declare the
- resolver, a url mapping to a controller that will process the bean, and
- the controller itself:
+ if (!file.isEmpty()) {
+ byte[] bytes = file.getBytes();
+ // store the bytes somewhere
+ return "redirect:uploadSuccess";
+ } else {
+ return "redirect:uploadFailure";
+ }
+ }
+
+}
+
+ Note how the @RequestParam method
+ parameters map to the input elements declared in the form. In this
+ example, nothing is done with the byte[], but in
+ practice you can save it in a database, store it on the file system, and
+ so on.
+
+ Finally, you will have to declare the controller and the resolver
+ in the application context:<beans>
- <!-- lets use the Commons-based implementation of the MultipartResolver interface -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
-
- <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
- <property name="mappings">
- <value>
- /upload.form=fileUploadController
- </value>
- </property>
- </bean>
-
- <bean id="fileUploadController" class="examples.FileUploadController">
- <property name="commandClass" value="examples.FileUploadBean"/>
- <property name="formView" value="fileuploadform"/>
- <property name="successView" value="confirmation"/>
- </bean>
+ <!-- Declare explicitly, or use <context:annotation-config/> -->
+ <bean id="fileUploadController" class="examples.FileUploadController"/>
</beans>
-
- After that, create the controller and the actual class to hold the
- file property:
-
- public class FileUploadController extends SimpleFormController {
-
- protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
- Object command, BindException errors) throws ServletException, IOException {
-
- // cast the bean
- FileUploadBean bean = (FileUploadBean) command;
-
- // let's see if there's content there
- byte[] file = bean.getFile();
- if (file == null) {
- // hmm, that's strange, the user did not upload anything
- }
-
- // well, let's do nothing with the bean for now and return
- return super.onSubmit(request, response, command, errors);
- }
-
- protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
- throws ServletException {
- // to actually be able to convert Multipart instance to byte[]
- // we have to register a custom editor
- binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
- // now Spring knows how to handle multipart objects and convert them
- }
-}
-
-public class FileUploadBean {
-
- private byte[] file;
-
- public void setFile(byte[] file) {
- this.file = file;
- }
-
- public byte[] getFile() {
- return file;
- }
-}
-
- As you can see, the FileUploadBean has a
- property typed byte[] that holds the file. The
- controller registers a custom editor to let Spring know how to convert
- the multipart objects the resolver has found to properties specified by
- the bean. In this example, nothing is done with the
- byte[] property of the bean itself, but in practice
- you can do save it in a database, mail it to somebody, and so on.
-
- The following is an equivalent example in which a file is bound
- straight to a String-typed property on a (form backing) object:
-
- public class FileUploadController extends SimpleFormController {
-
- protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
- Object command, BindException errors) throws ServletException, IOException {
-
- // cast the bean
- FileUploadBean bean = (FileUploadBean) command;
-
- // let's see if there's content there
- String file = bean.getFile();
- if (file == null) {
- // hmm, that's strange, the user did not upload anything
- }
-
- // well, let's do nothing with the bean for now and return
- return super.onSubmit(request, response, command, errors);
- }
-
- protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder)
- throws ServletException {
- // to actually be able to convert Multipart instance to a String
- // we have to register a custom editor
- binder.registerCustomEditor(String.class, new StringMultipartFileEditor());
- // now Spring knows how to handle multipart object and convert them
- }
-
-}
-
-public class FileUploadBean {
-
- private String file;
-
- public void setFile(String file) {
- this.file = file;
- }
-
- public String getFile() {
- return file;
- }
-}
-
- The preceding example only makes (logical) sense in the context of
- uploading a plain text file. It would not work as well with an image
- file upload.
-
- The third (and final) option is where one binds directly to a
- MultipartFile property declared on the
- (form backing) object's class. In this case one does not need to
- register any custom PropertyEditor
- because there is no type conversion to be performed.
-
- public class FileUploadController extends SimpleFormController {
-
- protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
- Object command, BindException errors) throws ServletException, IOException {
-
- // cast the bean
- FileUploadBean bean = (FileUploadBean) command;
-
- let's see if there's content there
- MultipartFile file = bean.getFile();
- if (file == null) {
- // hmm, that's strange, the user did not upload anything
- }
-
- // well, let's do nothing with the bean for now and return
- return super.onSubmit(request, response, command, errors);
- }
-}
-
-public class FileUploadBean {
-
- private MultipartFile file;
-
- public void setFile(MultipartFile file) {
- this.file = file;
- }
-
- public MultipartFile getFile() {
- return file;
- }
-}
@@ -2806,27 +2675,27 @@ public class FileUploadBean {
Spring HandlerExceptionResolvers ease the pain
of unexpected exceptions that occur while your request is handled by a
controller that matched the request.
- HandlerExceptionResolvers somewhat resemble the
- exception mappings you can define in the web application descriptor
- web.xml. However, they provide a more flexible way to
+ HandlerExceptionResolvers somewhat resemble the
+ exception mappings you can define in the web application descriptor
+ web.xml. However, they provide a more flexible way to
handle exceptions. They provide information about which handler was
- executing when the exception was thrown. Furthermore, a programmatic way
+ executing when the exception was thrown. Furthermore, a programmatic way
of handling exception gives you more options for responding
appropriately before the request is forwarded to another URL (the same
end result as when you use the servlet specific exception
mappings).
- Besides implementing the
- HandlerExceptionResolver interface, which
+ Besides implementing the
+ HandlerExceptionResolver interface, which
is only a matter of implementing the
resolveException(Exception, Handler) method and
returning a ModelAndView, you may also use the
- SimpleMappingExceptionResolver. This resolver
- enables you to take the class name of any exception that might be thrown
- and map it to a view name. This is functionally equivalent to the
+ SimpleMappingExceptionResolver. This resolver
+ enables you to take the class name of any exception that might be thrown
+ and map it to a view name. This is functionally equivalent to the
exception mapping feature from the Servlet API, but it is also possible
to implement more finely grained mappings of exceptions from different
- handlers.
+ handlers.