RestTemplate 在 spring cloud 中的使用技巧

使用服务名

示例:

@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();
    }
}

上面的示例中,远程调用的 url 使用的不是一个确定的ip:port,而是organizationservice。其实这里的organizationservice代表的是众多微服务spring.application.name=organizationservice的服务,真正的逻辑会对url进行解析,通过服务发现找到对应的服务实例集合中的一个实例的物理地址,然后发起真正的请求。

当然整个过程中还涉及到了负载均衡,目前为止默认使用的是 Netflix Ribbon

Microservices - RestTemplate UnknownHostException

在发起请求的时候,如果使用的是服务名,而不是确定的物理地址,那么有可能出现UnknownHostException的异常,这是因为在注入RestTemplate的时候缺少注解@LoadBalance,该注解告知Spring Cloud创建一个基于Ribbon的RestTemplate,才可以实现客户端负载均衡。

@SpringBootApplication
@EnableDiscoveryClient
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
        @LoadBalanced
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

返回结果是泛型

通常,我们都会将返回结果封装成一个统一的ResponseWrapper,比如:

public class ResponseWrapper<T> {
    private int code;
    private String message;
    private T data;
    // 省略 getter、setter
}

那么,如果希望返回结果是ResponseWrapper<Organization>呢,要如何操作?
答案是,可以借助spring提供的org.springframework.core.ParameterizedTypeReference来实现。
实例:

@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>>(){}是匿名内部类。

暂时先这么多,以后碰到其他的再补充。

猜你喜欢

转载自blog.csdn.net/weixin_34054866/article/details/87159195