本博文和你一起使用SpringBoot和Maven快速搭建RESTful web Service。笔者当前IDE是idea。
1. 创建项目
在Idea
中创建新的maven
项目,在maven tab
下选择maven-archetype-quickstart
模板。
输入Maven
项目的坐标值,并选择存储路径。
2. 完善目录结构
通过Maven
模板生成的项目目录通常是不完整的,缺少resources
目录。我们手动添加两个目录,并分别标记为资源文件。
3. pom.xml文件配置
Maven
是非常优秀的jar
管理工具,通过pom.xml
引入依赖、插件,统一管理jar
包。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ac</groupId>
<artifactId>Demo</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Demo</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- 引入springboot依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<!-- 锁定插件版本,避免使用Maven默认版本 -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
其中,parent
标签提供父级依赖,spring-boot-starter-parent
为使用Maven
构建的应用程序提供依赖性和插件管理。
spring-boot-starter-web
,使用Spring MVC
构建Web
(包括RESTful
)应用程序的启动器,默认使用Tomcat
容器。
spring-boot-starter-test
,使用JUnit
,Hamcrest
和Mockito
等库来测试Spring Boot
应用程序的启动器。
Spring Boot Maven插件spring-boot-maven-plugin
提供了很多方便的特性。例如,它收集类路径上的所有jar
包,并构建一个可运行的jar
包集,方便执行和传输服务;搜索public static void main()
方法以标记为可运行的类;它提供了一个内置的依赖项解析器,可以设置版本号以匹配Spring Boot
依赖项。
4. 创建资源类
该服务将处理/greeting
的GET
请求,可选地在查询字符串中使用name
参数。请求会返回200 OK
响应,body
中JSON
报文表示内容,其中id
字段是greeting
的唯一标识,content
是greeting
的文本表示。
{
"id": 1,
"content": "Hello, World!"
}
我们需要创建资源表示类,来建模greeting
。下面我们提供一个POJO
,设置字段、构造器、访问方法。
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;
}
}
5. 创建controller
Spring
通过controller
来处理HTTP
请求。如下GreetingController
处理/greeting
的GET
请求,并返回一个Greeting
类的对象。
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
简洁而且简单,其内部隐藏了很多东西。
@RequestMapping
注解用于确保/greeting
的HTTP
请求能映射到greeting()
方法。案例中并没有指定具体的HTTP
方法,如GET、PUT、POST
。此时,默认采取@RequestMapping(method=GET)
映射所有HTTP
操作。
@RequestParam
注解用于绑定查询字符串参数name
到greeting()
方法的name
参数上。如果请求中name
参数缺失,使用默认值World
。
传统MVC
控制器和上面的RESTful Web
服务控制器之间的关键区别在于创建HTTP
响应主体的方式。 这个RESTful Web
服务控制器只是填充并返回一个Greeting
对象,而不是依靠视图技术使服务端greeting
数据呈现为HTML
。 对象数据将作为JSON
直接写入HTTP
响应。
代码中使用了Spring4
的新注解@RestController
,用于将类标记位控制器,其中每个方法返回一个域对象,而不是view
,是@Controller
和@ResponseBody
汇总在一起的简写。
6. 创建服务启动器
虽然可以将此服务打包为传统的WAR
文件以便部署到外部应用程序服务器,但下面演示以更简单的方法创建了一个独立的应用程序。 将所有内容打包在一个可执行的JAR
文件中,由Java main()
方法驱动。 在此过程中,使用Spring
的支持将Tomcat servle
t容器嵌入为HTTP
运行时,而不是部署到外部实例。
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
是组合注解,用于快捷配置启动类。注解上有7个注解,其中前4个是元注解,用于修饰当前注解,无实际功能。
@SpringBootConfiguration
继承自@Configuration
,声明当前类是一个配置类,相当于Spring
配置的xml
文件。
@EnableAutoConfiguration
作用是让Spring Boot
会根据类路径中的jar包依赖为当前项目进行自动设置。例如,如果spring-webmvc
位于类路径上,则会将应用程序标记为Web应用程序并激活关键行为,例如设置DispatcherServlet
。
@ComponentScan
告诉Spring
自动扫描包中使用@Service,@Component,@Repository,@Controller
的类,并注册为bean
。
main()
方法使用Spring Boot
的SpringApplication.run()
方法来启动应用程序。我们可以发现在整个过程中不需要配置任何XML
文件。
7. 测试服务
首先启动服务
访问 http://localhost:8080/greeting
,就可以得到如下结果。
{"id":1,"content":"Hello, World!"}
再次访问带上name
参数http://localhost:8080/greeting?name=User
,结果会改变为
{"id":2,"content":"Hello, User!"}
此时name
参数生效,显式覆盖默认值。id
属性由1改变为2。这证明在多个请求中针对相同的GreetingController
实例,并且其计数器字段在每次调用时按预期递增。
至此,我们已经搭建好一个RESTful web Service
。