首页 > 其他分享 >openfeign应用汇总(二)

openfeign应用汇总(二)

时间:2023-08-07 21:45:49浏览次数:31  
标签:feign openfeign 汇总 auth header 应用 import RequestInterceptor public

openfeign应用汇总(二)

1、开启feign日志

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import feign.Logger;
import feign.codec.Decoder;
import feign.codec.ErrorDecoder;
@Configuration
public class FeignClientConfiguration{
	@Bean
	public Logger.Level feignLogLevel(){
		// 配置日志级别
		return Logger.Level.FULL;
	}
	@Bean
	public Decoder feignDefDecoder() {
		return new FeignResultDecoder();
	}
	@Bean
	public ErrorDecoder feignErrorDecoder() {
		return new FeignErrorDecoder();
	}
}
配置文件形式配置
feign: client: config: default: #此处写的是服务名称,针对我们feign微服务的配置,如果是default就是全局配置 loggerLevel: FULL #配置Feign的日志级别,相当于代码配置方式中的Logger
日志级别 打印内容
NONE(默认 不记录任何日志
BASIC 仅记录请求方法、URL、响应状态码以及执行时间(适合生产)
HEADERS 记录BASIC基础上,记录请求和响应的header
FULL   记录请求和响应header、body和元数据

2、openfeign设置header的5种方式

  • 在@RequestMapping注解里添加headers属性
  • 在方法参数前面添加@RequestHeader注解
  • 在方法或者类上添加@Headers的注解
  • 在方法参数前面添加@HeaderMap注解
  • 实现RequestInterceptor接口
@PostMapping(value = "/weixin/api", headers = {"Content-Type=application/json;charset=UTF-8", "App-Secret=${app.secret}"})
void saveUser(@RequestBody User user);
@GetMapping(value = "/getUser")
public User getUser(@RequestBody User user, @RequestHeader("Authorization") String token);
 ###设置多个headers
1@PostMapping(value = "/getUser") 2 public User getUser(@RequestBody User user, @RequestHeader MultiValueMap<String, String> headers);
@FeignClient(url = "${user.api.url}", name = "user", configuration = FeignClientConfiguration.class)
public interface UserFeignClient {
    @RequestLine("GET /{id}")
    @Headers({"Content-Type: application/json;charset=UTF-8", "Authorization: {token}"})
    public User findById(@Param("id") String id, @Param("token") String token);
}

###使用feign自带契约 ####@Headers不起作用,其实@Headers注解没有生效的原因是:官方的Contract没有生效 #####
@Configuration
public class Configuration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }
}
###使用feign自带契约 
@FeignClient(url = "${user.api.url}", name = "user", configuration = FeignClientConfiguration.class)
public interface UserFeignClient {
    @RequestLine("GET /{id}")
    public User findById(@Param("id") String id, @HeaderMap HttpHeaders headers);
}
@Configuration
public class FeignRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        template.header("Authorization", token);
    }
}

3、修改header参数值(实现requestInterceptor)

package com.kayak.integration.client.dto.weixin;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import feign.RequestInterceptor;
import feign.RequestTemplate;
public class WxRequestInceptor implements RequestInterceptor{
	final Logger logger = LoggerFactory.getLogger(this.getClass());
	private static final String header_key = "Authorization";
	private Iterator<String> iterator;
	@Override
	public void apply(RequestTemplate paramRequestTemplate) {
		Map<String, Collection<String>> headersMap = paramRequestTemplate.headers();#获取报文头中的参数信息
		if(headersMap != null) {
			Collection<String> value = headersMap.get(header_key);
			if(value != null) {
				iterator = value.iterator();
				while(iterator.hasNext()){
					String auth = iterator.next();
					if(auth.startsWith("WECHATPAY2-SHA256-RSA2048") && auth.contains(", ")) {
						paramRequestTemplate.removeHeader(header_key);
						paramRequestTemplate.header(header_key, auth.replaceAll(", ", ","));
					}
				}	
			}
		}else {
			logger.info("headersMap is null");
			return ;
		}
####修改上下文中的header
		//		ServletRequestAttributes reqAttr = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
		//		logger.info("reqAttr >>>"+reqAttr);
		//		if(Objects.isNull(reqAttr)) {
		//			return ;
		//		}
		//		HttpServletRequest request = reqAttr.getRequest();
		//		Enumeration<String> headerNames = request.getHeaderNames();
		//		if(headerNames != null) {
		//			while(headerNames.hasMoreElements()) {
		//				String name = headerNames.nextElement();
		//				String value = request.getHeader(name);
		//				logger.info("name "+name+";value"+value);
		//			}
		//		}
		//		String auth = request.getHeader(header_key);
		//		logger.info("auth "+auth);
		//		if(auth != null) {
		//			paramRequestTemplate.header(header_key, auth.replaceAll(", ", ","));
		//		}
	}
}

3、Feign接口的熔断机制为:线程模式;

自定义了一个RequestInterceptor实现类,就会导致hystrix熔断机制失效,接口调用异常(404、null)

原因:

  • 在feign调用之前,会走RequestInterceptor拦截器,拦截器中使用了ServletRequestAttributes获取请求数据;
  • 默认feign使用的是线程池模式,当开启熔断的时候,负责熔断的线程和执行Feign接口的线程不是同一个线程,ServletRequestAttributes取到的将会是空值。

