好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

feign调用返回object类型转换方式

feign调用返回object类型转换

引入依赖

?

1

2

3

4

5

< dependency >

      < groupId >com.fasterxml.jackson.core</ groupId >

      < artifactId >jackson-databind</ artifactId >

      < version >2.9.8</ version >

  </ dependency >

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

    /**

  * @Description: 将数据转换到相应的容器

  * @param bean

  * @param clazz

  * @return

  * @throws

  * @author dlh

  * @date 2019/3/19 10:28

  */

public static <T> T convertValue(Object bean, Class<T> clazz){

  try {

   ObjectMapper mapper = new ObjectMapper();

   return mapper.convertValue(bean, clazz);

  } catch (Exception e){

   logger.error( "错误的转换:BeanUtil.convertValue() --->" + e.getMessage());

   return null ;

  }

}

SpringCloud feign接口转换服务

Feign是通过提供面向接口操作的方式来替代RestTemplate API的Rest操作。

使用Feign

Feign这种技术应用在服务消费端

修改pom.xml配置文件,加入Feign的依赖包

?

1

2

3

4

< dependency >

     < groupId >org.springframework.cloud</ groupId >

     < artifactId >spring-cloud-starter-feign</ artifactId >

</ dependency >

由于Fegin是将Rest的操作转换成接口的形式,所以我们需要新建一个接口,并在接口上声明@FeignClient注解

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@FeignClient (value = "DEPT-PROVIDER" ,configuration = FeignClientConfig. class )

public interface DeptClientService {

     @RequestMapping (method= RequestMethod.GET,value= "/dept/get/{id}" )

     public Dept get( @PathVariable ( "id" ) long id) ;

     @RequestMapping (method=RequestMethod.GET,value= "/dept/list" )

     public List<Dept> list() ;

     @RequestMapping (method=RequestMethod.POST,value= "/dept/add" )

     public boolean add(Dept dept) ;

}

@Configuration

public class FeignClientConfig {

     @Bean

     public Logger.Level getFeignLoggerLevel() {

         return feign.Logger.Level.FULL ;

     }

     @Bean

     public BasicAuthRequestInterceptor getBasicAuthRequestInterceptor() {

         return new BasicAuthRequestInterceptor( "admin" , "admin" );

     }

}

其中configuration = FeignClientConfig.class不是必须的,将configuration属性去除仍然能work。

将之前的Rest操作的API,替换成面向DeptClientService接口的形式

?

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

@RestController

@RequestMapping ( "/consumer/dept" )

public class ConsumerDeptController {

     @Autowired

     private DeptClientService deptClientService;

     @RequestMapping (value = "/get" )

     public Dept get( long id) {

         return this .deptClientService.get(id);

     }

     @RequestMapping ( "/list" )

     public List<Dept> list(){

         return this .deptClientService.list();

     }

     @RequestMapping ( "/add" )

     public boolean add(Dept dept){

         return this .add(dept);

     }

/*

     public static final String DEPT_GET_URL = "http://DEPT-PROVIDER/dept/get/";

     public static final String DEPT_LIST_URL = "http://DEPT-PROVIDER/dept/list/";

     public static final String DEPT_ADD_URL = "http://DEPT-PROVIDER/dept/add";

     @Autowired

     private RestTemplate restTemplate;

     @Autowired

     private HttpHeaders httpHeaders;

     @Autowired

     private LoadBalancerClient loadBalancerClient;

     @RequestMapping(value = "/get")

     public Dept get(long id) {

         ServiceInstance serviceInstance = this.loadBalancerClient.choose("DEPT-PROVIDER") ;

         System.out.println(

                 "【*** ServiceInstance ***】host = " + serviceInstance.getHost()

                         + "、port = " + serviceInstance.getPort()

                         + "、serviceId = " + serviceInstance.getServiceId());

         //Dept dept = restTemplate.getForObject(DEPT_GET_URL + id, Dept.class);

         Dept dept = restTemplate.exchange(DEPT_GET_URL+id, HttpMethod.GET,new HttpEntity<Object>(this.httpHeaders),Dept.class).getBody();

         return dept;

     }

     @RequestMapping("/list")

     public List<Dept> list(){

         //List<Dept> deptList = restTemplate.getForObject(DEPT_LIST_URL, List.class);

         List<Dept> deptList = this.restTemplate.exchange(DEPT_LIST_URL,HttpMethod.GET,new HttpEntity<Object>(this.httpHeaders),List.class).getBody();

         return deptList;

     }

     @RequestMapping("/add")

     public boolean add(Dept dept){

         //Boolean flag = restTemplate.postForObject(DEPT_ADD_URL, dept, Boolean.class);

         Boolean flag = this.restTemplate.exchange(DEPT_ADD_URL,HttpMethod.POST,new HttpEntity<Object>(this.httpHeaders),Boolean.class).getBody();

         return flag;

     }*/

}

在启动类中加入@EnableFeignClients注解

?

1

2

3

4

5

6

7

8

@SpringBootApplication

@EnableEurekaClient

@EnableFeignClients (basePackages = { "cn.zgc.service" })

public class FeignConsumer_80_StartSpringCloudApplication {

     public static void main(String[] args) {

         SpringApplication.run(FeignConsumer_80_StartSpringCloudApplication. class ,args);

     }

}

Feign自带了负责均衡特性,所以使用Feign之后可以不用使用Ribbon。

Feign的配置

Feign 最重要的功能就是将 Rest 服务的信息转换为接口,但是在实际的使用之中也需要考虑到一些配置情况,例如:数据压缩, Rest 的核心本质在于: JSON 数据传输( XML、文本),于是就必须思考一种情况,万一用户发送的数据很大呢? 所以这个时候可以考虑修改application.yml 配置文件对传输数据进行压缩;

?

1

2

3

4

5

6

7

8

feign:

  compression:

  request:

  mime-types:  # 可以被压缩的类型

  - text/xml

  - application/xml

  - application/json

  min-request-size: 2048 # 超过2048的字节进行压缩

开启Feign的日志(默认是不开启的)

?

1

2

3

logging:

  level:

  cn.zgc.service: DEBUG

feign调用的时候返回参数不是期望的数据类型

今天碰到个坑,feign调用其他应用的时候反参并不是期望的类型;不知道这个在其他请求方式有没有这个bug

解决的方法

是在feign调用的那里指定Response<?>的泛型类,我这边是碰到期望是返回Long类型,但是返回的是Integer类型,不知道是不是隐式转换了,这里记录一下这个Bug

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

原文链接:https://blog.csdn.net/bpqdwo/article/details/94554009

查看更多关于feign调用返回object类型转换方式的详细内容...

  阅读:28次