Moved REST Etag filter to MVC chapter

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1390 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Arjen Poutsma 2009-06-16 14:37:57 +00:00
parent 90379c5172
commit dbca532155
1 changed files with 187 additions and 144 deletions

View File

@ -1550,15 +1550,15 @@ public class MyFormController {
<section id="mvc-handlermapping">
<title>Handler mappings</title>
<para>In previous versions of Spring MVC, users were required to define <interfacename>HandlerMapping</interfacename>s in
the web application context
to map incoming web requests to
appropriate handlers. With the introduction of Spring 2.5, the <classname>DispatcherServlet</classname> enables the
<classname>DefaultAnnotationHandlerMapping</classname>, which looks for
<interfacename>@RequestMapping</interfacename> annotations on <interfacename>@Controllers</interfacename>.
Typically, you do not need to override this default mapping, except when overriding the properties.
These properties are:
</para>
<para>In previous versions of Spring MVC, users were required to define
<interfacename>HandlerMapping</interfacename>s in the web application
context to map incoming web requests to appropriate handlers. With the
introduction of Spring 2.5, the <classname>DispatcherServlet</classname>
enables the <classname>DefaultAnnotationHandlerMapping</classname>, which
looks for <interfacename>@RequestMapping</interfacename> annotations on
<interfacename>@Controllers</interfacename>. Typically, you do not need to
override this default mapping, except when overriding the properties.
These properties are:</para>
<itemizedlist spacing="compact">
<listitem>
@ -1615,16 +1615,17 @@ public class MyFormController {
subclasses of
<classname>org.springframework.web.servlet.handler.AbstractUrlHandlerMapping</classname></emphasis>).</para>
<para>The following example shows how to override the default mapping, and add an interceptor:</para>
<para>The following example shows how to override the default mapping, and
add an interceptor:</para>
<programlisting language="xml"><![CDATA[<beans>
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<bean class="example.MyInterceptor"/>
</property>
</bean>
<programlisting language="xml">&lt;beans&gt;
&lt;bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"&gt;
&lt;property name="interceptors"&gt;
&lt;bean class="example.MyInterceptor"/&gt;
&lt;/property&gt;
&lt;/bean&gt;
<beans>]]></programlisting>
&lt;beans&gt;</programlisting>
<section id="mvc-handlermapping-interceptor">
<title>Intercepting requests - the
@ -1841,10 +1842,11 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
<row>
<entry><classname>ContentNegotiatingViewResolver</classname></entry>
<entry>An implementation of the <interfacename>ViewResolver</interfacename>
interface that that resolves a view based on the request file name or <literal>Accept</literal> header.
See <xref linkend="mvc-multiple-representations"/>.
</entry>
<entry>An implementation of the
<interfacename>ViewResolver</interfacename> interface that that
resolves a view based on the request file name or
<literal>Accept</literal> header. See <xref
linkend="mvc-multiple-representations" />.</entry>
</row>
</tbody>
</tgroup>
@ -2071,11 +2073,10 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
<section id="mvc-multiple-representations">
<title><classname>ContentNegotiatingViewResolver</classname></title>
<para>The <classname>ContentNegotiatingViewResolver</classname>
does not resolve views itself, but rather delegates to other
view resolvers, selecting the view that resembles the representation
requested by the client.
There are two strategies for a client to inform the server of
<para>The <classname>ContentNegotiatingViewResolver</classname> does not
resolve views itself, but rather delegates to other view resolvers,
selecting the view that resembles the representation requested by the
client. There are two strategies for a client to inform the server of
the representation it is interested in receiving.</para>
<para>The first strategy is to use a distinct URI for each resource.
@ -2142,26 +2143,26 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
<para>Here is an example configuration of a
<classname>ContentNegotiatingViewResolver</classname></para>
<programlisting language="xml"><![CDATA[<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="atom" value="application/atom+xml"/>
<entry key="html" value="text/html"/>
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</list>
</property>
</bean>
<programlisting language="xml">&lt;bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"&gt;
&lt;property name="mediaTypes"&gt;
&lt;map&gt;
&lt;entry key="atom" value="application/atom+xml"/&gt;
&lt;entry key="html" value="text/html"/&gt;
&lt;/map&gt;
&lt;/property&gt;
&lt;property name="viewResolvers"&gt;
&lt;list&gt;
&lt;bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/&gt;
&lt;bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;
&lt;property name="prefix" value="/WEB-INF/jsp/"/&gt;
&lt;property name="suffix" value=".jsp"/&gt;
&lt;/bean&gt;
&lt;/list&gt;
&lt;/property&gt;
&lt;/bean&gt;
<bean id="content" class="com.springsource.samples.rest.SampleContentAtomView"/>]]></programlisting>
&lt;bean id="content" class="com.springsource.samples.rest.SampleContentAtomView"/&gt;</programlisting>
<para>The <classname>InternalResourceViewResolver</classname> handles
the translation of view names and JSP pages while the
@ -2214,9 +2215,7 @@ public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
}
}</programlisting>
</section>
</section>
<section id="mvc-localeresolver">
@ -2813,9 +2812,11 @@ public class FileUploadBean {
<section id="mvc-ann-exceptionhandler">
<title><interfacename>@ExceptionResolver</interfacename></title>
<para>As an alternative to implementing the <interfacename>HandlerExceptionResolver</interfacename>, you
can use the <interfacename>@ExceptionHandler</interfacename>. The <classname>@ExceptionHandler</classname> method annotation is
used within a controller to specify which method will be invoked when an
<para>As an alternative to implementing the
<interfacename>HandlerExceptionResolver</interfacename>, you can use the
<interfacename>@ExceptionHandler</interfacename>. The
<classname>@ExceptionHandler</classname> method annotation is used
within a controller to specify which method will be invoked when an
exception of a specific type is thrown during the execution of
controller methods. For example</para>
@ -2851,7 +2852,6 @@ public class SimpleController {
<classname>ModelAndView</classname> object. Please refer to the API
documentation for more details.</para>
</section>
</section>
<section id="mvc-coc">
@ -3189,6 +3189,49 @@ public class SimpleController {
</section>
</section>
<section id="mvc-etag">
<title>ETag support</title>
<para>An <ulink url="http://en.wikipedia.org/wiki/HTTP_ETag">ETag</ulink>
(entity tag) is an HTTP response header returned by an HTTP/1.1 compliant
web server used to determine change in content at a given URL. It can be
considered to be the more sophisticated successor to the
<literal>Last-Modified</literal> header. When a server returns a
representation with an ETag header, the client can use this header in
subsequent GETs, in an <literal>If-None-Match</literal> header. If the
content has not changed, the server will return <literal>304: Not
Modified</literal>.</para>
<para>Support for ETags is provided by the servlet filter
<classname>ShallowEtagHeaderFilter</classname>. Since it is a plain
Servlet Filter, and thus can be used in combination with any web
framework. The <classname>ShallowEtagHeaderFilter</classname> filter
creates so-called shallow ETags (as opposed to deep ETags, more about that
later). The way it works is quite simple: the filter simply caches the
content of the rendered JSP (or other content), generates an MD5 hash over
that, and returns that as an ETag header in the response. The next time a
client sends a request for the same resource, it uses that hash as the
<literal>If-None-Match</literal> value. The filter notices this, renders
the view again, and compares the two hashes. If they are equal, a
<literal>304</literal> is returned. It is important to note that this
filter will not save processing power, as the view is still rendered. The
only thing it saves is bandwidth, as the rendered response is not sent
back over the wire.</para>
<para>You configure the <classname>ShallowEtagHeaderFilter</classname> in
<filename>web.xml</filename>:</para>
<programlisting language="xml">&lt;filter&gt;
&lt;filter-name&gt;etagFilter&lt;/filter-name&gt;
&lt;filter-class&gt;org.springframework.web.filter.ShallowEtagHeaderFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;etagFilter&lt;/filter-name&gt;
&lt;servlet-name&gt;petclinic&lt;/servlet-name&gt;
&lt;/filter-mapping&gt;</programlisting>
</section>
<section id="mvc-resources">
<title>Further Resources</title>