启动一个Restful的web服务
本地启动一个
从git上下载一个用于示例的Restful Web项目
git clone https://github.com/spring-guides/quoters.git
然后运行
mvn spring-boot:run
这样可以在浏览器中访问
localhost:8080/api/random
返回的数据是
{"type":"success","value":{"id":7,"quote":"The real benefit of Boot, however, is that it's just Spring. That means any direction the code takes, regardless of complexity, I know it's a safe bet."}}
或使用数字1-10
localhost:8080/api/2
现在的目的是在自己的项目中调用这个api获取数据。
另建一个Spring Boot项目
定义数据类
根据api返回的json定义对应的Record类,使用JsonIgnoreProperties注解表示如果json中存在java类里没有字段与之对应的属性则忽略。
上面的json有两层结构,定义两个类
Value:
@JsonIgnoreProperties(ignoreUnknown = true)
public record Value(Long id, String quote) { }
Quoter:
@JsonIgnoreProperties(ignoreUnknown = true)
public record Quoter(String type,Value value){}
定义RestTemplate
直接在Application的主类中定义RestTemplate。这是Spring提供的一个类,它会把请求api返回的数据封装成实体类返回。
使用@bean注解注册到Spring的IoC容器中,RestTemplateBuilder实例是spring容器提供的。
package com.example.consuming_rest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumingRestApplication {
private static final Logger log = LoggerFactory.getLogger(ConsumingRestApplication.class);
public static void main(String[] args) {
SpringApplication.run(ConsumingRestApplication.class, args);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
@Profile("!test")
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quoter quote = restTemplate.getForObject(
"http://localhost:8080/api/random", Quoter.class);
log.info(quote.toString());
};
}
}
调用RestTemplate
用@Bean注册一个CommandLineRunner组件,
@Profile("!test")表示在非测试环境下执行
CommandLineRunner是一个函数式,方法中采用lambda表达式args ->{} 简写函数式。
CommandLineRunner会在Spring Boot启动后,接收请求前触发。
改端口启动
在application.propertites中
server.port=8081
然后启动该项目
在Controller中使用RestTemplate
package com.example.consuming_rest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class QuoterController {
@Value("${api.quoter-url}") // 注入配置值
private String sourceApi;
private final RestTemplate restTemplate;
public QuoterController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@GetMapping("/quoter")
public Quoter getQuoter(@RequestParam(value = "id",required=false) String id) {
String url=id==null?sourceApi+"random":sourceApi+id;
return restTemplate.getForObject(url, Quoter.class);
}
}
API的URL从配置文件获取
将api的url放在配置文件中:
# application.properties
server.port=8081
api.quoter-url=http://localhost:8080/api/
然后使用@Value注入。
使用参数构造自动注入
Spring4.3+之后,将要注入的Bean放在有参构造中,仅保留一个构造方法,Spring会自动注入,不用@AutoWired注解。