[关闭]
@K1999 2016-08-22T08:27:08.000000Z 字数 6466 阅读 1633

Spring学习笔记之一:建立一个RESTful Web Service

Java


原文地址:https://spring.io/guides/gs/rest-service/
项目地址:https://github.com/spring-guides/gs-rest-service

示例环境:
IDE: IntelliJ IDEA 2016.2.1
JRE: 1.8.0_101-b13 amd64
JVM: Java HotSpot(TM) 64-Bit Server VM by Oracle Corporation


功能

构建一个服务器,能够接收如下的HTTP GET请求:

  1. http://localhost:8080/greeting

并返回一个JSON格式的数据:

  1. {"id":1,"content":"Hello, World!"}

你也可以通过指定查询字符串中的可选参数name来定制问候语:

  1. http://localhost:8080/greeting?name=User

参数name的值覆盖了默认值“World”,得到的响应为:

  1. {"id":1,"content":"Hello, User!"}

步骤

1. 在IntellJ中建立一个maven项目。

2. 创建资源描述类

这个服务要处理/greeting的GET请求,其查询字符串包含一个可选的name参数。这个GET请求应该一个200 OK的响应,以及JSON结构的描述问候语的内容。格式如下:

  1. {
  2. "id": 1,
  3. "content": "Hello, World!"
  4. }

id域是问候语的唯一标识,content域是问候语的文本描述。
为了对问候语的描述进行建模,创建了一个资源描述类。提供了一个包含域(id和content)、构造方法和访问器(getter和setter)的pojo(pain old java object)类:

  1. // 文件地址:src/main/java/hello/Greeting.java
  2. package hello;
  3. public class Greeting {
  4. private final long id;
  5. private final String content;
  6. public Greeting(long id, String content) {
  7. this.id = id;
  8. this.content = content;
  9. }
  10. public long getId() {
  11. return id;
  12. }
  13. public String getContent() {
  14. return content;
  15. }
  16. }

3. 创建资源控制器

下面的步骤中,Spring使用了Jackson JSON库将Greeting类型的实例编码成JSON格式。
采用Spring构建RESTful web services时,采用控制器处理HTTP请求。控制器组件通过@Controller注解来标识,下面的GreetingController类处理/greeting的GET请求,并返回一个Greeting类的新的实例:

  1. // 文件地址:src/main/java/hello/GreetingController.java
  2. package hello;
  3. import java.util.concurrent.atomic.AtomicLong;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.web.bind.annotation.RequestMapping;
  6. import org.springframework.web.bind.annotation.RequestParam;
  7. import org.springframework.web.bind.annotation.ResponseBody;
  8. @Controller
  9. public class GreetingController {
  10. private static final String template = "Hello, %s!";
  11. private final AtomicLong counter = new AtomicLong();
  12. @RequestMapping("/greeting")
  13. public @ResponseBody Greeting greeting(
  14. @RequestParam(value="name", required=false, defaultValue="World") String name) {
  15. return new Greeting(counter.incrementAndGet(),
  16. String.format(template, name));
  17. }
  18. }

这个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格式。

4. 使程序可执行

虽然可以将这个service打包成传统的WAR文件,并部署到一个外部的应用服务器上,但是我们采用了一个更简单的方式:创建一个独立的(standalone)应用程序。把所有文件打包到一个可执行的JAR文件中,由古老的main()方法驱动。采用Spring提供的嵌入的Tomcat Servlet容器作为HTTP运行时环境,而不用部署一个外部的运行时环境实例。

  1. // 文件地址:src/main/java/hello/Application.java
  2. package hello;
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5. @SpringBootApplication
  6. public class Application {
  7. public static void main(String[] args) {
  8. SpringApplication.run(Application.class, args);
  9. }
  10. }

@SpringBootApplication是一个方便的注解,他自动把下面这些注解添加到程序中来:

main()方法调用了SpringApplication帮助类,把Application.class传递给它的run()方法作为参数。这样Spring就会去从Application读取注解,并作为Spring application context的一个组件进行管理。

5. 配置pom.xml文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>org.springframework</groupId>
  6. <artifactId>gs-rest-service</artifactId>
  7. <version>0.1.0</version>
  8. <parent>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-starter-parent</artifactId>
  11. <version>1.4.0.RELEASE</version>
  12. </parent>
  13. <dependencies>
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-web</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.springframework.boot</groupId>
  20. <artifactId>spring-boot-starter-test</artifactId>
  21. <scope>test</scope>
  22. </dependency>
  23. <dependency>
  24. <groupId>com.jayway.jsonpath</groupId>
  25. <artifactId>json-path</artifactId>
  26. <scope>test</scope>
  27. </dependency>
  28. <dependency>
  29. <groupId>ch.qos.logback</groupId>
  30. <artifactId>logback-classic</artifactId>
  31. <version>1.1.7</version>
  32. <scope>provided</scope>
  33. </dependency>
  34. </dependencies>
  35. <properties>
  36. <java.version>1.8</java.version>
  37. </properties>
  38. <build>
  39. <plugins>
  40. <plugin>
  41. <groupId>org.springframework.boot</groupId>
  42. <artifactId>spring-boot-maven-plugin</artifactId>
  43. </plugin>
  44. </plugins>
  45. </build>
  46. <repositories>
  47. <repository>
  48. <id>spring-releases</id>
  49. <url>https://repo.spring.io/libs-release</url>
  50. </repository>
  51. </repositories>
  52. <pluginRepositories>
  53. <pluginRepository>
  54. <id>spring-releases</id>
  55. <url>https://repo.spring.io/libs-release</url>
  56. </pluginRepository>
  57. </pluginRepositories>
  58. </project>

6. 执行

在IntellJ中,可以直接在Application.java文件中右击鼠标,选择:
Run Application.main()
在控制台中出现如下日志,说明执行成功:

  1. . ____ _ __ _ _
  2. /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
  3. ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
  4. \\/ ___)| |_)| | | | | || (_| | ) ) ) )
  5. ' |____| .__|_| |_|_| |_\__, | / / / /
  6. =========|_|==============|___/=/_/_/_/
  7. :: Spring Boot :: (v1.4.0.RELEASE)
  8. 八月 12, 2016 5:47:50 下午 org.apache.catalina.core.StandardService startInternal
  9. INFO: Starting service Tomcat
  10. 八月 12, 2016 5:47:50 下午 org.apache.catalina.core.StandardEngine startInternal
  11. INFO: Starting Servlet Engine: Apache Tomcat/8.5.4
  12. 八月 12, 2016 5:47:51 下午 org.apache.catalina.core.ApplicationContext log
  13. INFO: Initializing Spring embedded WebApplicationContext

此时,服务器已经启动,可以访问http://localhost:8080/greeting,你会看到:

  1. {"id":1,"content":"Hello, World!"}

查询字符串中指定一个name参数,如http://localhost:8080/greeting?name=User。content的值从"Hello, World!"变为"Hello, User!":

  1. {"id":2,"content":"Hello, User!"}

这说明GreetingController类中的@RequestParam注解起作用了。name参数给定的默认值为"World",但是可以通过在查询字符串中设定值覆盖它。

注意id属性从1变为2。这表明你在多次请求中访问了同一个GreetingController实例,它的counter域每次访问时会自增1。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注