The feign call returns the object type conversion mode

  • 2021-10-11 18:39:20
  • OfStack

The feign call returns an object type conversion

Introducing dependency


       <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>

    /**
  * @Description:  Convert the data to the appropriate container 
  * @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(" Wrong conversion: BeanUtil.convertValue() --->" + e.getMessage());
   return null;
  }
 }

SpringCloud feign Interface Translation Service

Feign is an Rest operation that replaces RestTemplate API by providing an interface-oriented operation.

Using Feign

Feign This technology is applied to the service consumer

Modify the pom. xml configuration file and add the dependency package of Feign


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

Since Fegin converts the operations of Rest into interfaces, we need to create a new interface and declare the @ FeignClient annotation on the interface


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

Where configuration = FeignClientConfig. class is not required, and work can still be achieved by removing configuration attribute.

Replace the API of the previous Rest operation with the form facing the DeptClientService interface


@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;
    }*/
}

Add @ EnableFeignClients annotation to startup class


@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 comes with a responsible equalization feature, so you can use Feign without using Ribbon.

Configuration of Feign

The most important function of Feign is to convert the information of Rest service into an interface, but in actual use, we also need to consider one configuration situation, such as data compression. The core essence of Rest lies in: JSON data transmission (XML, text), so we must think about one situation, and the data sent by 10,000 users is very large. Therefore, at this time, we can consider modifying the application. yml configuration file to compress the transmitted data;


feign:
 compression:
 request:
 mime-types:  #  Types that can be compressed 
 - text/xml
 - application/xml
 - application/json
 min-request-size: 2048 #  Exceed 2048 To compress the bytes of 

Turn on the log of Feign (it is not turned on by default)


logging:
 level:
 cn.zgc.service: DEBUG

When feign is called, the return parameter is not the expected data type

Today, I encountered a pit. When feign calls other applications, the anti-parameter is not the expected type; I don't know if this bug is available in other request methods

A solution

Response is specified where feign is called < ? > Generic class, my side is expected to return Long type, but returned Integer type, do not know if it is implicit conversion, here record 1 under this Bug


Related articles: