|
|
@@ -3,7 +3,7 @@ Getting Started: Creating a REST Endpoint
|
|
3
|
3
|
|
|
4
|
4
|
This Getting Started guide will walk you through the process of creating a simple REST endpoint using Spring.
|
|
5
|
5
|
|
|
6
|
|
-Setting up Gradle
|
|
|
6
|
+Setting Up Gradle
|
|
7
|
7
|
-----------------
|
|
8
|
8
|
We recommend you use Gradle for your Spring projects. If you’re a big Ant / Ivy, Buildr, Gradle, SBT, Leiningen, or Gant fan, that’s cool, but we use Gradle and we’ll be using Gradle in this guide. If you have any questions about how Gradle works, Building and Testing with Gradle (O'Reilly) should have what you’re looking for. (We’re assuming you know how to create a new Gradle project. If not, you can use this to get started.)
|
|
9
|
9
|
|
|
|
@@ -18,50 +18,59 @@ repositories { mavenCentral() }
|
|
18
|
18
|
dependencies {
|
|
19
|
19
|
compile "org.springframework:spring-webmvc:3.2.2.RELEASE"
|
|
20
|
20
|
compile "org.codehaus.jackson:jackson-mapper-asl:1.9.9"
|
|
|
21
|
+ providedCompile "javax.servlet:servlet-api:2.5"
|
|
21
|
22
|
}
|
|
22
|
23
|
```
|
|
23
|
24
|
|
|
24
|
|
-Spring's REST support is based on Spring MVC. Therefore, we must add spring-webmvc as a dependency to our project. Also, so that our endpoints can produce JSON output, we needed to include the Jackson JSON library.
|
|
|
25
|
+Spring's REST support is based on Spring MVC. Therefore, we must add spring-webmvc as a dependency to our project. Also, so that our endpoints can produce JSON output, we needed to include the Jackson JSON library. And, since we'll be working with code that depends on the Servlet API, we'll need the Servlet API (as a providedCompile dependency for compile-time purposes only).
|
|
25
|
26
|
|
|
26
|
|
-Each of these dependencies has dependencies of their own that will transitively be resolved.
|
|
|
27
|
+Each of these dependencies have dependencies of their own that will transitively be resolved.
|
|
27
|
28
|
|
|
28
|
29
|
We've also included the 'jetty' plugin so that we can easily run and test our code via Gradle.
|
|
29
|
30
|
|
|
30
|
31
|
|
|
31
|
|
-Setting up DispatcherServlet
|
|
|
32
|
+Setting Up DispatcherServlet
|
|
32
|
33
|
----------------------------
|
|
33
|
|
-Spring REST endpoints are built as Spring MVC controllers. Therefore, we'll need to be sure that Spring's DispatcherServlet is configured in our application's /WEB-INF/web.xml:
|
|
34
|
|
-
|
|
35
|
|
-```xml
|
|
36
|
|
-<servlet>
|
|
37
|
|
- <servlet-name>appServlet</servlet-name>
|
|
38
|
|
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
|
39
|
|
- <init-param>
|
|
40
|
|
- <param-name>contextClass</param-name>
|
|
41
|
|
- <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
|
|
42
|
|
- </init-param>
|
|
43
|
|
- <init-param>
|
|
44
|
|
- <param-name>contextConfigLocation</param-name>
|
|
45
|
|
- <param-value>org.springframework.hello.config</param-value>
|
|
46
|
|
- </init-param>
|
|
47
|
|
- <load-on-startup>1</load-on-startup>
|
|
48
|
|
-</servlet>
|
|
49
|
|
-
|
|
50
|
|
-<servlet-mapping>
|
|
51
|
|
- <servlet-name>appServlet</servlet-name>
|
|
52
|
|
- <url-pattern>/</url-pattern>
|
|
53
|
|
-</servlet-mapping>
|
|
|
34
|
+Spring REST endpoints are built as Spring MVC controllers. Therefore, we'll need to be sure that Spring's DispatcherServlet is configured. We can do that by creating a web application initializer class:
|
|
|
35
|
+
|
|
|
36
|
+```java
|
|
|
37
|
+package org.springframework.hello.config;
|
|
|
38
|
+
|
|
|
39
|
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
|
|
|
40
|
+
|
|
|
41
|
+public class HelloWorldWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
|
|
|
42
|
+
|
|
|
43
|
+ @Override
|
|
|
44
|
+ protected String[] getServletMappings() {
|
|
|
45
|
+ return new String[] { "/" };
|
|
|
46
|
+ }
|
|
|
47
|
+
|
|
|
48
|
+ @Override
|
|
|
49
|
+ protected Class<?>[] getRootConfigClasses() {
|
|
|
50
|
+ return null;
|
|
|
51
|
+ }
|
|
|
52
|
+
|
|
|
53
|
+ @Override
|
|
|
54
|
+ protected Class<?>[] getServletConfigClasses() {
|
|
|
55
|
+ return new Class[] { HelloWorldConfiguration.class };
|
|
|
56
|
+ }
|
|
|
57
|
+
|
|
|
58
|
+}
|
|
54
|
59
|
```
|
|
55
|
60
|
|
|
56
|
|
-Here we've configured DispatcherServlet to use AnnotationConfigWebApplicationContext as the context class so that our configuration can be expressed in Java, rather than XML. We've also set told DispatcherServlet (via the contextConfigLocation initialization parameter) that it can find our configuration classes in the org.springframework.hello.config package.
|
|
|
61
|
+By extending AbstractAnnotationConfigDispatcherServletInitializer, our web application initializer will get a DispatcherServlet that is configured with @Configuration-annotated classes. All we must do is tell it where those configuration classes are and what path(s) to map DispatcherServlet to.
|
|
|
62
|
+
|
|
|
63
|
+With regard to the servlet path mappings, getServletMappings() returns a single-entry array of String specifying that DispatcherServlet should be mapped to "/".
|
|
57
|
64
|
|
|
58
|
|
-Now let's create the configuration class.
|
|
|
65
|
+The getRootConfigClasses() and getServletConfigClasses() methods specify the configuration classes. The Class array returned from getRootConfigClasses() specifies the classes for the root context provided to ContextLoaderListener. Similarly, the Class array returned from getServletConfigClasses() specifies the classes for the servlet application context provided to DispatcherServlet.
|
|
59
|
66
|
|
|
|
67
|
+For our purposes there will only be a servlet application context, so getRootConfigClasses() returns null. getServletConfigClasses(), however, specifies HelloWorldConfiguration as the only configuration class.
|
|
60
|
68
|
|
|
61
|
69
|
Creating a Configuration Class
|
|
62
|
70
|
------------------------------
|
|
63
|
|
-In our Spring configuration, we'll need to enable annotation-oriented Spring MVC. And we'll also need to tell Spring where it can find our endpoint controller class. The following configuration class takes care of both of those things:
|
|
|
71
|
+Now that we have setup DispatcherServlet to handle requests for our application, we need to configure the Spring application context used by DispatcherServlet.
|
|
64
|
72
|
|
|
|
73
|
+In our Spring configuration, we'll need to enable annotation-oriented Spring MVC. And we'll also need to tell Spring where it can find our endpoint controller class. The following configuration class takes care of both of those things:
|
|
65
|
74
|
|
|
66
|
75
|
```java
|
|
67
|
76
|
package org.springframework.hello.config;
|
|
|
@@ -80,10 +89,10 @@ public class HelloWorldConfiguration {
|
|
80
|
89
|
|
|
81
|
90
|
The @EnableWebMvc annotation turns on annotation-oriented Spring MVC. And we've also annotated the configuration class with @ComponentScan to have it look for components (including controllers) in the org.springframework.hello package. As it turns out, classes that are annotated with @Configuration are also discovered by component scanning, so we had to specify an exclude filter to keep it from discovering and using our configuration class a second time.
|
|
82
|
91
|
|
|
83
|
|
-With configuration details completed, now it's time to start writing code for our endpoint.
|
|
84
|
|
-
|
|
85
|
92
|
Creating a Representation Class
|
|
86
|
93
|
-------------------------------
|
|
|
94
|
+With the essential Spring MVC configuration out of the way, it's time to get to the nuts and bolts of our REST endpoint by creating a resource representation class and an endpoint controller.
|
|
|
95
|
+
|
|
87
|
96
|
Before we get too carried away with building the endpoint controller, we need to give some thought to what our API will look like.
|
|
88
|
97
|
|
|
89
|
98
|
What we want is to handle GET requests for /hello-world, optionally with a name query parameter. In response to such a request, we'd like to send back JSON looking something like this:
|
|
|
@@ -157,11 +166,17 @@ The key difference between a human-facing controller and a REST endpoint control
|
|
157
|
166
|
|
|
158
|
167
|
The magic is in the @ResponseBody annotation. @ResponseBody tells Spring MVC to not render a model into a view, but rather to write the returned object into the response body. It does this by using one of Spring's message converters.
|
|
159
|
168
|
|
|
160
|
|
-{TODO: briefly talk about what message converters do and list the ones that come out of the box with Spring}
|
|
|
169
|
+>__TODO__: briefly talk about what message converters do and list the ones that come out of the box with Spring}
|
|
161
|
170
|
|
|
162
|
171
|
|
|
163
|
172
|
Building and Running the REST Endpoint
|
|
164
|
173
|
--------------------------------------
|
|
|
174
|
+>**NOTE**: The following section probably needs to be reworked
|
|
|
175
|
+ (and the build file that goes with it) to use a Servlet 3
|
|
|
176
|
+ container (such as a modern Tomcat). At this point,
|
|
|
177
|
+ these steps do not work since the sample code uses a
|
|
|
178
|
+ web app initializer instead of web.xml.
|
|
|
179
|
+
|
|
165
|
180
|
All of the pieces of our REST endpoint are in place. All that's left to do is to build it and run it.
|
|
166
|
181
|
|
|
167
|
182
|
To run the sample, issue the following Gradle command:
|