SpringBoot(二):构建RESTful Web服务

一.目的

这篇博客主要是简单讲一下如何使用SpringBoot来实现RESTful web service。什么是RESTful?就是一种设计风格,由一组架构约束条件和原则组成,从客户端到服务器的每个请求都必须包含理解请求所必需的信息。

看文字有点晦涩,但对程序员来说,看到代码一下就能明白了(毕竟上面比较专业的描述,都是百度来的)。

二.创建项目

上一章SpringBoot(一):创建第一个工程已经讲了如何快速的创建一个工程,基础配置同上。

项目配置好后,创建一个bean类,名字随意。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

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;
}
}

创建Controller类

1
2
3
4
5
6
7
8
9
10
11
12
13
14

@RestController
public class Controller {

private static final String template = "hello,%s!";
private static 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));
}

}
  • @RestController@ResponseBody@Controller的组合注解,可以直接返回json。

  • @RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。表示该类或者方法中的的响应请求都是以该地址作为父路径。在上面没有指定GET、PUT、POST等等,是因为@RequestMapping默认情况下是映射所有HTTP操作的,当然也可以使用@RequestMapping(method=GET)来指定是哪种请求。

  • @RequestParam 将查询字符串参数的值绑定到greeting()方法的name参数中,如果请求中不存在name参数,就默认使用“World”。

三.测试服务

启动服务,访问http:// localhost:8080 / greeting,其中显示:

{“id”:1,”content”:”hello, World!”}

使用http:// localhost:8080 / greeting?name = Leason,提供查询字符串参数:

{“id”:2,”content”:”hello,Leason!”}

四.请求第三方接口

使用SpringBoot提供https://gturnquist-quoters.cfapps.io/api/random 的接口。

创建一个实体类:Quote

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

public class Quote {
private String type;
private Object value;

public Quote() {
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public Object getValue() {
return value;
}

public void setValue(Object value) {
this.value = value;
}

@Override
public String toString() {
return "Quote{" +
"type='" + type + '\'' +
", value=" + value +
'}';
}
}

在我们之前创建的Controller类中,新建地址映射:

1
2
3
4
5
6
7

@RequestMapping("/quote")
public String getInfo() {
RestTemplate restTemplate = new RestTemplate();
Quote quote = restTemplate.getForObject("http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
return quote.toString();
}

然后访问http://localhost:8080/quote ,即可看到我们请求的结果

Quote{type=’success’, value={id=6, quote=It embraces convention over configuration, providing an experience on par with frameworks that excel at early stage development, such as Ruby on Rails.}}

这是主动调用得到的,如果需要程序自动请求并展示呢?可以使用Spring Boot来管理应用程序生命周期,找到根目录的Application文件,在其中配置RestTemplate,同时将它放到CommandLineRunner的回调中,以便在启动时由SpringBoot执行,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

//用于打印结果
private static final Logger log = LoggerFactory.getLogger(Application.class);

@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}

@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
}

这样,我们在运行程序的时候,就可以看到请求的结果(为了方便,就直接输出到console界面了):

2018-07-26 12:15:25.756 INFO 7260 — [ main] javafx.application.Application : Quote{type=’success’, value={id=6, quote=It embraces convention over configuration, providing an experience on par with frameworks that excel at early stage development, such as Ruby on Rails.}}

五.总结

SpringBoot的所有功能模块用起来都很方便配置,且并不仅仅局限于客户端的开发,也可以用于编写接口供其它程序使用。举个例子:有个需求是在一个页面做个定时任务,请其它3个系统的最新消息。则可以把请求这一步放到SpringBoot服务里来做,提供redis缓存,在需求页面上则每次只需调一个接口就行。

点击查看源码

参考资料