SpringCloud 利用 RestTemplate 或 Feign 发起http请求 请求服务提供者的接口

目录

1,注册RestTemplate

2,服务远程调用 RestTemplate

3,RestTemplate常用方法:

3.1 Get请求之getForObject。以JSON形式自动化转换responseType指定返回类型

3.2 POST之postForObject

3.3 exchange自定义请求方式

一,使用Feign的步骤

二 自定义Feign的配置

三 Feign的性能优化

四 Feign的最佳使用方案

方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。

方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用

五 总结:

RestTemplate方式与 feign 方式的对比


1,注册RestTemplate

    /**
     * 创建RestTemplate并注入Spring容器
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

2,服务远程调用 RestTemplate

    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.利用RestTemplate发起http请求,查询用户
        // 2.1.url路径
        String url = "http://localhost:10086/user/" + order.getUserId();
        // 2.2.发送http get请求请求,实现远程调用
        User user = restTemplate.getForObject(url, User.class);
        // 3.封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }

3,RestTemplate常用方法:

3.1 Get请求之getForObject。以JSON形式自动化转换responseType指定返回类型

//Get请求之getForObject。以JSON形式自动化转换responseType指定返回类型。
  
url:请求地址
responseType:返回值类型 结果转换后的对象
uriVariables:携带参数
//方法1
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables){},

JSONObject results = restTemplate.getForObject(BASE_URL + "/get1/{1}/{2}",JSONObject.class,"条件1", "条件2");

//方法2
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables)

    Map<String, String> map = new HashMap();
	map.put("id", "100");
	map.put("name", "名字1");
	JSONObject results = restTemplate.getForObject(BASE_URL + "/get2?id={id}&name={name}", JSONObject.class, map);


//方法3
public <T> T getForObject(URI url, Class<T> responseType)

String results = restTemplate.getForObject(BASE_URL + "/条件1/条件2", String.class);




3.2 POST之postForObject

POST之postForObject。
 
url:请求地址
request参数可以是aHttpEntity以便向请求中添加其他HTTP标头。
responseType:返回值类型 结果转换后的对象
uriVariables:动态URL
public <T> postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
public <T> postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables)
public <T> postForObject(URI url, @Nullable Object request, Class<T> responseType,  responseType)


3.3 exchange自定义请求方式

exchange()可以指定HttpMethod,请求体requestEntity。
 
@Test
void get1() {
	//设置请求头
	HttpHeaders headers = new HttpHeaders();
	headers.setContentType(MediaType.APPLICATION_JSON);
	//body参数
	Map<String, String> map = new HashMap<>();
	map.put("id", "1");
	map.put("name", "动次打次打次打");
	HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(map, headers);
	//exchange 自定义
	ResponseEntity<String> result = restTemplate.exchange(BASE_URL + "/post1", HttpMethod.POST, httpEntity, String.class);
	logger.info(result.getBody());
}



一,使用Feign的步骤

Feign介绍: Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign

1,引入依赖

<dependency>    
    <groupId>org.springframework.cloud</groupId>    
    <artifactId>spring-cloud-starter-openfeign</artifactId> 
</dependency>

2,在服务启动类里添加注解开启Feign的功能(@EnableFeignClients())

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {

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

3 编写Feign客户端

@FeignClient("userservice")
public interface UserClient {    
    @GetMapping("/user/{id}")     
    User findById(@PathVariable("id") Long id);
}

主要是基于SpringMVC的注解来声明远程调用的信息,比如:

服务名称:userservice

请求方式:GET

请求路径:/user/{id}

请求参数:Long id

返回值类型:User

4 调用Feign客户端

    @Autowired
    private UserClient userClient;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.用Feign远程调用
        User user = userClient.findById(order.getUserId());
        // 3.封装user到Order
        order.setUser(user);
        // 4.返回
        return order;
    }

二 自定义Feign的配置

FFeign运行自定义配置来覆盖默认配置,可以修改的配置如下:

类型

作用

说明

feign.Logger.Level

修改日志级别

包含四种不同的级别:NONE、BASIC、

HEADERS、FULL

feign.codec.Decoder

响应结果的解析器

http远程调用的结果做解析,例如解析

json字符串为java对象

feign.codec.Encoder

请求参数编码

将请求参数编码,便于通过http请求发送

feign. Contract

支持的注解格式

默认是SpringMVC的注解

feign. Retryer

失败重试机制

请求失败的重试机制,默认是没有,不过

会使用Ribbon的重试

配置Feign日志有两种方式

1,配置文件方式

  1.1 全局生效:

feign:  
    client:    
        config:      
            default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置(请求该服务的时候) 
               loggerLevel: FULL #  日志级别 

1.2 局部生效:

feign:  
    client:    
        config:       
            userservice: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置(请求该服务的时候的配置) 
                loggerLevel: FULL #  日志级别 

2,java代码方式,需要先声明一个Bean

public class FeignClientConfiguration {    
    @Bean    
    public Logger.Level feignLogLevel(){        
        return Logger.Level.BASIC;     
    }
}

2.1 如果是全局配置,则把它放到启动类的@EnableFeignClients这个注解中

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients(defaultConfiguration = FeignClientConfiguration.class)
public class OrderApplication {

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

2.2 如果是局部配置,则把它放到声明请求的类 @FeignClient这个注解中

@FeignClient(value = "userservice", configuration = FeignClientConfiguration.class)
public interface UserClient {

    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

三 Feign的性能优化

Feign底层的客户端实现:

        URLConnection:默认实现,不支持连接池

        Apache HttpClient :支持连接池

        OKHttp:支持连接池

因此优化Feign的性能主要包括:

        使用连接池代替默认的URLConnection

        日志级别,最好用basic或none

1,Feign的性能优化-连接池配置

1.1 添加HttpClient的依赖

<!--httpClient的依赖 -->
<dependency>    
    <groupId>io.github.openfeign</groupId>    
    <artifactId>feign-httpclient</artifactId>
</dependency>

1.2 配置连接池:

feign:  
    client:    
        config:      
            default: # default全局的配置        
                loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息   
    httpclient:    
        enabled: true # 开启feign对HttpClient的支持    
        max-connections: 200 # 最大的连接数    
        max-connections-per-route: 50 # 每个路径的最大连接数

四 Feign的最佳使用方案

方式一(继承):给消费者的FeignClient和提供者的controller定义统一的父接口作为标准。

只是提供一种思路(但不建议 因为这样继承会造成服务耦合)

方式二(抽取):将FeignClient抽取为独立模块,并且把接口有关的POJO、默认的Feign配置都放到这个模块中,提供给所有消费者使用

推荐使用该方案

实例:抽取FeignClient

1.首先创建一个module,命名为feign-api,然后引入feign的starter依赖

2.将order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api     项目中

3.在order-service中引入feign-api的依赖

4.修改order-service中的所有与上述三个组件有关的import部分,改成导入feign-api中的包

5.重启测试

会发现找不到 UserClient 的bean 因为order-service里 默认只扫描order-service里的包 不会扫描feign-api里的包 所以无法将 UserClient 注入spring容器里

有两种方式解决:

方式一:指定FeignClient所在包  @EnableFeignClients(basePackages= "cn.itcast.feign.clients")

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients(basePackages= "cn.itcast.feign.clients",defaultConfiguration = FeignClientConfiguration.class)
public class OrderApplication {

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

方式二:指定FeignClient字节码  @EnableFeignClients(clients = UserClient.class)

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
@EnableFeignClients(clients = UserClient.class,defaultConfiguration = FeignClientConfiguration.class)
public class OrderApplication {

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

五 总结:

RestTemplate方式与 feign 方式的对比

RestTemplate代码可读性差,编程体验不统一

RestTemplate参数复杂URL难以维护

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值