上一篇文章中已经讲述 Feign的基本用法,本章主要概述 FeignClient GET/POST/PUT/DELETE restful写法以及 Feign 拦截器,与配置优化方案,关闭HttpClient开启OKHTTP…

- 准备工作

1.启动Consul,所有文章都将以Consul作为服务注册中心

2.创建 battcn-feign-hello,battcn-feign-hi(本文代码基于上篇改造)

3.服务(Hi)-> FeignClient -> 服务(Hello),通过实现 RequestInterceptor 传递 header 信息

- battcn-feign-hello

- pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

- BattcnFeignHelloApplication.java

1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableDiscoveryClient
public class BattcnFeignHelloApplication { public static void main(String[] args) {
SpringApplication.run(BattcnFeignHelloApplication.class, args);
}
}

- Student.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Student {

    private Long id;
private String name;
private String email; //...get set
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
public Student(){}
public Student(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
}

- HelloController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@RestController
@RequestMapping("/hello")
public class HelloController { @Autowired
HttpServletRequest request; static Logger LOGGER = LoggerFactory.getLogger(HelloController.class); @ResponseStatus(HttpStatus.OK)
@GetMapping
public Student findStudentByName(@RequestParam("name") String name,@RequestHeader(name = "token",required = false)) {
// TODO:不做具体代码实现,只打印Log
LOGGER.info("[查询参数] - [{}]", name);
LOGGER.info("[Token] - [{}]",token);
LOGGER.info("[Auth] - [{}]",request.getHeader("Auth"));
return new Student(1L,"挽歌-GET","1837307557@qq.com");
} @ResponseStatus(HttpStatus.CREATED)
@PostMapping
public Student addStudent(@RequestBody Student student) {
// TODO:不做具体代码实现,只打印Log
LOGGER.info("[添加信息] - [{}]", student.toString());
return new Student(2L,"挽歌-SAVA","1837307557@qq.com");
} @ResponseStatus(HttpStatus.CREATED)
@PutMapping("/{studentId}")
public Student editStudent(@RequestBody Student student, @PathVariable("studentId") Long studentId) {
// TODO:不做具体代码实现,只打印Log
LOGGER.info("[修改信息] - [{}]", student.toString());
return new Student(3L,"挽歌-EDIT","1837307557@qq.com");
} @ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/{studentId}")
public void deleteStudent(@PathVariable("studentId") Long studentId) {
// TODO:不做具体代码实现,只打印Log
LOGGER.info("[根据编号删除学生] - [{}]", studentId);
}
}

- bootstrap.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server:
port: 8765 spring:
application:
name: battcn-feign-hello
cloud:
consul:
host: localhost
port: 8500
enabled: true
discovery:
enabled: true
prefer-ip-address: true

- 测试

访问:http://localhost:8765/hello?name=Levin

显示:{"id":1,"name":"挽歌-GET","email":"1837307557@qq.com"} 代表我们服务启动成功

- battcn-feign-hi

- pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<dependencies>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.battcn</groupId>
<artifactId>battcn-starter-swagger</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

- BattcnFeignHiApplication.java

1
2
3
4
5
6
7
8
9
10
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class BattcnFeignHiApplication { public static void main(String[] args) {
SpringApplication.run(BattcnFeignHiApplication.class, args);
} }

- HiController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@RestController
@RequestMapping("/hi")
public class HiController { static Logger LOGGER = LoggerFactory.getLogger(HiController.class); @Autowired
HelloClient helloClient; @ResponseStatus(HttpStatus.OK)
@GetMapping
public Student find(@RequestParam("name") String name,@RequestHeader(name="token",required = false)String token) {
// TODO:只是演示Feign调用的方法
LOGGER.info("[Token] - [{}]",token);
return helloClient.findStudentByName(name,token);
} @ResponseStatus(HttpStatus.CREATED)
@PostMapping
public Student add(@RequestBody Student student) {
// TODO:只是演示Feign调用的方法
return helloClient.addStudent(student);
} @ResponseStatus(HttpStatus.CREATED)
@PutMapping("/{studentId}")
public Student edit(@RequestBody Student student, @PathVariable("studentId") Long studentId) {
// TODO:只是演示Feign调用的方法
return helloClient.editStudent(student, studentId);
} @ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/{studentId}")
public void delete(@PathVariable("studentId") Long studentId) {
// TODO:只是演示Feign调用的方法
helloClient.deleteStudent(studentId);
}
}

- MyFeignInterceptor.java

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 传递Token
* @author Levin
* @date 2017-07-29.
*/
@Configuration
public class MyFeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("Auth","My Name's request header Auth");
}
}

