构建RESTful Web 服务
这个指南将会带你用Spring创建一个"hello word" RESTful Web 服务
你可以创建什么
你可以用创建一个服务接受HTTP GET请求
http://localhost:8080/greeting
并且响应JSON格式的greeting
{"id":1,"content":"Hello, World!"}
你可以在查询字符串中自定义带有可选择name参数的greeting
http://localhost:8080/greeting?name=User
这个name的值重写"word"这个默认值,并且体现在这个响应中
{"id":1,"content":"Hello, User!"}
你需要什么
-
About 15 minutes
-
A favorite text editor or IDE
-
JDK 1.8 or later
-
You can also import the code straight into your IDE:
怎么完成这个指南
像大多数Spring Getting Started指南一样,你可以从scratch开始并且完成每一步,或者你可以跳过基本的你已经熟悉步骤,不管怎样,你最后都要以工作代码结束
现在开始这个scratch,请点击这链接 Build with Gradle
跳过基本步骤,请做一下步骤:
- 下载并且解压这个导读指南的资源仓库,或者从git上克隆
-
cd into
gs-rest-service/initial
当你完成之后,你可以code这个检查结果:gs-rest-service/complete
.
创建一个资源来表示这个类
现在你可以设置项目和构建系统,你可以创建你的web 服务
通过考虑服务交互来开始
这个服务会提交关于/greeting的GET请求,也可以选择带有name的参数在查询字符串里,这个GET请求应该返回一个JSON格式的200 ok在表示greeting的主体中,它应该看起来像这样。
{
"id": 1,
"content": "Hello, World!"
}
这个id字段是这个greeting的唯一认证,这个content字段是代表greeting的文本描述
为了构建greeting代表,你可创建一个资源代表类,并且提供一个具有字段,构造函数和访问器的普通java对象。
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;
}
}
当你看到下面的步骤,Spring使用Jackson JSON库自动的整理Greeting类型的实例到JSON中
接下来你可以创造服务这些greeting的controller资源
创造一个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:
在Spring构建WEB service中,HTTP请求被Controller控制,这些组件很容易的被@Controller注解标识,下面的GreetingController来处理greeting的GET请求,并返回一个新的Greeting类的实例
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));
}
}
这个controller简单明了,但是在后台有大量的事情处理,让我们继续一步一步打破它
The @RequestMapping
annotation ensures that HTTP requests to /greeting
are mapped to the greeting()
method.
这个@RequestMapping注解确定greeting的HTTP请求可以匹配到greeting()方法
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.
上面并没指定GET、PUT、POST,因为@RequestMapping注解默认匹配所有HTTP操作,使用@Requestmapping(method=GET)来精准定位这个映射。
@RequestParam binds the value of the query string parameter name into the name parameter of the greeting() method. If the name parameter is absent in the request, the defaultValue of "World" is used
@RequestPara绑定查询字符串中的参数到greeting()方法的name参数,如果name参数不存在,就是用默认值“World”
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 given name by using the greeting template.
方法主体的实现产生并且返回一个新的带有id和content字段的Greeting对象,并且使用greeting规范被给予的name
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.
传统的MVC控制器和RESTful web服务之间最关键的区别是HTTP响应主体的创建,RESTful web服务控制器简单的返回Greeting对象,而不是依赖试图技术来执行服务端对greeting数据到HTML的渲染,对象数据将以JSON格式被直接写入到HTTP响应中
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.
这个代码使用Spring4新的@RestController注解,被标记为控制器,并且每个方法都返回一个对象,而不是试图,它是@Controller和
@ResponseBody
的结合。
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.
这个greeting对象必须被转换成JSON,多亏Spring消息转换器的支持,你不需要手动转换,因为Jackson 2是在Spring的MappingJackson2HttpMessageConverter自动的把Greeting这个实例转换为JSON。
使这个程序执行
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 Java main()
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.
尽管可能将这个服务打成WAR包发布到远端服务器上,下面更简单的方法演示创建一个独立的应用程序,你打包所有东西成单一的可执行的JAR包,被java的main()方法驱动,通过这个方法,你使用Spring的支持为了潜入Tomcat服务容器到HTTP运行时,而不是部署到一个外部的实例中
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:
@SpringBootApplication
是一个很方便的注解,添加了一下内容:
-
@Configuration
tags the class as a source of bean definitions for the application context. -
@Configuration
标记这个类给Spring应用上下文作为bean的来源 -
@EnableAutoConfiguration
tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings. -
@EnableAutoConfiguration 告诉Spring基于类路径配置、其他beans和各种属性配置来添加bean
-
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
. -
通常你会添加
@EnableWebMvc
给Spring MVC应用程序,但是SpringBoot自动添加它,当它在类路径上看到spring-webmvc,标记这个应用程序为web应用程序,并且激活关键行为,比如设置一个DispatcherServlet
. -
@ComponentScan
tells Spring to look for other components, configurations, and services in thehello
package, allowing it to find the controllers. -
@ComponentScan 告诉Spring取在htllo包寻找其他的组件,配置和服务,允许它找到控制器
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.
main()方法使用SpringBoot的SpringApplication.run()方法去启动一个应用程序,你注意到这里没有一行xml吗?也没有web.xml文件,这个web应用程序是100%纯java,你也不用处理任何管道和基础设施。
构建一个可执行的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.
你可以使用gradle或者maven来运行应用程序,或者你可以构建一个可执行的JAR包,包括所有必须的依赖,类,和资源并且运行它,在整个开发周期,越过不同环境等等,使你很容易的控制版本和发布这个服务到应用程序中。
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:
如果你使用Gradle,你可以使用./gradlew bootRun 运行容器,或者你可以创建一个JAR包使用./gradlew build,然后运行JAR包:
java -jar build/libs/gs-rest-service-0.1.0.jar
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:
如果你使用Maven,你可以使用./mvnw spring-boot:run运行你的容器,或者你可以创建一个JAR包使用./mvnw clean package,然后运行JAR包:
java -jar target/gs-rest-service-0.1.0.jar
Logging output is displayed. The service should be up and running within a few seconds.
日志输出已经显示了,这个服务会在几秒内启动。
测试这个服务
Now that the service is up, visit http://localhost:8080/greeting, where you see:
现在这个服务已经启动,你可以访问http://localhost:8080/greeting,当你看到:
{"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!"
提供一个name查询自渡船参数用这个http://localhost:8080/greeting?name=User,注意内容属性的值怎么从"Hello, World!"改变成"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.
这个变化演示了在GreetingController里的@RequestParam注解正在按预期进行,这个name参数已经被提供默认值“World”,但是可以通过查询字符串被重写。
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 its counter
field is being incremented on each call as expected.
也注意id属性从1变成2,这证明了你可以对同样的GreetingController请求工作通过多个请求,它的counter字段会自动增加。
总结
Congratulations! You’ve just developed a RESTful web service with Spring.
恭喜,你开发了一个有Spring的REST Web服务