解决方案:

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 30000
          strategy: SEMAPHORE  ####线程隔离

 4、开启RequestInterceptor的4种方式

  • @Bean方法将RequestInterceptor实现类注入到Spring容器
  • 配置文件形式全局生效
  • 在某个接口针对类生效
  • 配置方式针对某个服务生效
方式一:
@Configuration
public class MyConfiguration {
    @Bean
    public RequestInterceptor requestInterceptor() {
        return new MyFeignRequestInterceptor();
    }
}

方式二:
feign:
  client:
    config:
      default:  ####全局生效
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: full
        # 拦截器配置(和@Bean的方式二选一)
        requestInterceptors:
          - com.yew.feign.config.MyFeignRequestInterceptor

方式三:
在@FeignClient注解中指定configuration属性为RequestInterceptor实现类
@FeignClient(Configuration=MyRequestInterceptor.class) 方式四: feign: client: config: service-A: ####指定服务生效 connectTimeout: 5000 readTimeout: 5000 loggerLevel: full # 拦截器配置(和@Bean的方式二选一) requestInterceptors: - com.yew.feign.config.MyFeignRequestInterceptor

 

标签:feign,openfeign,汇总,auth,header,应用,import,RequestInterceptor,public
From: https://www.cnblogs.com/vincentYw/p/17612792.html

相关文章

  • linux内网穿透应用场景有哪些?快解析有什么用处?
    随着网络技术的不断发展,无论是工作上还是在生活中人们对网络的依赖和需求越来越高。Linux内网穿透作为一种创新的解决方案,为我们提供了无限可能。首先我们了解一下Linux操作系统。Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户、多任务、支持多线程......
  • 打开电脑中应用程序及问题解决方案
    1、使用os.system()函数:示例代码importosos.system("notepad.exe")这将在Windows系统上打开记事本应用程序。2、使用subprocess示例代码:importsubprocesssubprocess.Popen(['notepad.exe'])3、使用webbrowser示例代码:importwebbrowserwebbrowser.open('http://www.goog......
  • 3D组态编辑器,零代码拖拉拽轻松构建数字孪生应用场景
    随着《中国制造2025》计划的提出,在国家数字化转型利好政策和行业发展趋势双向驱动加持下,数字孪生成为这两年数字经济发展的关键核心技术应用之一。中服云物联网开发平台组态编辑器,零代码拖拉拽轻松构建2D/3D数字孪生场景。企业生产、制造、运营等各类场景,以清晰、明确、实时的可视......
  • 从 SOCKS5、SK5 到 IP 代理的网络安全与应用
    在当今数字化时代,网络已经成为人们生活和工作中不可或缺的一部分。然而,随着网络的普及,网络安全问题也愈发凸显。为了保护个人隐私、绕过地理限制、加强网络安全,代理服务器技术应运而生。本文将深入探讨SOCKS5代理、SK5代理和IP代理等相关概念,探讨其在网络安全、爬虫和其他应用......
  • DELPHI应用EXCEL(4) 使用TOLEContainer控件
    严格的来说,tolecontainer控件并不是一个EXCEL控件,而是一个所有OLE文件的控件,可以用它打开PDF、OFFICE、TXT文件等等。而且使用OLECONTAINER控件打开的文件,文件内容依旧是一个VARIANT类型的数据。OLECONTAINER控件在SYSTEM组下。 使用OLECONTAINER控件需要注意以下几点:1、一......
  • 微前端的优势在哪里?为何能够打败单体应用架构
    微前端是一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品。有一个基座应用(主应用),来管理各个子应用的加载和卸载。所以微前端不是指具体的库,不是指具......
  • Linux常用的shell命令汇总
    本文介绍Linux系统下常用的系统级命令,包括软硬件查看、修改命令,有CPU、内存、硬盘、网络、系统管理等命令。说明命令是在Centos6.464位的虚拟机系统进行测试的。本文介绍的命令都会在此Centos下运行验证(也有部分命令会在suse/ubuntu系统里测试的,会做特明说明),但运行结果就不再列出......
  • Delphi ShellExecute为应用程序传递多个参数
    开发环境DelphiXe11.3 调用的程序  procedureTForm2.Button1Click(Sender:TObject);begin//某个参数包含空格时(用""),如下面这行;这里传递过去是3个参数ShellExecute(handle,'open',pchar('C:\Users\PC\Desktop\新建文件夹\新建文件夹\Win32\Debug\Project2.ex......
  • Delphi应用EXCEL(3) 使用OLEOBJECT
    1、创建EXCEL的方法首先创建Excel对象,使用单元ComObj:VarExcelApp:Variant;beginExcelApp:=CreateOleObject(''Excel.Application'');使用OLEOBJECT创建的EXCEL应用程序是一个Variant类型,所以DELPHI不能自动补充语句,也没有帮助文件,需要到visualbasic......
  • 岩土工程监测仪器多通道振弦传感器信号转换器应用于铁路监测
    岩土工程监测仪器多通道振弦传感器信号转换器应用于铁路监测岩土工程监测是工程建设和运营过程中必不可少的环节,它主要是通过对地下水位、土体应力、变形、固结沉降等参数进行实时监测,以保证工程施工和运营的安全性和稳定性。而多通道振弦传感器信号转换器正是岩土工程监测中的重......