- HelloClient.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.battcn.client;

import com.battcn.pojo.Student;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*; /**
* 模拟完整的CRUD操作
*/
@FeignClient(name = "battcn-feign-hello")
public interface HelloClient { @ResponseStatus(HttpStatus.OK)
@GetMapping("/hello")
Student findStudentByName(@RequestParam("name") String name,@RequestHeader(name="token",required = false)String token); @ResponseStatus(HttpStatus.CREATED)
@PostMapping("/hello")
Student addStudent(@RequestBody Student student); @ResponseStatus(HttpStatus.CREATED)
@PutMapping("/hello/{studentId}")
Student editStudent(@RequestBody Student student, @PathVariable("studentId") Long studentId); @ResponseStatus(HttpStatus.NO_CONTENT)
@DeleteMapping("/hello/{studentId}")
void deleteStudent(@PathVariable("studentId") Long studentId);
}

- bootstrap.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
server:
port: 8766 spring:
application:
name: battcn-feign-hi
cloud:
consul:
host: localhost
port: 8500
enabled: true
discovery:
enabled: true
prefer-ip-address: true #Hystrix支持,如果为true,hystrix库必须在classpath中
feign:
okhttp:
enabled: true #开启OKHTTP支持,依赖 (feign-okhttp)默认HttpClient
#请求和响应GZIP压缩支持
compression:
request:
enabled: true
#支持压缩的mime types
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
response:
enabled: true
hystrix:
enabled=false
# 日志支持
logging:
level:
project.com.battcn.UserClient: DEBUG #以下就是需要写的配置,注意base-package就可以了
swagger:
enable: true #是否开启Swagger
api-info:
description: ${spring.application.name}
license: ${spring.application.name}
license-url: http://blog.battcn.com
terms-of-service-url: http://blog.battcn.com
title: 鏖战八方
version: "@project.version@"
contact:
email: 1837307557@qq.com
name: 挽歌
url: http://blog.battcn.com
docket:
base-package: com.battcn.controller #扫描路径,建议以Controller的父包为主
group-name: ${spring.application.name}

- 测试

访问:http://localhost:8766/swagger-ui.html

使用Swagger做测试

swagger测试

此处只演示GET,PUT,DELETE,POST 示例代码都包括,自行测试即可

日志:

