Finish REST docs, add docs for @FactoryMethod, add links in 'new-in-3'
This commit is contained in:
parent
0c5ab54dce
commit
aa36118e1c
|
|
@ -6411,6 +6411,57 @@ public class CachingMovieCatalog implements MovieCatalog {
|
||||||
per-class.</para>
|
per-class.</para>
|
||||||
</note>
|
</note>
|
||||||
</section>
|
</section>
|
||||||
|
<section id="beans-factorybeans-annotations">
|
||||||
|
<title>Defining FactoryBeans with annotations</title>
|
||||||
|
|
||||||
|
<para>FactoryBeans can be defined in code using the
|
||||||
|
<classname>@FactoryMethod </classname>method level annotation. Factory bean
|
||||||
|
definiton supports using standard as well as custom qualifiers using
|
||||||
|
annotations. The scope of the object produces and if it should be a scoped
|
||||||
|
AOP proxy are determined by the presence of <classname>@Scope</classname>
|
||||||
|
and <classname>@ScopedProxy</classname> annotations. The default scope for
|
||||||
|
methods with <classname>@FactoryMethod</classname> can also be inherited
|
||||||
|
from the class level. The following example shows a variety of usages of the
|
||||||
|
<classname>@FactoryMethod</classname> annotation.</para>
|
||||||
|
|
||||||
|
<programlisting language="java">@Component
|
||||||
|
public class FactoryMethodComponent {
|
||||||
|
|
||||||
|
private static TestBean staticTestBean = new TestBean("staticInstance",1);
|
||||||
|
|
||||||
|
@Autowired @Qualifier("public")
|
||||||
|
public TestBean autowiredTestBean;
|
||||||
|
|
||||||
|
private static int i;
|
||||||
|
|
||||||
|
@FactoryMethod @Qualifier("static")
|
||||||
|
public static TestBean staticInstance()
|
||||||
|
{
|
||||||
|
return staticTestBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FactoryMethod @Qualifier("public")
|
||||||
|
public TestBean getPublicInstance() {
|
||||||
|
return new TestBean("publicInstance");
|
||||||
|
}
|
||||||
|
|
||||||
|
@FactoryMethod @BeanAge(1)
|
||||||
|
protected TestBean getProtectedInstance() {
|
||||||
|
return new TestBean("protectedInstance", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FactoryMethod @Scope("prototype")
|
||||||
|
private TestBean getPrivateInstance() {
|
||||||
|
return new TestBean("privateInstance", i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FactoryMethod @Scope("request") @ScopedProxy
|
||||||
|
private TestBean getPrivateInstance() {
|
||||||
|
return new TestBean("privateInstance", i++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</programlisting>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="context-load-time-weaver">
|
<section id="context-load-time-weaver">
|
||||||
|
|
|
||||||
|
|
@ -171,7 +171,7 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>IoC enhancements/Spring JavaConfig</para>
|
<para>IoC enhancements/Java based bean metadata</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
|
|
@ -191,65 +191,72 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<section id="new-feature-java5">
|
<section id="new-feature-java5">
|
||||||
<title>Core APIs updated for Java 5</title>
|
<title>Core APIs updated for Java 5</title>
|
||||||
|
|
||||||
<para>BeanFactoryinterface returns typed bean
|
<para>BeanFactoryinterface returns typed bean instancesas far as
|
||||||
instancesas far as possible
|
possible <itemizedlist>
|
||||||
<itemizedlist>
|
<listitem>
|
||||||
<listitem><para>T getBean(Stringname, Class<T> requiredType)</para></listitem>
|
<para>T getBean(Stringname, Class<T> requiredType)</para>
|
||||||
<listitem><para>Map<String, T> getBeansOfType(Class<T> type)</para></listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>Spring's TaskExecutorinterface extends
|
|
||||||
<classname>java.util.concurrent.Executor</classname> now
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>extended AsyncTaskExecutor supports standard Callables with Futures</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>New Java 5 based converter API and SPI
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>stateless ConversionService and Converters</para></listitem>
|
|
||||||
<listitem><para>superseding standard JDK PropertyEditors</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>Typed ApplicationListener<E>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="new-feature-el">
|
<listitem>
|
||||||
<title>Spring Expression Language</title>
|
<para>Map<String, T> getBeansOfType(Class<T>
|
||||||
|
type)</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist></para>
|
||||||
|
|
||||||
<para>Spring introduces an expression language which is similar to Unified
|
<para>Spring's TaskExecutorinterface extends
|
||||||
EL in its syntax but offers significantly more features. The expression
|
<classname>java.util.concurrent.Executor</classname> now <itemizedlist>
|
||||||
language can be used when defining XML and Annotation based bean
|
<listitem>
|
||||||
definitions and also serves as the foundation for expression language
|
<para>extended AsyncTaskExecutor supports standard Callables with
|
||||||
support across the Spring portfolio. Details of this new functionality can
|
Futures</para>
|
||||||
be found in the chapter <link linkend="expressions">Spring Expression
|
</listitem>
|
||||||
Language (SpEL).</link></para>
|
</itemizedlist></para>
|
||||||
|
|
||||||
<para>The Spring Expression Language was created to provide the Spring community with a single well
|
<para>New Java 5 based converter API and SPI <itemizedlist>
|
||||||
supported expression language that can used across all the products in the Spring portfolio. Its language
|
<listitem>
|
||||||
features are driven by the requirements of the projects in the Spring portfolio, including tooling
|
<para>stateless ConversionService and Converters</para>
|
||||||
requirements for code completion support within the eclipse based SpringSource Tool Suite.</para>
|
</listitem>
|
||||||
|
|
||||||
<para>The following is an example of how the Expression Language can be used to configure some properties
|
<listitem>
|
||||||
of a database setup
|
<para>superseding standard JDK PropertyEditors</para>
|
||||||
<programlisting language="xml"><![CDATA[<bean class="mycompany.RewardsTestDatabase">
|
</listitem>
|
||||||
<property name="databaseName"
|
</itemizedlist></para>
|
||||||
value="#{systemProperties.databaseName}"/>
|
|
||||||
<property name="keyGenerator"
|
<para>Typed ApplicationListener<E></para>
|
||||||
value="#{strategyBean.databaseKeyGenerator}"/>
|
</section>
|
||||||
</bean>
|
|
||||||
]]></programlisting>
|
<section id="new-feature-el">
|
||||||
</para>
|
<title>Spring Expression Language</title>
|
||||||
<para>This functionality is also available if you prefer to configure your components using
|
|
||||||
annotations:
|
<para>Spring introduces an expression language which is similar to
|
||||||
<programlisting language="java"><![CDATA[@Repository
|
Unified EL in its syntax but offers significantly more features. The
|
||||||
|
expression language can be used when defining XML and Annotation based
|
||||||
|
bean definitions and also serves as the foundation for expression
|
||||||
|
language support across the Spring portfolio. Details of this new
|
||||||
|
functionality can be found in the chapter <link
|
||||||
|
linkend="expressions">Spring Expression Language (SpEL).</link></para>
|
||||||
|
|
||||||
|
<para>The Spring Expression Language was created to provide the Spring
|
||||||
|
community with a single well supported expression language that can used
|
||||||
|
across all the products in the Spring portfolio. Its language features
|
||||||
|
are driven by the requirements of the projects in the Spring portfolio,
|
||||||
|
including tooling requirements for code completion support within the
|
||||||
|
eclipse based SpringSource Tool Suite.</para>
|
||||||
|
|
||||||
|
<para>The following is an example of how the Expression Language can be
|
||||||
|
used to configure some properties of a database setup <programlisting
|
||||||
|
language="xml"><bean class="mycompany.RewardsTestDatabase">
|
||||||
|
<property name="databaseName"
|
||||||
|
value="#{systemProperties.databaseName}"/>
|
||||||
|
<property name="keyGenerator"
|
||||||
|
value="#{strategyBean.databaseKeyGenerator}"/>
|
||||||
|
</bean>
|
||||||
|
</programlisting></para>
|
||||||
|
|
||||||
|
<para>This functionality is also available if you prefer to configure
|
||||||
|
your components using annotations: <programlisting language="java">@Repository
|
||||||
public class RewardsTestDatabase {
|
public class RewardsTestDatabase {
|
||||||
|
|
||||||
@Value("#{systemProperties.databaseName}")
|
@Value("#{systemProperties.databaseName}")
|
||||||
|
|
@ -258,29 +265,47 @@ public class RewardsTestDatabase {
|
||||||
@Value("#{strategyBean.databaseKeyGenerator}")
|
@Value("#{strategyBean.databaseKeyGenerator}")
|
||||||
public voidsetKeyGenerator(KeyGenerator kg) { … }
|
public voidsetKeyGenerator(KeyGenerator kg) { … }
|
||||||
}
|
}
|
||||||
]]></programlisting>
|
</programlisting></para>
|
||||||
</para>
|
</section>
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="new-feature-java-config">
|
<section id="new-feature-java-config">
|
||||||
<title>The Inversion of Control (IoC) container</title>
|
<title>The Inversion of Control (IoC) container</title>
|
||||||
|
|
||||||
<para>Some core JavaConfig features have been added to the Spring Framework now. This means that the following
|
<section id="new-java-configuration">
|
||||||
annotations are now directly supported:
|
<title>Java based bean metadata</title>
|
||||||
|
|
||||||
<itemizedlist>
|
|
||||||
<listitem><para>@Configuration</para></listitem>
|
|
||||||
<listitem><para>@Bean</para></listitem>
|
|
||||||
<listitem><para>@Primary</para></listitem>
|
|
||||||
<listitem><para>@Lazy</para></listitem>
|
|
||||||
<listitem><para>@Import</para></listitem>
|
|
||||||
<listitem><para>@Value</para></listitem>
|
|
||||||
</itemizedlist>
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<para>
|
<para>Some core features from the <ulink
|
||||||
Here is an example of a Java class providing basic configuration using the new JavaConfig features:
|
url="http://www.springsource.org/javaconfig"><link
|
||||||
<programlisting language="java"><![CDATA[@Configuration
|
linkend="???">JavaConfig</link></ulink> project have been added to the
|
||||||
|
Spring Framework now. This means that the following annotations are
|
||||||
|
now directly supported: <itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>@Configuration</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>@Bean</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>@Primary</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>@Lazy</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>@Import</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>@Value</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist></para>
|
||||||
|
|
||||||
|
<para>Here is an example of a Java class providing basic configuration
|
||||||
|
using the new JavaConfig features: <programlisting language="java">@Configuration
|
||||||
public class AppConfig{
|
public class AppConfig{
|
||||||
@Value("#{jdbcProperties.url}") String jdbcUrl;
|
@Value("#{jdbcProperties.url}") String jdbcUrl;
|
||||||
@Value("#{jdbcProperties.username}") String username;
|
@Value("#{jdbcProperties.username}") String username;
|
||||||
|
|
@ -310,47 +335,83 @@ public class AppConfig{
|
||||||
username, password);
|
username, password);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]]></programlisting>
|
</programlisting> To get this to work you need to add the following component
|
||||||
|
scanning entry in your minimal application context XML file.
|
||||||
|
<programlisting language="java"><context:component-scan
|
||||||
|
base-package="com.myco.config"/></programlisting></para>
|
||||||
|
</section>
|
||||||
|
|
||||||
To get this to work you need to add the following component scanning entry in your minimal
|
<section>
|
||||||
application context XML file.
|
<title>Factory Bean definitions using annotations</title>
|
||||||
|
|
||||||
<programlisting language="java"><![CDATA[<context:component-scan
|
|
||||||
base-package="com.myco.config"/>]]></programlisting>
|
|
||||||
|
|
||||||
</para>
|
|
||||||
|
|
||||||
</section>
|
<para>FactoryBeans can be defined within a Spring component definition
|
||||||
|
and registered using standard component-scanning techniques. See <link
|
||||||
<section id="new-feature-rest">
|
linkend="beans-factorybeans-annotations">Factory Bean Definitions
|
||||||
<title>The Web Tier</title>
|
using annotations</link> for more information</para>
|
||||||
|
</section>
|
||||||
<para>Work in progress ...</para>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<title>Comprehensive REST support</title>
|
|
||||||
|
|
||||||
<para>Work in progress ...</para>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section id="new-feature-rest">
|
||||||
<title>@MVC additions</title>
|
<title>The Web Tier</title>
|
||||||
|
|
||||||
<para>Work in progress ...</para>
|
<para>Work in progress ...</para>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Comprehensive REST support</title>
|
||||||
|
|
||||||
|
<para>Server-side support for building RESTful applications has been
|
||||||
|
provided as an extension of the existing annotation driven MVC web
|
||||||
|
framework. Client-side support is provided by the
|
||||||
|
<classname>RestTemplate</classname> class in the spirit of other
|
||||||
|
template classes such as <classname>JdbcTemplate</classname> and
|
||||||
|
<classname>JmsTemplate</classname>. Both server and client side REST
|
||||||
|
functionality make use of
|
||||||
|
<interfacename>HttpConverter</interfacename>s to facilitate the
|
||||||
|
conversion between objects and their representation in HTTP request
|
||||||
|
and replies. </para>
|
||||||
|
|
||||||
|
<para>The <classname>MarhsallingHttpMessageConverter</classname> uses
|
||||||
|
the Object to XML mapping functionality in the
|
||||||
|
<literal>org.springframework.oxm</literal> package. This functionality
|
||||||
|
had previously been part of Spring Web Services. More information on
|
||||||
|
the use of the <literal>org.springframework.oxm</literal> can be found
|
||||||
|
in that projects <ulink
|
||||||
|
url="http://static.springframework.org/spring-ws/sites/1.5/reference/html/oxm.html">reference
|
||||||
|
documentation.</ulink></para>
|
||||||
|
|
||||||
|
<para>Refer to the section on <link linkend="rest">REST support</link>
|
||||||
|
for more information.</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>@MVC additions</title>
|
||||||
|
|
||||||
|
<para>Additional annotations such as
|
||||||
|
<classname>@CookieValue</classname> and
|
||||||
|
<classname>@RequestHeaders</classname> have been added. See <link
|
||||||
|
linkend="mvc-ann-cookievalue">Mapping cookie values with the
|
||||||
|
@CookieValue annotation</link> and <link
|
||||||
|
linkend="mvc-ann-requestheader">Mapping request header attributes with
|
||||||
|
the @RequestHeader annotation</link> for more information.</para>
|
||||||
|
|
||||||
|
<para>Work in progress ...</para>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="new-feature-validation">
|
||||||
|
<title>Declarative model validation</title>
|
||||||
|
|
||||||
|
<para>Hibernate Validator, JSR 303</para>
|
||||||
|
|
||||||
|
<para>Work in progress...</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="new-feature-jee-6">
|
||||||
|
<title>Early support for Java EE 6</title>
|
||||||
|
|
||||||
|
<para>JSF 2.0, JPA 2.0, etc</para>
|
||||||
|
|
||||||
|
<para>Work in progress...</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="new-feature-validation">
|
|
||||||
<title>Declarative model validation</title>
|
|
||||||
|
|
||||||
<para>Hibernate Validator, JSR 303</para>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="new-feature-jee-6">
|
|
||||||
<title>Early support for Java EE 6</title>
|
|
||||||
|
|
||||||
<para>JSF 2.0, JPA 2.0, etc</para>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</chapter>
|
</chapter>
|
||||||
|
|
@ -6,29 +6,34 @@
|
||||||
<title>Introduction</title>
|
<title>Introduction</title>
|
||||||
|
|
||||||
<para>The goal of Spring's REST support is to make the development of
|
<para>The goal of Spring's REST support is to make the development of
|
||||||
'RESTful' Web services and applications easier. Client-side access to
|
RESTful Web services and applications easier. </para>
|
||||||
RESTful resources is greatly simplified using Spring
|
|
||||||
<classname>RestTemplate</classname>. <classname>RestTemplate</classname>
|
<para>Client-side access to RESTful resources is greatly simplified using
|
||||||
follows in the footsteps of other 'Template' classes in Spring such as
|
Spring <classname>RestTemplate</classname>.
|
||||||
<classname>JdbcTemplate</classname> and
|
<classname>RestTemplate</classname> follows in the footsteps of other
|
||||||
|
template classes in Spring such as <classname>JdbcTemplate</classname> and
|
||||||
<classname>JmsTemplate</classname>. Instead of dealing with a verbose
|
<classname>JmsTemplate</classname>. Instead of dealing with a verbose
|
||||||
lower level API such as Apache Commons HttpClient to create RESTful
|
lower level API such as Apache Commons <classname>HttpClient</classname>
|
||||||
request, RestTemplate provides one liner methods that are purpose built
|
to create RESTful request, RestTemplate provides one liner methods that
|
||||||
for RESTful programming. On the server-side, Spring's REST support is
|
are purpose built for RESTful programming. </para>
|
||||||
based upon Spring's existing annotation based MVC framework. (For those
|
|
||||||
interested in the rational for that decision, and say not implenting
|
<para>On the server-side, Spring's REST support is based upon Spring's
|
||||||
JAX-RS, read Arjen Putsma's SpringSource TeamBlog <ulink
|
existing annotation based MVC framework. (For those interested in the
|
||||||
|
rational for that decision, and for not implementing JAX-RS, read Arjen
|
||||||
|
Poutsma's SpringSource TeamBlog <ulink
|
||||||
url="http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/">entry</ulink>.)
|
url="http://blog.springsource.com/2009/03/08/rest-in-spring-3-mvc/">entry</ulink>.)
|
||||||
With little effort, you can marshall data out of a RESTful request using
|
With little effort, you can marshall data out of a RESTful request using
|
||||||
@RequestMapping and @PathVariable annotations and return different views
|
<classname>@RequestMapping</classname> and
|
||||||
as determined by the request's Context-Type header.</para>
|
<classname>@PathVariable</classname> annotations and return different
|
||||||
|
views as determined by the request's <literal>Context-Type</literal>
|
||||||
|
header.</para>
|
||||||
|
|
||||||
<para>In this chapter we describe all the features of Spring's REST
|
<para>In this chapter we describe all the features of Spring's REST
|
||||||
support. It is divided into two main two chapters, one for the server-side
|
support. It is divided into two main two chapters, one for the server-side
|
||||||
and one for the client-side. For those new to Spring's <link
|
and one for the client-side. For those new to Spring's <link
|
||||||
linkend="mvc">MVC framework</link>, you may want to read through the
|
linkend="mvc">MVC framework</link>, you may want to read through the
|
||||||
reference documentation on <link linkend="mvc-annotation">annotation-based
|
reference documentation on <link linkend="mvc-annotation">annotation-based
|
||||||
controller configuration</link> to undestand the general programming
|
controller configuration</link> to understand the general programming
|
||||||
model.</para>
|
model.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -41,13 +46,13 @@
|
||||||
linkend="mvc-servlet">DispatcherServlet</link>.</para>
|
linkend="mvc-servlet">DispatcherServlet</link>.</para>
|
||||||
|
|
||||||
<section id="rest-uritemplate">
|
<section id="rest-uritemplate">
|
||||||
<title>URI templates</title>
|
<title>URI Templates</title>
|
||||||
|
|
||||||
<para>RESTful services use URIs to name resourses. To faciliate
|
<para>RESTful services use URIs to name resources. To facilitate
|
||||||
accessing the information contained in a URI, its structure follows
|
accessing the information contained in a URI, its structure follows
|
||||||
conventions so that it can easily be described in a parameterized form.
|
conventions so that it can easily be described in a parameterized form.
|
||||||
The <ulink url="http://bitworking.org/projects/URI-Templates/">proposed
|
The <ulink url="http://bitworking.org/projects/URI-Templates/">proposed
|
||||||
RFC</ulink> for URI Templates defines how a URI is parameterized. For
|
RFC</ulink> for URI Templates defines how an URI is parameterized. For
|
||||||
example, the URI Template</para>
|
example, the URI Template</para>
|
||||||
|
|
||||||
<programlisting>http://www.example.com/users/{userid}</programlisting>
|
<programlisting>http://www.example.com/users/{userid}</programlisting>
|
||||||
|
|
@ -57,11 +62,11 @@
|
||||||
|
|
||||||
<programlisting>http://www.example.com/users/fred</programlisting>
|
<programlisting>http://www.example.com/users/fred</programlisting>
|
||||||
|
|
||||||
<para>When processing an request the URI can be compared to an expected
|
<para>When processing a request the URI can be compared to an expected
|
||||||
URI Template in order to extract a collection of variables.</para>
|
URI Template in order to extract a collection of variables.</para>
|
||||||
|
|
||||||
<para>Spring uses the <classname>@RequestMapping</classname> annotation
|
<para>Spring uses the <classname>@RequestMapping</classname> method
|
||||||
to define the URI Template for the request.
|
annotation to define the URI Template for the request.
|
||||||
The<classname>@PathVariable</classname> annotation is used to extract
|
The<classname>@PathVariable</classname> annotation is used to extract
|
||||||
the value of the template variables and assign their value to a method
|
the value of the template variables and assign their value to a method
|
||||||
variable. A Spring controller method to process above example is shown
|
variable. A Spring controller method to process above example is shown
|
||||||
|
|
@ -78,9 +83,9 @@ public String getUser(@PathVariable String userId) {
|
||||||
<section id="rest-path-variable">
|
<section id="rest-path-variable">
|
||||||
<title>Mapping RESTful URLs with the @PathVariable annotation</title>
|
<title>Mapping RESTful URLs with the @PathVariable annotation</title>
|
||||||
|
|
||||||
<para>The <classname>@PathVariable</classname> method level annotation
|
<para>The <classname>@PathVariable</classname> method parameter
|
||||||
is used to indicate that a method parameter should be bound to the
|
annotation is used to indicate that a method parameter should be bound
|
||||||
value of a URI template variable.</para>
|
to the value of a URI template variable.</para>
|
||||||
|
|
||||||
<para>The following code snippet shows the use of a single
|
<para>The following code snippet shows the use of a single
|
||||||
<classname>@PathVariable</classname> in a controller method:</para>
|
<classname>@PathVariable</classname> in a controller method:</para>
|
||||||
|
|
@ -95,9 +100,9 @@ public String findOwner(<emphasis role="bold">@PathVariable</emphasis> String ow
|
||||||
|
|
||||||
<para>The URI Template "<literal>/owners/{ownerId}</literal>"
|
<para>The URI Template "<literal>/owners/{ownerId}</literal>"
|
||||||
specifies the variable name ownerId. When the controller handles this
|
specifies the variable name ownerId. When the controller handles this
|
||||||
request, the value of ownerId is set the the value in the request URI.
|
request, the value of ownerId is set the value in the request URI. For
|
||||||
For example, when a request comes in for /owners/fred, the value
|
example, when a request comes in for /owners/fred, the value 'fred' is
|
||||||
'fred' is bound to the method parameter <literal>String
|
bound to the method parameter <literal>String
|
||||||
ownerId</literal>.</para>
|
ownerId</literal>.</para>
|
||||||
|
|
||||||
<para>The matching of method parameter names to URI Template variable
|
<para>The matching of method parameter names to URI Template variable
|
||||||
|
|
@ -113,8 +118,8 @@ public String findOwner(<emphasis role="bold">@PathVariable</emphasis>("ownerId"
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>The name of the method parameter does not matter in this case,
|
<para>The name of the method parameter does not matter in this case,
|
||||||
so you may also use create a controlled method with the signature
|
so you may also use a controller method with the signature shown
|
||||||
shown below</para>
|
below</para>
|
||||||
|
|
||||||
<programlisting language="java">@RequestMapping("/owners/{ownerId}", method=RequestMethod.GET)
|
<programlisting language="java">@RequestMapping("/owners/{ownerId}", method=RequestMethod.GET)
|
||||||
public String findOwner(<emphasis role="bold">@PathVariable</emphasis>("ownerId") String theOwner, Model model) {
|
public String findOwner(<emphasis role="bold">@PathVariable</emphasis>("ownerId") String theOwner, Model model) {
|
||||||
|
|
@ -157,6 +162,93 @@ public class RelativePathUriTemplateController {
|
||||||
not correct.</para>
|
not correct.</para>
|
||||||
</tip>
|
</tip>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Mapping the request body with the @RequestBody
|
||||||
|
annotation</title>
|
||||||
|
|
||||||
|
<para>The <classname>@RequestBody</classname> method parameter
|
||||||
|
annotation is used to indicate that a method parameter should be bound
|
||||||
|
to the value of the HTTP request body. For example, </para>
|
||||||
|
|
||||||
|
<programlisting language="java">@RequestMapping(value = "/something", method = RequestMethod.PUT)
|
||||||
|
public void handle(@RequestBody String body, Writer writer) throws IOException {
|
||||||
|
writer.write(body);
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para>The conversion of the request body to the method argument is
|
||||||
|
done using a <interfacename>HttpMessageConverter</interfacename>.
|
||||||
|
<interfacename>HttpMessageConverter</interfacename> is responsible for
|
||||||
|
converting for converting from the HTTP request message to an object
|
||||||
|
and converting from an object to the HTTP response body.
|
||||||
|
<classname>DispatcherServlet</classname> supports annotation based
|
||||||
|
processing using the
|
||||||
|
<classname>DefaultAnnotationHandlerMapping</classname> and
|
||||||
|
<classname>AnnotationMethodHandlerAdapter</classname>. In Spring 3 the
|
||||||
|
<classname>AnnotationMethodHandlerAdapter</classname> has been
|
||||||
|
extended to support the <classname>@RequestBody</classname> and has
|
||||||
|
several <interfacename>HttpMessageConverters</interfacename>
|
||||||
|
registered by default, these are</para>
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para><classname>ByteArrayHttpMessageConverter</classname> -
|
||||||
|
converts byte arrays</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>StringHttpMessageConverter</classname> - converts
|
||||||
|
strings</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>FormHttpMessageConverter</classname> - converts
|
||||||
|
form data to/from a MultiValueMap<String, String></para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>SourceHttpMessageConverter</classname> - convert
|
||||||
|
to/from a javax.xml.transform.Source;</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para><classname>MarshallingHttpMessageConverter</classname> -
|
||||||
|
convert to/from an object using the
|
||||||
|
<classname>org.springframework.oxm</classname> package.</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
|
||||||
|
<para>More information on these converters can be found in the section
|
||||||
|
<link linkend="rest-message-conversion">Message Converters</link>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>The <classname>MarshallingHttpMessageConverter</classname>
|
||||||
|
requires a <interfacename>Marshaller</interfacename> and
|
||||||
|
<interfacename>Unmarshaller</interfacename> from the
|
||||||
|
<classname>org.springframework.oxm</classname> package to be
|
||||||
|
configured on an instance of
|
||||||
|
<classname>AnnotationMethodHandlerAdapter</classname> in the
|
||||||
|
application context. For example</para>
|
||||||
|
|
||||||
|
<programlisting language="xml"><bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
|
||||||
|
<property name="messageConverters">
|
||||||
|
<util:list id="beanList">
|
||||||
|
<ref bean="stringHttpMessageConverter"/>
|
||||||
|
<ref bean="marshallingHttpMessageConverter"/>
|
||||||
|
</util:list>
|
||||||
|
</property
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/>
|
||||||
|
|
||||||
|
<bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
|
||||||
|
<property name="marshaller" ref="castorMarshaller" />
|
||||||
|
<property name="unmarshaller" ref="castorMarshaller" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/>
|
||||||
|
</programlisting>
|
||||||
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="rest-multiple-representations">
|
<section id="rest-multiple-representations">
|
||||||
|
|
@ -205,7 +297,7 @@ public class RelativePathUriTemplateController {
|
||||||
view based on the file extension or <literal>Accept</literal> header of
|
view based on the file extension or <literal>Accept</literal> header of
|
||||||
the HTTP request. <classname>ContentNegotiatingViewResolver</classname>
|
the HTTP request. <classname>ContentNegotiatingViewResolver</classname>
|
||||||
does not perform the view resolution itself, but instead delegates to a
|
does not perform the view resolution itself, but instead delegates to a
|
||||||
list of view resolvers set using the property
|
list of view resolvers set using the bean property
|
||||||
<literal>ViewResolvers</literal>.</para>
|
<literal>ViewResolvers</literal>.</para>
|
||||||
|
|
||||||
<para>The <classname>ContentNegotiatingViewResolver</classname> selects
|
<para>The <classname>ContentNegotiatingViewResolver</classname> selects
|
||||||
|
|
@ -221,7 +313,7 @@ public class RelativePathUriTemplateController {
|
||||||
Context-Type was 'text/xml' is a compatible match.</para>
|
Context-Type was 'text/xml' is a compatible match.</para>
|
||||||
|
|
||||||
<para>To support the resolution of a view based on a file extension,
|
<para>To support the resolution of a view based on a file extension,
|
||||||
<classname>ContentNegotiatingViewResolver</classname>'s property
|
<classname>ContentNegotiatingViewResolver</classname>'s bean property
|
||||||
<literal>MediaTypes</literal> is used to specify a mapping of file
|
<literal>MediaTypes</literal> is used to specify a mapping of file
|
||||||
extensions to media types. For more information on the algorithm to
|
extensions to media types. For more information on the algorithm to
|
||||||
determine the request media type, refer to the API documentation for
|
determine the request media type, refer to the API documentation for
|
||||||
|
|
@ -309,7 +401,7 @@ public class ContentController {
|
||||||
<section id="rest-views">
|
<section id="rest-views">
|
||||||
<title>Views</title>
|
<title>Views</title>
|
||||||
|
|
||||||
<para>Several views were added to Spring 3 to help support creating
|
<para>Several views were added in Spring 3 to help support creating
|
||||||
RESTful services. They are:</para>
|
RESTful services. They are:</para>
|
||||||
|
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
|
|
@ -325,29 +417,34 @@ public class ContentController {
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para><classname>MarshallingView</classname> - returns an XML
|
<para><classname>MarshallingView</classname> - returns an XML
|
||||||
representation using Spring's Objecct/XML mapping (OXM)
|
representation using Spring's Object to XML mapping (OXM)
|
||||||
functionality</para>
|
functionality</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>Available separately is the <classname>JacksonJsonView</classname>
|
<note>
|
||||||
included as part of the Spring JavaScript project.</para>
|
<para>Available separately is the
|
||||||
|
<classname>JacksonJsonView</classname> included as part of the Spring
|
||||||
|
JavaScript project.</para>
|
||||||
|
</note>
|
||||||
|
|
||||||
<section id="rest-feedview">
|
<section id="rest-feedview">
|
||||||
<title>Feed Views</title>
|
<title>Feed Views</title>
|
||||||
|
|
||||||
<para>Both <classname>AbstractAtomFeedView</classname> and
|
<para>Both <classname>AbstractAtomFeedView</classname> and
|
||||||
<classname>AbstractRssFeedView</classname> inherit from the base class
|
<classname>AbstractRssFeedView</classname> inherit from the base class
|
||||||
<classname>AbstractFeedView<T></classname> and are used to
|
<classname>AbstractFeedView</classname> and are used to provide Atom
|
||||||
provide Atom and RSS Feed views respectfully. They are based on
|
and RSS Feed views respectfully. They are based on java.net's <ulink
|
||||||
java.net's <ulink url="https://rome.dev.java.net">ROME</ulink> project
|
url="https://rome.dev.java.net">ROME</ulink> project and are located
|
||||||
and located in the package org.springframework.web.servlet.view.feed.
|
in the package
|
||||||
The <classname>AbstractAtomFeedView</classname> requires you to
|
<literal>org.springframework.web.servlet.view.feed</literal>. </para>
|
||||||
|
|
||||||
|
<para><classname>AbstractAtomFeedView</classname> requires you to
|
||||||
implement the <methodname>buildFeedEntries</methodname> method and
|
implement the <methodname>buildFeedEntries</methodname> method and
|
||||||
optionally override the <methodname>buildFeedMetadata</methodname>
|
optionally override the <methodname>buildFeedMetadata</methodname>
|
||||||
method (the default implementation is empty), as shown below</para>
|
method (the default implementation is empty), as shown below</para>
|
||||||
|
|
||||||
<programlisting>public class SampleContentAtomView extends AbstractAtomFeedView {
|
<programlisting language="java">public class SampleContentAtomView extends AbstractAtomFeedView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void buildFeedMetadata(Map<String, Object> model, Feed feed, HttpServletRequest request) {
|
protected void buildFeedMetadata(Map<String, Object> model, Feed feed, HttpServletRequest request) {
|
||||||
|
|
@ -365,7 +462,7 @@ public class ContentController {
|
||||||
<para>Similar requirements apply for implementing
|
<para>Similar requirements apply for implementing
|
||||||
<classname>AbstractRssFeedView</classname>, as shown below</para>
|
<classname>AbstractRssFeedView</classname>, as shown below</para>
|
||||||
|
|
||||||
<programlisting>public class SampleContentAtomView extends AbstractRssFeedView {
|
<programlisting language="java">public class SampleContentAtomView extends AbstractRssFeedView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void buildFeedMetadata(Map<String, Object> model, Channel feed, HttpServletRequest request) {
|
protected void buildFeedMetadata(Map<String, Object> model, Channel feed, HttpServletRequest request) {
|
||||||
|
|
@ -387,15 +484,22 @@ public class ContentController {
|
||||||
automatically be written to the response object after the method
|
automatically be written to the response object after the method
|
||||||
returns. </para>
|
returns. </para>
|
||||||
|
|
||||||
<para>For an example implementation of creating a Atom view please
|
<para>For an example of creating a Atom view please refer to Alef
|
||||||
refer to Alef Arendsen's SpringSource TeamBlog <ulink
|
Arendsen's SpringSource TeamBlog <ulink
|
||||||
url="http://blog.springsource.com/2009/03/16/adding-an-atom-view-to-an-application-using-springs-rest-support/">entry</ulink>.</para>
|
url="http://blog.springsource.com/2009/03/16/adding-an-atom-view-to-an-application-using-springs-rest-support/">entry</ulink>.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<title>XML Marshalling View</title>
|
<title>XML Marshalling View</title>
|
||||||
|
|
||||||
<para>The MarhsallingView</para>
|
<para>The <classname>MarhsallingView</classname> uses a XML
|
||||||
|
<interfacename>Marshaller</interfacename> defined in the
|
||||||
|
<classname>org.springframework.oxm</classname> package to render the
|
||||||
|
response content as XML. The object to be marshalled can be set
|
||||||
|
explicitly using <classname>MarhsallingView</classname>'s
|
||||||
|
<property>modelKey</property> bean property. Alternatively, the view
|
||||||
|
will iterate over all model properties marhsall only those types that
|
||||||
|
are supported by the <interfacename>Marshaller</interfacename>.</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -471,7 +575,7 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
|
||||||
renders the view again, and compares the two hashes. If they are equal,
|
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
|
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.
|
filter will not save processing power, as the view is still rendered.
|
||||||
The only thing it saves is bandwith, as the rendered response is not
|
The only thing it saves is bandwidth, as the rendered response is not
|
||||||
sent back over the wire.</para>
|
sent back over the wire.</para>
|
||||||
|
|
||||||
<para>Deep ETags are a bit more complicated. In this case, the ETag is
|
<para>Deep ETags are a bit more complicated. In this case, the ETag is
|
||||||
|
|
@ -486,62 +590,354 @@ public String deletePet(@PathVariable int ownerId, @PathVariable int petId) {
|
||||||
<section id="rest-exception">
|
<section id="rest-exception">
|
||||||
<title>Exception Handling</title>
|
<title>Exception Handling</title>
|
||||||
|
|
||||||
<para>@ExceptionHandler</para>
|
<para>The <classname>@ExceptionHandling</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>
|
||||||
|
|
||||||
|
<programlisting language="java">@Controller
|
||||||
|
public class SimpleController {
|
||||||
|
|
||||||
|
// other controller method omitted
|
||||||
|
|
||||||
|
@ExceptionHandler(IOException.class)
|
||||||
|
public String handleIOException(IOException ex, HttpServletRequest request) {
|
||||||
|
return ClassUtils.getShortName(ex.getClass());
|
||||||
|
}
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para>will invoke the 'handlerIOException' method when a
|
||||||
|
<classname>java.io.IOException</classname> is thrown.</para>
|
||||||
|
|
||||||
|
<para>The <classname>@ExceptionHandler</classname> value can be set to
|
||||||
|
an array of Exception types. If an exception is thrown matches one of
|
||||||
|
the types in the list, then the method annotated with the matching
|
||||||
|
<classname>@ExceptionHandler</classname> will be invoked. If the
|
||||||
|
annotation value is not set then the exception types listed as method
|
||||||
|
arguments are used. </para>
|
||||||
|
|
||||||
|
<para>Much like standard controller methods annotated with a
|
||||||
|
<classname>@RequestMapping</classname> annotation, the method arguments
|
||||||
|
and return values of <classname>@ExceptionHandler</classname> methods
|
||||||
|
are very flexible. For example, the
|
||||||
|
<classname>HttpServletRequest</classname> can be access in Servlet
|
||||||
|
environments and the <classname>PortletRequest</classname> in Portlet
|
||||||
|
environments. The return type can be a <classname>String</classname>,
|
||||||
|
which is interpreted as a view name or a
|
||||||
|
<classname>ModelAndView</classname> object. Please refer to the API
|
||||||
|
documentation for more details. </para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="rest-client-access">
|
<section id="rest-client-access">
|
||||||
<title>Accessing RESTful services on the Client</title>
|
<title>Accessing RESTful services on the Client</title>
|
||||||
|
|
||||||
<para>Spring provides a client-side API blah blah</para>
|
<para>The <classname>RestTemplate</classname> is the core class for
|
||||||
|
client-side access to RESTful services. It is conceptually similar to
|
||||||
|
other template classes in Spring, such as
|
||||||
|
<classname>JdbcTemplate</classname> and <classname>JmsTemplate</classname>
|
||||||
|
and other template classes found in other Spring portfolio projects.
|
||||||
|
<classname>RestTemplate</classname>'s behavior is customized by providing
|
||||||
|
callback methods and configuring the
|
||||||
|
<interfacename>HttpMessageConverter</interfacename> used to marshal
|
||||||
|
objects into the HTTP request body and to unmarshall any response back
|
||||||
|
into an object. As it is common to use XML as a message format, Spring
|
||||||
|
provides a <classname>MarshallingHttpMessageConverter</classname> that
|
||||||
|
uses the Object-to-XML framework that is part of the
|
||||||
|
<classname>org.springframework.oxm</classname> package. This gives you a
|
||||||
|
wide range of choices of XML to Object mapping technologies to choose
|
||||||
|
from. </para>
|
||||||
|
|
||||||
|
<para>This section describes how to use the
|
||||||
|
<classname>RestTemplate</classname> and its associated
|
||||||
|
<interfacename>HttpMessageConverters</interfacename>.</para>
|
||||||
|
|
||||||
<section id="rest-resttemplate">
|
<section id="rest-resttemplate">
|
||||||
<title>RestTemplate</title>
|
<title>RestTemplate</title>
|
||||||
|
|
||||||
<para>blah blah</para>
|
<para>Invoking RESTful services in Java is typically done using a helper
|
||||||
|
class such as Jakarta Commons <classname>HttpClient</classname>. For
|
||||||
|
common REST operations this approach is too low level as shown
|
||||||
|
below.</para>
|
||||||
|
|
||||||
|
<programlisting>String uri = "http://example.com/hotels/1/bookings";
|
||||||
|
|
||||||
|
PostMethod post = new PostMethod(uri);
|
||||||
|
String request = // create booking request content
|
||||||
|
post.setRequestEntity(new StringRequestEntity(request));
|
||||||
|
|
||||||
|
httpClient.executeMethod(post);
|
||||||
|
|
||||||
|
if (HttpStatus.SC_CREATED == post.getStatusCode()) {
|
||||||
|
Header location = post.getRequestHeader("Location");
|
||||||
|
if (location != null) {
|
||||||
|
System.out.println("Created new booking at :" + location.getValue());
|
||||||
|
}
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para> RestTemplate provides higher level methods that correspond to
|
||||||
|
each of the six main HTTP methods that make invoking many RESTful
|
||||||
|
services a one-liner and enforce REST best practices.</para>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<title>Overview of RestTemplate methods</title>
|
||||||
|
|
||||||
|
<tgroup cols="2">
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry><emphasis role="bold">HTTP Method</emphasis></entry>
|
||||||
|
|
||||||
|
<entry><emphasis role="bold">RestTemplate
|
||||||
|
Method</emphasis></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>DELETE</entry>
|
||||||
|
|
||||||
|
<entry><ulink
|
||||||
|
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#delete(String,%20String...)">delete(String
|
||||||
|
url, String… urlVariables)</ulink></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>GET</entry>
|
||||||
|
|
||||||
|
<entry><ulink
|
||||||
|
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject(String,%20Class,%20String...)">getForObject(String
|
||||||
|
url, Class<T> responseType, String…
|
||||||
|
urlVariables)</ulink></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>HEAD</entry>
|
||||||
|
|
||||||
|
<entry><ulink
|
||||||
|
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#headForHeaders(String,%20String...)">headForHeaders(String
|
||||||
|
url, String… urlVariables)</ulink></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>OPTIONS</entry>
|
||||||
|
|
||||||
|
<entry><ulink
|
||||||
|
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#optionsForAllow(String,%20String...)">optionsForAllow(String
|
||||||
|
url, String… urlVariables)</ulink></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>POST</entry>
|
||||||
|
|
||||||
|
<entry><ulink
|
||||||
|
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#postForLocation(String,%20Object,%20String...)">postForLocation(String
|
||||||
|
url, Object request, String… urlVariables)</ulink></entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>PUT</entry>
|
||||||
|
|
||||||
|
<entry><ulink
|
||||||
|
url="http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html#put(String,%20Object,%20String...)">put(String
|
||||||
|
url, Object request, String…urlVariables)</ulink></entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<para>The names of <classname>RestTemplate</classname> methods follow a
|
||||||
|
naming convention, the first part indicates what HTTP method is being
|
||||||
|
invoked and the second part indicates what is returned. For example, the
|
||||||
|
method <methodname>getForObject</methodname> will perform a GET, convert
|
||||||
|
the HTTP response into an object type of your choice, and returns that
|
||||||
|
object. The method <methodname>postForLocation</methodname> will do a
|
||||||
|
POST, converting the given object into a HTTP request, and returns the
|
||||||
|
response HTTP Location header where the newly created object can be
|
||||||
|
found In case of an exception processing the HTTP request, an exception
|
||||||
|
of the type <classname>RestClientException</classname> will be
|
||||||
|
thrown.</para>
|
||||||
|
|
||||||
|
<para>Objects passed to and returned from these methods are converted to
|
||||||
|
and from HTTP messages by
|
||||||
|
<interfacename>HttpMessageConverter</interfacename> instances.
|
||||||
|
Converters for the main mime types are registered by default, but you
|
||||||
|
can also write your own converter and register it via the
|
||||||
|
<methodname>messageConverters</methodname> bean property. The default
|
||||||
|
converter instances registered with the template are
|
||||||
|
<classname>ByteArrayHttpMessageConverter</classname>,
|
||||||
|
<classname>StringHttpMessageConverter</classname>,
|
||||||
|
<classname>FormHttpMessageConverter</classname> and
|
||||||
|
<classname>SourceHttpMessageConverter</classname>. You can override
|
||||||
|
these defaults using the <methodname>messageConverters</methodname> bean
|
||||||
|
property as would be required if using the
|
||||||
|
<classname>MarshallingHttpMessageConverter</classname>.</para>
|
||||||
|
|
||||||
|
<para>Each method takes URI template arguments in two forms, either as a
|
||||||
|
<literal>String</literal> variable length argument or a
|
||||||
|
<literal>Map<String,String></literal>. For example, </para>
|
||||||
|
|
||||||
|
<programlisting language="java">String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/bookings/{booking}",
|
||||||
|
String.class,"42", "21");
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>using variable length arguments and </para>
|
||||||
|
|
||||||
|
<programlisting language="java">Map<String, String> vars = Collections.singletonMap("hotel", 42);
|
||||||
|
String result = restTemplate.getForObject("http://example.com/hotels/{hotel}/rooms/{hotel}", String.class, vars);
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>using a <literal>Map<String,String></literal>. </para>
|
||||||
|
|
||||||
|
<para>To create an instance of <classname>RestTemplate</classname> you
|
||||||
|
can simply call the default constructor. This will use standard Java
|
||||||
|
classes from the <literal>java.net</literal> package as the underlying
|
||||||
|
implementation to create HTTP requests. This can be overridden by
|
||||||
|
specifying an implementation of
|
||||||
|
<interfacename>ClientHttpRequestFactory</interfacename>. Spring provides
|
||||||
|
the implementation
|
||||||
|
<classname>CommonsClientHttpRequestFactory</classname> that uses the
|
||||||
|
Jakarta Commons <classname>HttpClient</classname> to create requests.
|
||||||
|
<classname>CommonsClientHttpRequestFactory</classname> is configured
|
||||||
|
using an instance of
|
||||||
|
<classname>org.apache.commons.httpclient.HttpClient</classname> which
|
||||||
|
can in turn be configured with credentials information or connection
|
||||||
|
pooling functionality.</para>
|
||||||
|
|
||||||
|
<para>The previous example using Jakarta Commons
|
||||||
|
<classname>HttpClient</classname> directly rewritten to use the
|
||||||
|
<classname>RestTemplate</classname> is shown below </para>
|
||||||
|
|
||||||
|
<programlisting>uri = "http://example.com/hotels/{id}/bookings";
|
||||||
|
|
||||||
|
RestTemplate template = new RestTemplate();
|
||||||
|
|
||||||
|
Booking booking = // create booking object
|
||||||
|
|
||||||
|
URI location = template.postForLocation(uri, booking, String.class, "1");
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>The general callback interface is
|
||||||
|
<interfacename>RequestCallback</interfacename> and is called when the
|
||||||
|
execute method is invoked.</para>
|
||||||
|
|
||||||
|
<programlisting language="java">public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback,
|
||||||
|
ResponseExtractor<T> responseExtractor,
|
||||||
|
String... urlVariables)
|
||||||
|
|
||||||
|
|
||||||
|
// also has an overload with urlVariables as a Map<String, String>.</programlisting>
|
||||||
|
|
||||||
|
<para>The <interfacename>RequestCallback</interfacename> interface is
|
||||||
|
defined as </para>
|
||||||
|
|
||||||
|
<programlisting language="java">public interface RequestCallback {
|
||||||
|
void doWithRequest(ClientHttpRequest request) throws IOException;
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para>and allows you to manipulate the request headers and write to the
|
||||||
|
request body. When using the execute method you do not have to worry
|
||||||
|
about any resource management, the template will always close the
|
||||||
|
request and handle any errors. Refer to the API documentation for more
|
||||||
|
information on using the execute method and the meaning of its other
|
||||||
|
method arguments.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="rest-message-conversion">
|
<section id="rest-message-conversion">
|
||||||
<title>HTTP Message Conversion</title>
|
<title>HTTP Message Conversion</title>
|
||||||
|
|
||||||
<para>blah blah</para>
|
<para>Objects passed to and returned from the methods getForObject(),
|
||||||
|
postForLocation(), and put() and are converted to HTTP requests and from
|
||||||
|
HTTP responses by <interfacename>HttpMessageConverters</interfacename>.
|
||||||
|
The <interfacename>HttpMessageConverter</interfacename> interface is
|
||||||
|
show below to give you a better feel for its functionality</para>
|
||||||
|
|
||||||
|
<programlisting language="java">public interface HttpMessageConverter<T> {
|
||||||
|
|
||||||
|
// Indicate whether the given class is supported by this converter.
|
||||||
|
boolean supports(Class<? extends T> clazz);
|
||||||
|
|
||||||
|
// Return the list of MediaType objects supported by this converter.
|
||||||
|
List<MediaType> getSupportedMediaTypes();
|
||||||
|
|
||||||
|
// Read an object of the given type form the given input message, and returns it.
|
||||||
|
T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
|
||||||
|
|
||||||
|
// Write an given object to the given output message.
|
||||||
|
void write(T t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
|
||||||
|
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para>Concrete implementations for the main media (mime) types are
|
||||||
|
provided in the framework and are registered by default with the
|
||||||
|
<classname>RestTemplate</classname> on the client-side and with
|
||||||
|
<classname>AnnotationMethodHandlerAdapter</classname> on the
|
||||||
|
server-side. </para>
|
||||||
|
|
||||||
|
<para>The implementations of
|
||||||
|
<classname>HttpMessageConverter</classname>s are described in the
|
||||||
|
following sections. For all converters a default media type is used but
|
||||||
|
can be overridden by setting the
|
||||||
|
<classname>supportedMediaTypes</classname> bean property</para>
|
||||||
|
|
||||||
<section id="rest-string-converter">
|
<section id="rest-string-converter">
|
||||||
<title>StringHttpMessageConverter</title>
|
<title>StringHttpMessageConverter</title>
|
||||||
|
|
||||||
<para></para>
|
<para>A <interfacename>HttpMessageConverter</interfacename>
|
||||||
|
implementation that can read and write Strings from the HTTP request
|
||||||
<para></para>
|
and response. By default, this converter supports all text media types
|
||||||
|
(<literal>text/*</literal>), and writes with a
|
||||||
|
<literal>Content-Type</literal> of
|
||||||
|
<literal>text/plain</literal>.</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="rest-form-converter">
|
<section id="rest-form-converter">
|
||||||
<title>FormHttpMessageConverter</title>
|
<title>FormHttpMessageConverter</title>
|
||||||
|
|
||||||
<para></para>
|
<para>A <interfacename>HttpMessageConverter</interfacename>
|
||||||
|
implementation that can read and write form data from the HTTP request
|
||||||
<para></para>
|
and response. By default, this converter reads and writes the media
|
||||||
|
type (<literal>application/x-www-form-urlencoded</literal>). Form data
|
||||||
|
is read from and written into a <literal>MultiValueMap<String,
|
||||||
|
String></literal>. </para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="rest-byte-converter">
|
<section id="rest-byte-converter">
|
||||||
<title>ByteArrayMessageConverter</title>
|
<title>ByteArrayMessageConverter</title>
|
||||||
|
|
||||||
<para></para>
|
<para>A <interfacename>HttpMessageConverter</interfacename>
|
||||||
|
implementation that can read and write byte arrays from the HTTP
|
||||||
<para></para>
|
request and response. By default, this converter supports all media
|
||||||
|
types (<literal>*/*</literal>), and writes with a
|
||||||
|
<literal>Content-Type</literal> of
|
||||||
|
<literal>application/octet-stream</literal>. This can be overridden by
|
||||||
|
setting the <property>supportedMediaTypes</property> property, and
|
||||||
|
overriding <literal>getContentType(byte[])</literal>. </para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="rest-marhsalling-converter">
|
<section id="rest-marhsalling-converter">
|
||||||
<title>MarshallingHttpMessageConverter</title>
|
<title>MarshallingHttpMessageConverter</title>
|
||||||
|
|
||||||
<para></para>
|
<para>A <interfacename>HttpMessageConverter</interfacename>
|
||||||
|
implementation that can read and write XML using Spring's
|
||||||
<para></para>
|
<interfacename>Marshaller</interfacename> and
|
||||||
|
<interfacename>Unmarshaller</interfacename> abstractions from the
|
||||||
|
<classname>org.springframework.oxm</classname> package. This converter
|
||||||
|
requires a <interfacename>Marshaller</interfacename> and
|
||||||
|
<interfacename>Unmarshaller</interfacename> before it can be used.
|
||||||
|
These can be injected via constructor or bean properties. By default
|
||||||
|
this converter supports (<literal>text/xml</literal>) and
|
||||||
|
(<literal>application/xml</literal>).</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="rest-source-converter">
|
<section id="rest-source-converter">
|
||||||
<title>SourceHttpMessageConverter</title>
|
<title>SourceHttpMessageConverter</title>
|
||||||
|
|
||||||
<para></para>
|
<para>A <interfacename>HttpMessageConverter</interfacename>
|
||||||
|
implementation that can read and write
|
||||||
|
<classname>javax.xml.transform.Source</classname> from the HTTP
|
||||||
|
request and response. Only <classname>DOMSource</classname>,
|
||||||
|
<classname>SAXSource</classname>, and
|
||||||
|
<classname>StreamSource</classname> are supported. By default, this
|
||||||
|
converter supports (<literal>text/xml</literal>) and
|
||||||
|
(<literal>application/xml</literal>).</para>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue