使用服務名
示例:
@Component
public class OrganizationRestTemplateClient {
@Autowired
RestTemplate restTemplate;
public Organization getOrganization(String organizationId){
ResponseEntity<Organization> restExchange =
restTemplate.exchange(
"http://organizationservice/v1/organizations/{organizationId}",
HttpMethod.GET,
null, Organization.class, organizationId);
return restExchange.getBody();
}
}
上面的示例中,遠程調(diào)用的 url 使用的不是一個確定的ip:port,而是organizationservice。其實這里的organizationservice代表的是眾多微服務spring.application.name=organizationservice的服務,真正的邏輯會對url進行解析,通過服務發(fā)現(xiàn)找到對應的服務實例集合中的一個實例的物理地址,然后發(fā)起真正的請求。
當然整個過程中還涉及到了負載均衡,目前為止默認使用的是 Netflix Ribbon。
Microservices - RestTemplate UnknownHostException
在發(fā)起請求的時候,如果使用的是服務名,而不是確定的物理地址,那么有可能出現(xiàn)UnknownHostException的異常,這是因為在注入RestTemplate的時候缺少注解@LoadBalance,該注解告知Spring Cloud創(chuàng)建一個基于Ribbon的RestTemplate,才可以實現(xiàn)客戶端負載均衡。
@SpringBootApplication
@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
返回結(jié)果是泛型
通常,我們都會將返回結(jié)果封裝成一個統(tǒng)一的ResponseWrapper,比如:
public class ResponseWrapper<T> {
private int code;
private String message;
private T data;
// 省略 getter、setter
}
那么,如果希望返回結(jié)果是ResponseWrapper<Organization>呢,要如何操作?
答案是,可以借助spring提供的org.springframework.core.ParameterizedTypeReference來實現(xiàn)。
實例:
@Component
public class OrganizationRestTemplateClient {
@Autowired
RestTemplate restTemplate;
public ResponseWrapper<Organization> getOrganization(String organizationId){
ResponseEntity<ResponseWrapper<Organization>> restExchange =
restTemplate.exchange(
serviceUri,
HttpMethod.GET,
null,
new ParameterizedTypeReference<ResponseWrapper<Organization>>(){},
organizationId);
return restExchange.getBody();
}
}
其中new ParameterizedTypeReference<ResponseWrapper<Organization>>(){}是匿名內(nèi)部類。
暫時先這么多,以后碰到其他的再補充。