1
2
3
2017-07-29 18:21:26.854  INFO 12620 --- [nio-8765-exec-2] com.battcn.controller.HelloController    : [查询参数] - [Levin]
2017-07-29 18:21:26.854 INFO 12620 --- [nio-8765-exec-2] com.battcn.controller.HelloController : [Token] - [Token HA]
2017-07-29 18:21:26.854 INFO 12620 --- [nio-8765-exec-2] com.battcn.controller.HelloController : [Auth] - [My Name's request header Auth]

如果未实现 RequestInterceptor 那么 LOGGER.info("[Auth] - [{}]",request.getHeader("Auth")); 就无法获取到 request 中的信息

- 流程图

画图工具:https://www.processon.com/

流程图

服务消费者(Feign-下)的更多相关文章

  1. SpringCloud学习系列之二 ----- 服务消费者(Feign)和负载均衡(Ribbon)使用详解

    前言 本篇主要介绍的是SpringCloud中的服务消费者(Feign)和负载均衡(Ribbon)功能的实现以及使用Feign结合Ribbon实现负载均衡. SpringCloud Feign Fei ...

  2. SpringCloud-创建服务消费者-Feign方式(附代码下载)

    场景 SpringCloud-服务注册与实现-Eureka创建服务注册中心(附源码下载): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  3. Spring Cloud学习笔记【三】服务消费者Feign

    Feign 是一个声明式的 Web Service 客户端,它的目的就是让 Web Service 调用更加简单.它整合了 Ribbon 和 Hystrix,从而让我们不再需要显式地使用这两个组件.F ...

  4. 创建服务消费者(Feign)

    概述 Feign 是一个声明式的伪 Http 客户端,它使得写 Http 客户端变得更简单.使用 Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用 Feign 注解和 JAX-RS ...

  5. Spring Cloud(四)服务提供者 Eureka + 服务消费者 Feign

    上一篇文章,讲述了如何通过RestTemplate + Ribbon去消费服务,这篇文章主要讲述如何通过Feign去消费服务. Feign简介 Feign是一个声明式的伪Http客户端,它使得写Htt ...

  6. 服务消费者Feign和Ribbon的区别

    1.Ribbon通过注解@EnableEurekaClient/@EnableDiscoveryClient向服务中心注册:    PS:选用的注册中心是eureka,那么就推荐@EnableEure ...

  7. 一起来学Spring Cloud | 第四章:服务消费者 ( Feign )

    上一章节,讲解了SpringCloud如何通过RestTemplate+Ribbon去负载均衡消费服务,本章主要讲述如何通过Feign去消费服务. 一.Feign 简介: Feign是一个便利的res ...

  8. Spring Cloud (4) 服务消费者-Feign

    Spring Cloud Feign Spring Cloud Feign 是一套基于Netflix Feign实现的声明式服务调用客户端.它使得编写Web服务客户端变得更加简单,我们只需要创建接口并 ...

  9. 8、服务发现&服务消费者Feign

    spring cloud的Netflix中提供了两个组件实现软负载均衡调用,分别是Ribbon和Feign.上一篇和大家一起学习了Ribbon. Ribbon :Spring Cloud Ribbon ...

  10. 玩转SpringCloud(F版本) 二.服务消费者(2)feign

    上一篇博客讲解了服务消费者的ribbon+restTemplate模式的搭建,此篇文章将要讲解服务消费者feign模式的搭建,这里是为了普及知识 平时的项目中两种消费模式选择其一即可 本篇博客基于博客 ...

随机推荐

  1. Java实现LeetCode 111. Minimum Depth of Binary Tree

    /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * Tre ...

  2. iOS-PCH File的快速导入方法和使用

    PCH的文件的用途:      在实际的项目开发中,如果很多地方都在使用某个类的头文件,很多地方都在使用同一个”宏”的时候:很多地方用到了NSLog()函数, 在app发布的时候,想清除掉时,此时就需 ...

  3. Linux RTC设备驱动

    1. 在Linux2.6.29内核中,RTC是以平台设备的方式注册进内核的. ① RTC驱动定义于文件:drivers/rtc/rtc-s3c.c static struct platform_dri ...

  4. MySQL进阶篇(02):索引体系划分,B-Tree结构说明

    本文源码:GitHub·点这里 || GitEE·点这里 一.索引简介 1.基本概念 首先要明确索引是什么:索引是一种数据结构,数据结构是计算机存储.组织数据的方式,是指相互之间存在一种或多种特定关系 ...

  5. monkey命令的基本使用

    看到monkey,你想到了什么?今天给大家分享下monkey命令的基本使用 monkey测试是Android平台自动化测试的一种手段,通过monkey程序模拟用户触摸屏幕,滑动.按键操作等操作对设备上 ...

  6. Vue-websocket使用

    Vue中使用websocket 1.介绍:websocket是一个双向通行工具,解决了原来的http单向通信的弊端,可以让服务器主动向客户端推送数据 // 安装客户端的socket npm i soc ...

  7. 君荣 TS--8200 消费机显示说明

     Err 001——不在消费时段内Err 002——非本系统卡Err 003——余额不足Err 004——级别未开放Err 005——卡已挂失Err 006——有效期未生效Err 007——已过有效期 ...

  8. yii2中的场景使用

    下面给大家介绍一下 yii2.0 场景的使用.小伙多唠叨一下了,就是担心有的人还不知道,举个简单的例子,现在在 post表里面有 title image content 三个的字段,当我创建一个 po ...

  9. centos7下docker的安装教程

    Centos7下docker安装教程以及踩过的那些坑 推荐在Centos下安装docker,在windows下安装docker可能会遇到很多的问题,而且docker官方推荐使用linux环境来使用do ...

  10. python实现装饰器

    #编写一个装饰器 def zs(x): def h(): return ""+x() return h @zs def hhh(): return "你好" p ...