OpenFeign 各种用法、 logger 日志记录

<spring-cloud-openfeign.version>2.2.6.RELEASE</spring-cloud-openfeign.version>
对应的SpringBoot
<version>2.3.0.RELEASE</version>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>${spring-cloud-openfeign.version}</version>
    <exclusions>
        <exclusion>
            <artifactId>archaius-core</artifactId>
            <groupId>com.netflix.archaius</groupId>
        </exclusion>
    </exclusions>
</dependency>

 如果不在同一个 Module 中,需要添加 MapperScan

@ComponentScan(basePackages = {"com.iron"})
@SpringBootApplication
@EnableFeignClients(basePackages = {"com.iron.his"})
@MapperScan(basePackages ={"com.iron.his.mapper"} ) -- 如果两个MapperScan 就需要 classpath: 改成 classpath*
public class DefaultApplication { 
    public static void main(String[] args) {
        SpringApplication.run(VipSoftWebApplication.class, args);
    } 
}

 

日志记录

FeignConfig

package com.vipsoft.dingtalk.config;

import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FeignConfig {

    /**
     * Feign 的详细日志,配合yml使用
     *logging:
     *   level:
     *     # feign 日志以什么级别监控哪个接口
     *     com.vipsoft.ecgreport.sehedule.service: debug
     * @return
     */
    @Bean
    Logger.Level fegnLoggerLevel(){
        return Logger.Level.FULL;
    }
}

application.yml

server:
  application:
    name: VipSoft Dingtalk
  port: 8080
  servlet:
    context-path: /dingtalk
  tomcat:
    basedir: ./logs/
    background-processor-delay: 30
    redirect-context-root: true
    uri-encoding: UTF-8
    accesslog:
      enabled: true #为true时,上面的日期格式才有意义,否则就是写在一个文件里了
      buffered: true
      directory: ./logs
      file-date-format: .yyyy-MM-dd
      #pattern: '%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-Agent}i" %D ms'
      pattern: '%t %a %m %U %s %b %D ms'
      prefix: access_log
      rename-on-rotate: false
      request-attributes-enabled: false
      rotate: true
      suffix: .log

# 因为feign调试日志是debug级别输出,springboot默认的日志级别是info,所以feign的debug日志级别就不会输出
# logging.level=debug这样配置是对所有的日志级别进行配置
# 该场景只需要对feign接口进行debug配置,所以是这样配置logging.level.com.vipsoft.dingtalk.rpc=debug
logging:
   level:
     # feign 日志以什么级别监控哪个接口
     com.vipsoft.dingtalk.rpc: debug

dingtalk:
  rebot-url: https://oapi.dingtalk.com

 

简单调用

//定义一个拦截器
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("AppId", "AppId");
        requestTemplate.header("AppKey", "myuser1");
        requestTemplate.header("AppSecret", "mypassword");
    }
}


//接口类
@Component
@FeignClient(name = "demo-feign",
        url = "https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/",
        configuration = FeignInterceptor.class)
public interface IFeignTestService {

    @GetMapping(value = "/GetUser")
    String getUser(@RequestBody String words);

}


//调用
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FeignTests {
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IFeignTestService feignTestService;

    @Test
    void searchTest() {
        String result = feignTestService.getUser("VipSoft");
        logger.info(result);

    }

}

 

OpenFeign 动态URL

//定义一个拦截器
public class FeignInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate requestTemplate) {
        requestTemplate.header("AppId", "AppId");
        requestTemplate.header("AppKey", "myuser1");
        requestTemplate.header("AppSecret", "mypassword");
    }
}


//接口类
@Component
@FeignClient(name = "demo-feign",
        url = "url必须有值,这里随便写,但不能为空",
        configuration = FeignInterceptor.class)
public interface IFeignTestService {

    @PostMapping("/")
    String getWebsite(URI uri, @RequestBody String words); 
}


//调用
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FeignTests {
    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IFeignTestService feignTestService;

    @Test
    void searchTest() {
       String ss1 = feignTestService.getWebsite(new URI("https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/GetUser"), "");
        logger.error(ss1);
        String ss2 = feignTestService.getWebsite(new URI("https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/hospital"), "");
        logger.error(ss2);
        String ss3 = feignTestService.getWebsite(new URI("https://www.fastmock.site/mock/e5738f58a04967320a772f1d69aa4a41/mp/device"), "");
        logger.error(ss3); 
    }

}

 OpenFeign  application/x-www-form-urlencoded

@Test
void queryOrderTest() { 
    MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
    param.add("msg_type", "GUOGUO_QUERY_SEND_SERVICE_DETAIL");
    param.add("logistic_provider_id", "123456"); 
    param.add("data_digest", "def");
    param.add("logistics_interface", "abc");
    String result = cainiaoService.querySendServiceDetail(param);
    logger.info(PojoUtil.pojoToJson(param));
    logger.info(result);
}

 
@Component
@FeignClient(name = "feign-cainiao", url = "${cainiao.url}")
public interface IFeignCainiaoService {
  
    /**
     * 获取三期API接口
     *
     * @param bodyParam AppId、PageIndex、PageSize
     * @return
     */
    @PostMapping(headers = {"content-type=application/x-www-form-urlencoded"})
    String querySendServiceDetail(@RequestBody MultiValueMap<String, Object> bodyParam);
}

 OpenFeign 自定义配置

//接口类
@Component
@FeignClient(name = "demo-feign",
        url = "url必须有值,这里随便写,但不能为空",
        configuration = IFeignTestService.MultipartSupportConfig.class)
public interface IFeignTestService {
    //写接口内部,这样可以高内聚
    class MultipartSupportConfig {

        @Autowired
        private ObjectFactory<HttpMessageConverters> messageConverters;

        @Bean
        public Encoder feignFormEncoder() {
            return new SpringFormEncoder(new SpringEncoder(messageConverters));
        }
    }

    @PostMapping("/")
    String getWebsite(URI uri, @RequestBody String words); 
}

 


 

传 Header、URL 参数

/**
 * 发送预警信息 
 * @return
 */
@PostMapping(value = "/")
String sendMessage(@RequestHeader Map<String, Object> headerParam, @RequestBody RobotMessage param);

/**
 * 发送预警信息 
 * @return
 */
@PostMapping(value = "/robot/send")
String sendMessage(@RequestParam Map<String, Object> headerParam, @RequestBody RobotMessage param);

 

上传文件

@FeignClient(name = "vipsoft", url = "${api.url}")
public interface ICallbackFeignService {
    /**
     * 上传文件
     *
     * 注意: 使用openfeign传递参数含有文件类型时必须指定 consumes = MediaType.MULTIPART_FORM_DATA_VALUE*
     * @return
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    String upload(@RequestPart("file") MultipartFile file);

}    




package com.vipsoft.web;

import com.vipsoft.web.rpc.ICallbackFeignService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;

@SpringBootTest
public class AppCallbackTest {

    @Autowired
    ICallbackFeignService appCallbackFeignService;

    @Test
    void Upload() throws Exception {

        File file = new File("D:\\Users\\Desktop\\fanye.mp4");
        //这里的第一个参数值 file 是对应上面feign的文件注解中的@RequestPar中的name。一定要对应上
        MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), "application/octet-stream;charset=utf-8", new FileInputStream(file));
        appCallbackFeignService.upload(multipartFile);
    }
}

 

posted @ 2021-05-28 16:30  VipSoft  阅读(958)  评论(0编辑  收藏  举报