RestTemplate&Feign

为什么要用springcloud呢?

springcloud中这么多个微服务,每个微服务都是用的http协议去互相调用的,里都有很多的接口,需要其他的微服务硬编码到代码中,这样不是每次修改都要改其他调用这个接口的其他微服务吗?

我觉得

  1. 首先,spring的生态的强大是我们用springcloud的一点原因。
  2. 然后我们每个微服务就算用不同语言也可以互相调用,因为用的是http协议。
  3. 最后就是灵活,怎么说呢?微服务直接用的http协议进行互相调用,http又是无状态的,我们经常对于同一个微服务进行集群扩展(提供同样的服务),那我们调用者服务对这个微服务集群进行调用,这个集群中的服务可以灵活的上下线也不会影响到调用方。

所以接下来总结一下springcloud微服务直接怎么调用

RestTemplate

在上一篇文章中eureka的文章中,我们注入了RestTemplate对象,传入url和responseType,就可以调用相关服务的接口,并且返回信息后自动帮我们转换成我们需要的responseType的类型。

我们的RestTemplate对象是单例的,所以我们可以写一个RestTemplateConfiguration的类,然后把RestTemplate对象注册到springioc容器中。@LoadBalanced可以实现负载均衡

@Configuration
public class RestTemplateConfiguration {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        return restTemplate;
    }
}

RestTemplate还有一个拦截器,可以拦截请求发出和请求返回,我们先新建一个类HttpRequestInterceptor 并且实现ClientHttpRequestInterceptr接口 ,如图

public class HttpRequestInterceptor implements ClientHttpRequestInterceptor {
    @Override
    public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {

        System.out.println("拦截到啦");
        System.out.println(httpRequest.getURI());
        ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest,bytes);
        System.out.println(response.getHeaders());

        return response;
    }
}

然后再我们的RestTemplate配置类里加上我们的拦截器对象

@Configuration
public class RestTemplateConfiguration {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add(new HttpRequestInterceptor());
        return restTemplate;
    }
}

 当我们用RestTemplate调用服务时,就会到我们的拦截其中,被拦截到。

Feign

Feign本身不支持springMVC的注解

OpenFeign是springcloud在Feign的基础上支持springMVC的注解

OpenFeign的@FeignClient可以解析springMVC的@RequestMapping注解下的接口,通过动态代理产生实现类,在实现类中做负载均衡并调用其他服务。

首先我们建一个微服务,user-provider,引入spring-web和eruekaClient依赖

先配置好user-provider的properties


server.port=82

spring.application.name=user-provider

#这里的地址是provider去寻找服务的地址和端口
eureka.client.service-url.defaultZone=http://eureka1.com:7001/eureka/

在user-provider中写一个controller服务

@RestController
public class UserProviderController {

    @GetMapping("/alive")
    public  String alive(){
        return "ok";
    }
}

当然还有建一个微服务,user-consumer,引入spring-web和eruekaClient还有openfeign的依赖

先配置好user-consumer的properties


server.port=83

spring.application.name=user-consumer

#这里的地址是provider去寻找服务的地址和端口
eureka.client.service-url.defaultZone=http://eureka1.com:7001/eureka/

在user-consumer服务的项目入口,加上注解

@SpringBootApplication
@EnableFeignClients
public class UserConsumerApplication {

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

}

 然后我们可以在user-consumer中新建一个接口,FeignClient可以吧url和GetMapping进行拼接

//这里name是eureka里的服务名
@FeignClient(name = "user-provider")
public interface UserAPI {

    @GetMapping("/alive")
    public String alive();
}

 然后我们写一个user-consumer的controller服务

@RestController
public class UserConsumerController {

    @Autowired
    UserAPI userAPI;

    @GetMapping("/alive")
    public  String alive(){
        return userAPI.alive();
    }
}

这样也可以调用成功!!! 

会发现以上这种方式和restTemplate一样,需要provider写一个接口文档,如果只是java与java,可以用一下方法。

首先可以先起个接口项目,引入spring-web引用

写一个Api接口

@RequestMapping("/User")
public interface Api {

    @GetMapping("/alive")
    public String alive();
}

然后用maven打包

然后user-consumer引入打包好的maven项目

<!--引入自定义的api-->
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>user-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

然后user-consumer就只需要继承这个引入的api

//这里name是eureka里的服务名
@FeignClient(name = "user-provider")
public interface UserAPI extends ProviderApi {
    
}

然后controller就可以直接用啦。然后user-provider的controller也可以同样的引入这个jar包,然后实现这个接口,就可以重写这个接口啦,这样做就可以只修改这个独立的接口项目,对于服务提供者和服务调用者都可以去根据这个接口实现业务代码,一个接口就可以规范两边的服务去实现或者调用,就很棒 !!!!!!!!!!!!!!!!!!!!!!!!

提醒:因为Feign底层是根据注解去获取服务名,还有拼接url,注意还有参数,所以我们的api,里面的参数必须加@RequestParam("xx"),不然的话会无法调通接口,中间的api里的所有注解都是给Feign提供的,Resolved[org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not supported]

@RequestMapping("/user")
public interface ProviderApi {

    @GetMapping("/alive")
    public String alive();

    @GetMapping("/getMapById")
    public HashMap getMapById(@RequestParam("id") Integer id);
}

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值