目标
构建一个service,接收如下HTTP GET请求:
并返回如下JSON格式的问候语:
你也可以通过指定查询字符串中的可选参数name来定制问候语:
参数name的值覆盖了默认值“World”,得到的响应为:
准备工作
- 大约15分钟
- 一个文本编辑器或IDE
- JDK1.6或更高
- Gradle 1.8+或Maven 3.0+
- 你也可以使用STS(Spring Tool Suite)直接import该工程
如何完成
如同所有的Spring入门教程,你可以选择一步一步的自己实现,也可以跳过基本的设置步骤。最终,你都将得到一份可以正常运行的代码。
如果选择按步实现,继续下一节。
如果选择跳过基本的安装部分,则执行以下命令从github获取代码:
切换当前目录到gs-rest-service/initial,跳到Create a resource representation class步骤。
完成后,可以与gs-rest-service/complete中的代码对比一下,确保正确。
建立工程
首先建立一个基本的构建脚本。基于Spring构建应用时,可以用使用任何的构建系统。这里我们以Gradle和Maven为例。如果不熟悉它们,请参考Building Java Projects with Gradle或者Building Java Projects with Maven
建立目录结构
在你选定的工程目录下,建立如下子目录结构;例如,在*nix系统中使用mkdir -p src/main/java/hello命令:
└── src └── main └── java └── hello
创建Gradle构建文件
下面是初始的gradle构建文件。你也可以使用Maven,Maven的配置文件pom.xml可以参考这里。如果你使用STS(Spring Tool Suite),可以直接导入该工程。
build.gradle
注意:本文使用了Spring Boot。
创建资源描述类(Create a resource representation class)
现在已经建立了工程和构建系统,下面创建你的web service。
首先考虑服务间的交互(service interactions)。
这个服务要处理/greeting的GET请求,其查询字符串包含一个可选的name参数。这个GET请求应该一个200 OK的响应,以及JSON结构的描述问候语的内容。格式如下:
id域是问候语的唯一标识,content域是问候语的文本描述。
为了对问候语的描述进行建模,创建了一个资源描述类。提供了一个包含域(id和content)、构造方法和访问器(getter和setter)的pojo(pain old java object)类:
src/main/java/hello/Greeting.java
注意:下面的步骤中,Spring使用了Jackson JSON库将Greeting类型的实例编码成JSON格式。
下面创建资源控制器(resource controller)来发送这些问候语。
创建资源控制器(Create a resource controller)
采用Spring构建RESTful web services时,采用控制器处理HTTP请求。控制器组件通过@Controller注解来标识,下面的GreetingController类处理/greeting的GET请求,并返回一个Greeting类的新的实例:
src/main/java/hello/GreetingController.java
这个controller很简单,但是其内部做了大量工作,麻雀虽小,五脏俱全。我们一步一步的解释。
@RequestMapping注解确保对/greeting的HTTP请求映射到greeting()方法。
注意:上述例子中没有写明GET、PUT、POST等等。这是因为@RequestMapping注解默认情况下映射所有的HTTP操作。使用@RequestMapping(method=GET)指定只映射GET请求。
@RequestParam把查询字符串中name参数的值绑定到greeting()方法的name参数上。该查询参数不是必须的(required=false);如果请求时没有指定该参数,则使用其默认值“World”(defaultValue)。
方法体的实现创建并返回了一个新的Greeting对象,该对象的id属性每次自增1,content属性采用template和name组合而来。
传统的MVC控制器和上述RESTful web service控制器的一个关键区别在于:HTTP响应体的创建方式。前者采用视图层技术(view technology)实现把服务器端的数据渲染为HTML,后者则返回一个Greeting对象。对象数据将会直接以JSON格式写到HTTP响应中。
通过以下方式实现上述功能,greeting()方法的@ResponseBody注解告诉Spring MVC不需要使用服务器端视图层渲染问候语对象(the greeting object),取而代之的是,返回的问候语对象时一个response body,而且应该直接写出。
Greeting对象必须转换成JSON格式。由于Spring支持HTTP报文转换,你不需要手工进行转换。由于Jackson 2在classpath中,因而Spring的MappingJackson2HttpMessageConverter会自动将Greeting实例转换为JSON格式。
Make the application executable
虽然可以将这个service打包成传统的WAR文件,并部署到一个外部的应用服务器上,但是我们采用了一个更简单的方式:创建一个独立的(standalone)应用程序。把所有文件打包到一个可执行的JAR文件中,由古老的main()方法驱动。采用Spring提供的嵌入的Tomcat Servlet容器作为HTTP运行时环境,不需要部署一个外部的运行时环境实例。
src/main/java/hello/Application.java
main()方法调用了SpringApplication帮助类,把Application.class传递给它的run()方法作为参数。这样Spring就会去从Application读取注解,并作为Spring application context的一个组件进行管理。
@ComponentScan注解告诉Spring递归地搜索hello包和其子包中直接或间接标记为@Component的类。这确保Spring发现并注册GreetingController,由于它被标记为@Controller,而@Controller是一类@Component注解。
@EnableAutoConfiguration注解基于你的classpath的内容打开合理的默认行为。例如,由于应用程序依赖于嵌入版的Tomcat(tomcat-embed-core.jar),一个Tomcat服务器会自动建立并进行合理的默认配置。应用程序也依赖于Spring MVC(spring-webmvc.jar),一个Spring MVC DispatcherServlet会为你配置和注册--不需要web.xml!自动配置(Auto-configuration)是一种强大的灵活的机制。详请参考API文档。
构建可执行JAR(Build an executable JAR)
目前位置,Application类已经写完,下面通过构建系统把所有文件打包为一个可执行jar文件。这将便于对这个service在多种不同环境中进行发布、版本控制和部署。
下面是采用Gradle的步骤,如果采用Maven,可以在这里找到pom.xml文件,执行mvn clean package构建工程。
更新build.gradle文件的buildscript部分,如下:
再在build.gradle中添加如下语句:
可以在这里看到最终版本的build.gradle文件。
Spring Boot gradle plugin收集classpath中的所有jar包,并构建一个单独的uber-jar,这使得更加便于执行和传输你的service。它也搜索public static void main()方法标志为一个可执行类。
下面执行如下命令生成一个单独的可执行JAR文件,该JAR文件包含所有必需的依赖的类和资源:
如果你使用Gradle,可以使用如下语句执行生成的JAR文件:
如果使用Maven,使用如下语句:
注意:上述过程将生成一个可执行JAR。你也可以选择构建一个WAR文件。
执行(Run the service)
如果采用Gradle,可以在命令行中执行如下命令来运行你的service:
注意:如果采用Maven,可以执行如下语句mvn clean package && java -jar target/gs-rest-service-0.1.0.jar
日志输出。service将会启动并在数秒钟内运行。
测试(Test the service)
现在service已经启动,访问http://localhost:8080/greeting,你会看到:
查询字符串中指定一个name参数,如http://localhost:8080/greeting?name=User。content的值从“Hello, World!”变为“Hello, User!”:
这说明GreetingController类中的@RequestParam注解起作用了。name参数给定的默认值为“World”,但是可以通过在查询字符串中设定值覆盖它。
注意id属性从1变为2。这表明你在多次请求中访问了同一个GreetingController实例,它的counter域每次访问时会自增1。
小结(Summary)
恭喜!你已经开发出了一个基于Spring的RESTful web service。
英文原文:Building a RESTful Web Service
Building a RESTful Web Service
This guide walks you through the process of creating a "hello world" RESTful web service with Spring.
What you’ll build
You’ll build a service that will accept HTTP GET requests at:
http://localhost:8080/greeting
and respond with a JSON representation of a greeting:
{"id":1,"content":"Hello, World!"}
You can customize the greeting with an optional name
parameter in the query string:
http://localhost:8080/greeting?name=User
The name
parameter value overrides the default value of "World" and is reflected in the response:
{"id":1,"content":"Hello, User!"}
What you’ll need
-
About 15 minutes
-
A favorite text editor or IDE
-
JDK 1.8 or later
-
You can also import the code from this guide as well as view the web page directly intoSpring Tool Suite (STS) and work your way through it from there.
How to complete this guide
Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.
To start from scratch, move on to Build with Gradle.
To skip the basics, do the following:
-
Download and unzip the source repository for this guide, or clone it using Git:
git clone https://github.com/spring-guides/gs-rest-service.git
-
cd into
gs-rest-service/initial
-
Jump ahead to Create a resource representation class.
When you’re finished, you can check your results against the code ings-rest-service/complete
.
Build with Gradle
Build with Maven
Build with your IDE
Create a resource representation class
Now that you’ve set up the project and build system, you can create your web service.
Begin the process by thinking about service interactions.
The service will handle GET
requests for /greeting
, optionally with a name
parameter in the query string. The GET
request should return a 200 OK
response with JSON in the body that represents a greeting. It should look something like this:
{
"id": 1,
"content": "Hello, World!"
}
The id
field is a unique identifier for the greeting, and content
is the textual representation of the greeting.
To model the greeting representation, you create a resource representation class. Provide a plain old java object with fields, constructors, and accessors for the id
and content
data:
src/main/java/hello/Greeting.java
package hello;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
As you see in steps below, Spring uses the Jackson JSON library to automatically marshal instances of type Greeting into JSON. |
Next you create the resource controller that will serve these greetings.
Create a resource controller
In Spring’s approach to building RESTful web services, HTTP requests are handled by a controller. These components are easily identified by the @RestController
annotation, and the GreetingController
below handles GET
requests for /greeting
by returning a new instance of the Greeting
class:
src/main/java/hello/GreetingController.java
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}
This controller is concise and simple, but there’s plenty going on under the hood. Let’s break it down step by step.
The @RequestMapping
annotation ensures that HTTP requests to /greeting
are mapped to the greeting()
method.
The above example does not specify GET vs. PUT , POST , and so forth, because@RequestMapping maps all HTTP operations by default. Use@RequestMapping(method=GET) to narrow this mapping. |
@RequestParam
binds the value of the query string parameter name
into the name
parameter of the greeting()
method. This query string parameter is optional (required=false
by default): if it is absent in the request, the defaultValue
of "World" is used.
The implementation of the method body creates and returns a new Greeting
object with id
and content
attributes based on the next value from the counter
, and formats the givenname
by using the greeting template
.
A key difference between a traditional MVC controller and the RESTful web service controller above is the way that the HTTP response body is created. Rather than relying on a view technology to perform server-side rendering of the greeting data to HTML, this RESTful web service controller simply populates and returns a Greeting
object. The object data will be written directly to the HTTP response as JSON.
This code uses Spring 4’s new @RestController
annotation, which marks the class as a controller where every method returns a domain object instead of a view. It’s shorthand for@Controller
and @ResponseBody
rolled together.
The Greeting
object must be converted to JSON. Thanks to Spring’s HTTP message converter support, you don’t need to do this conversion manually. Because Jackson 2 is on the classpath, Spring’s MappingJackson2HttpMessageConverter
is automatically chosen to convert the Greeting
instance to JSON.
Make the application executable
Although it is possible to package this service as a traditional WAR file for deployment to an external application server, the simpler approach demonstrated below creates a standalone application. You package everything in a single, executable JAR file, driven by a good old Javamain()
method. Along the way, you use Spring’s support for embedding the Tomcat servlet container as the HTTP runtime, instead of deploying to an external instance.
src/main/java/hello/Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication
is a convenience annotation that adds all of the following:
-
@Configuration
tags the class as a source of bean definitions for the application context. -
@EnableAutoConfiguration
tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. -
Normally you would add
@EnableWebMvc
for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up aDispatcherServlet
. -
@ComponentScan
tells Spring to look for other components, configurations, and services in the thehello
package, allowing it to find theHelloController
.
The main()
method uses Spring Boot’s SpringApplication.run()
method to launch an application. Did you notice that there wasn’t a single line of XML? No web.xml file either. This web application is 100% pure Java and you didn’t have to deal with configuring any plumbing or infrastructure.
Build an executable JAR
You can run the application from the command line with Gradle or Maven. Or you can build a single executable JAR file that contains all the necessary dependencies, classes, and resources, and run that. This makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.
If you are using Gradle, you can run the application using ./gradlew bootRun
. Or you can build the JAR file using ./gradlew build
. Then you can run the JAR file:
If you are using Maven, you can run the application using ./mvnw spring-boot:run
. Or you can build the JAR file with ./mvnw clean package
. Then you can run the JAR file:
The procedure above will create a runnable JAR. You can also opt to build a classic WAR fileinstead. |
Logging output is displayed. The service should be up and running within a few seconds.
Test the service
Now that the service is up, visit http://localhost:8080/greeting, where you see:
{"id":1,"content":"Hello, World!"}
Provide a name
query string parameter with http://localhost:8080/greeting?name=User. Notice how the value of the content
attribute changes from "Hello, World!" to "Hello User!":
{"id":2,"content":"Hello, User!"}
This change demonstrates that the @RequestParam
arrangement in GreetingController
is working as expected. The name
parameter has been given a default value of "World", but can always be explicitly overridden through the query string.
Notice also how the id
attribute has changed from 1
to 2
. This proves that you are working against the same GreetingController
instance across multiple requests, and that itscounter
field is being incremented on each call as expected.
Summary
Congratulations! You’ve just developed a RESTful web service with Spring.
Want to write a new guide or contribute to an existing one? Check out our contribution guidelines.
All guides are released with an ASLv2 license for the code, and an Attribution, NoDerivatives creative commons license for the writing. |
Building a RESTful Web Service
This guide walks you through the process of creating a "hello world" RESTful web service with Spring.
What you’ll build
You’ll build a service that will accept HTTP GET requests at:
http://localhost:8080/greeting
and respond with a JSON representation of a greeting:
{"id":1,"content":"Hello, World!"}
You can customize the greeting with an optional name
parameter in the query string:
http://localhost:8080/greeting?name=User
The name
parameter value overrides the default value of "World" and is reflected in the response:
{"id":1,"content":"Hello, User!"}
What you’ll need
-
About 15 minutes
-
A favorite text editor or IDE
-
JDK 1.8 or later
-
You can also import the code from this guide as well as view the web page directly intoSpring Tool Suite (STS) and work your way through it from there.
How to complete this guide
Like most Spring Getting Started guides, you can start from scratch and complete each step, or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.
To start from scratch, move on to Build with Gradle.
To skip the basics, do the following:
-
Download and unzip the source repository for this guide, or clone it using Git:
git clone https://github.com/spring-guides/gs-rest-service.git
-
cd into
gs-rest-service/initial
-
Jump ahead to Create a resource representation class.
When you’re finished, you can check your results against the code ings-rest-service/complete
.
Build with Gradle
Build with Maven
Build with your IDE
Create a resource representation class
Now that you’ve set up the project and build system, you can create your web service.
Begin the process by thinking about service interactions.
The service will handle GET
requests for /greeting
, optionally with a name
parameter in the query string. The GET
request should return a 200 OK
response with JSON in the body that represents a greeting. It should look something like this:
{
"id": 1,
"content": "Hello, World!"
}
The id
field is a unique identifier for the greeting, and content
is the textual representation of the greeting.
To model the greeting representation, you create a resource representation class. Provide a plain old java object with fields, constructors, and accessors for the id
and content
data:
src/main/java/hello/Greeting.java
package hello;
public class Greeting {
private final long id;
private final String content;
public Greeting(long id, String content) {
this.id = id;
this.content = content;
}
public long getId() {
return id;
}
public String getContent() {
return content;
}
}
As you see in steps below, Spring uses the Jackson JSON library to automatically marshal instances of type Greeting into JSON. |
Next you create the resource controller that will serve these greetings.
Create a resource controller
In Spring’s approach to building RESTful web services, HTTP requests are handled by a controller. These components are easily identified by the @RestController
annotation, and the GreetingController
below handles GET
requests for /greeting
by returning a new instance of the Greeting
class:
src/main/java/hello/GreetingController.java
package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@RequestMapping("/greeting")
public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
}
This controller is concise and simple, but there’s plenty going on under the hood. Let’s break it down step by step.
The @RequestMapping
annotation ensures that HTTP requests to /greeting
are mapped to the greeting()
method.
The above example does not specify GET vs. PUT , POST , and so forth, because@RequestMapping maps all HTTP operations by default. Use@RequestMapping(method=GET) to narrow this mapping. |
@RequestParam
binds the value of the query string parameter name
into the name
parameter of the greeting()
method. This query string parameter is optional (required=false
by default): if it is absent in the request, the defaultValue
of "World" is used.
The implementation of the method body creates and returns a new Greeting
object with id
and content
attributes based on the next value from the counter
, and formats the givenname
by using the greeting template
.
A key difference between a traditional MVC controller and the RESTful web service controller above is the way that the HTTP response body is created. Rather than relying on a view technology to perform server-side rendering of the greeting data to HTML, this RESTful web service controller simply populates and returns a Greeting
object. The object data will be written directly to the HTTP response as JSON.
This code uses Spring 4’s new @RestController
annotation, which marks the class as a controller where every method returns a domain object instead of a view. It’s shorthand for@Controller
and @ResponseBody
rolled together.
The Greeting
object must be converted to JSON. Thanks to Spring’s HTTP message converter support, you don’t need to do this conversion manually. Because Jackson 2 is on the classpath, Spring’s MappingJackson2HttpMessageConverter
is automatically chosen to convert the Greeting
instance to JSON.
Make the application executable
Although it is possible to package this service as a traditional WAR file for deployment to an external application server, the simpler approach demonstrated below creates a standalone application. You package everything in a single, executable JAR file, driven by a good old Javamain()
method. Along the way, you use Spring’s support for embedding the Tomcat servlet container as the HTTP runtime, instead of deploying to an external instance.
src/main/java/hello/Application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@SpringBootApplication
is a convenience annotation that adds all of the following:
-
@Configuration
tags the class as a source of bean definitions for the application context. -
@EnableAutoConfiguration
tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. -
Normally you would add
@EnableWebMvc
for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up aDispatcherServlet
. -
@ComponentScan
tells Spring to look for other components, configurations, and services in the thehello
package, allowing it to find theHelloController
.
The main()
method uses Spring Boot’s SpringApplication.run()
method to launch an application. Did you notice that there wasn’t a single line of XML? No web.xml file either. This web application is 100% pure Java and you didn’t have to deal with configuring any plumbing or infrastructure.
Build an executable JAR
You can run the application from the command line with Gradle or Maven. Or you can build a single executable JAR file that contains all the necessary dependencies, classes, and resources, and run that. This makes it easy to ship, version, and deploy the service as an application throughout the development lifecycle, across different environments, and so forth.
If you are using Gradle, you can run the application using ./gradlew bootRun
. Or you can build the JAR file using ./gradlew build
. Then you can run the JAR file:
If you are using Maven, you can run the application using ./mvnw spring-boot:run
. Or you can build the JAR file with ./mvnw clean package
. Then you can run the JAR file:
The procedure above will create a runnable JAR. You can also opt to build a classic WAR fileinstead. |
Logging output is displayed. The service should be up and running within a few seconds.
Test the service
Now that the service is up, visit http://localhost:8080/greeting, where you see:
{"id":1,"content":"Hello, World!"}
Provide a name
query string parameter with http://localhost:8080/greeting?name=User. Notice how the value of the content
attribute changes from "Hello, World!" to "Hello User!":
{"id":2,"content":"Hello, User!"}
This change demonstrates that the @RequestParam
arrangement in GreetingController
is working as expected. The name
parameter has been given a default value of "World", but can always be explicitly overridden through the query string.
Notice also how the id
attribute has changed from 1
to 2
. This proves that you are working against the same GreetingController
instance across multiple requests, and that itscounter
field is being incremented on each call as expected.
Summary
Congratulations! You’ve just developed a RESTful web service with Spring.
Want to write a new guide or contribute to an existing one? Check out our contribution guidelines.
All guides are released with an ASLv2 license for the code, and an Attribution, NoDerivatives creative commons license for the writing. |