SpringBoot项目整合OpenFeign、实现动态IP+URL请求、自定义(编码器\解码器)
SpringBoot项目整合OpenFeign
- 基础操作
- pom依赖
- 配置application.yml
- 服务启动类
- 基础跨服务调用
- 动态IP+URL请求 + 动态编码器\解码器
- 自定义跨服务请求,Encoder编译器
- 自定义跨服务响应,Decoder 解码器
- 方式1:`FeignFactory.class`
- 工具类: `FeignUtils.class`
- 方式2:`FeignApiFactory.class`
基础操作
pom依赖
OpenFeign
是Spring Cloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中.
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置application.yml
#====《跨服务HTTP接口请求工具》====
feign:client:config:#可指定需要配置的:服务名称# manage-client:#或 默认配置:全局default:#日志打印级别loggerLevel: basic#跨服务接口请求超时readTimeout: 5000#跨服务请求连接超时connectTimeout: 5000
服务启动类
启动类加上注解:@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class OpenFeignServer {public static void main(String[] args) {SpringApplication.run(OpenFeignServer.class, args);}
}
基础跨服务调用
/*** @Author Owen* @Date 2020/8/18* @Description Admin后台管理服务*/
@FeignClient("serverName")
public interface AdminServiceClient {@RequestMapping(value = "/XXX/XXXX/XXXX", method = RequestMethod.GET, produces = {"application/json"}, consumes = {"application/glue+json"})<T> T doGet(@RequestParam("params") String params);@RequestMapping(value = "/XXX/XXXX/XXXX", method = RequestMethod.PUT, produces = {"application/json"}, consumes = {"application/communication+json"})<T> T doPut(@RequestBody Object params);@RequestMapping(value = "/XXX/XXXX/XXXX", method = RequestMethod.POST, produces = {"application/json"}, consumes = {"application/communication+json"})<T> T doPost(@RequestBody Object params);}
动态IP+URL请求 + 动态编码器\解码器
自定义跨服务请求,Encoder编译器
import com.details.utils.ConvertUtils;
import com.details.utils.JsonUtils;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.RequestTemplate;
import feign.Util;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;/*** @author Owen* @date 2022/10/22 21:10* @Description:自定义Feign跨服务请求,编译器*/
@Slf4j
public class FeignEncoder implements Encoder {ObjectMapper mapper = new ObjectMapper();@SneakyThrows@Overridepublic void encode(Object object, Type bodyType, RequestTemplate template) {log.info("Feign requset encode details: {}", object);try {//获取请求头详情Map<String, Collection<String>> headers = template.headers();//查看请求方式Collection<String> contentType = headers.get("Content-Type");//Json请求方式if (CollectionUtils.isNotEmpty(contentType) && contentType.contains("application/json") && !(object instanceof String)) {template.body(JsonUtils.object2Json(object));}//字符串else if (object instanceof String) {template.body(object.toString());} else {JavaType javaType = this.mapper.getTypeFactory().constructType(bodyType);template.body(ConvertUtils.writeAsBytes(javaType, object), Util.UTF_8);}} catch (Exception e) {throw new EncodeException(String.format("%s is not a type supported by this encoder.", object.getClass()));}}
}
自定义跨服务响应,Decoder 解码器
import feign.Response;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Type;/*** @author Owen* @date 2022/10/22 21:10* @Description:自定义Feign跨服务响应,解码器*/
@Slf4j
public class FeignDecoder implements Decoder {@Overridepublic Object decode(Response response, Type type) {log.info("URL:[{}] response result: {}", response.request().url(), response);return response.body();}
}
方式1:FeignFactory.class
动态URL
import feign.*;
import java.net.URI;/*** @Author: Owen* @Date: 2022/10/22* @Description:Feign公共接口(自定义请求API,内部请求)*/
public interface FeignFactory {/*** @param host 接口主机地址,如:http://localhost:8080,该参数是实现动态URL的关键* @param path 接口路径,如:/test/hello* @param body 请求消息体对象* @Author: Owen* @Date: 2022/10/22* @Description:通用POST请求,请求消息体格式为JSON*/@RequestLine("POST {path}")@Headers({"Content-Type: application/json", "Accept: application/json"})<T> T doPost(URI host,@Param("path") String path, Object body);/*** @param host 接口主机地址* @param path 接口路径,如:/test/hello* @Author: Owen* @Date: 2022/10/22* @Description:通用Get请求*/@RequestLine("POST {path}")<T> T doGet(URI host, @Param("path") String path);}
工具类: FeignUtils.class
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.details.nacos.NacosFactory;
import com.details.utils.CacheUtils;
import com.details.utils.ExceptionUtils;
import com.details.utils.IocUtils;
import com.details.utils.TcpIpUtils;
import feign.Feign;
import feign.Logger;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.slf4j.Slf4jLogger;
import lombok.extern.slf4j.Slf4j;
import java.net.URI;
import java.util.*;/*** @author: Owen* @date: 2021/3/24* @description:跨服务API请求工具 集成Spring openfeign各个功能* 动态设置 编译器 解码器 熔断器* 跨服务器 动态API请求 自定义构建 IP(单机\集群)+服务名*/
@Slf4j
public class FeignUtils {private static Feign.Builder feignClient = null; /*** @param ip 对应服务器公网IP* @param path API接口地址* @Author: Owen* @Date: 2022/10/22* @Description:通用Get请求*/public static <T> T doGet(String ip, String path) {T result = null;ExceptionUtils.isBlank(ip, "Params :[ip] is null !");ExceptionUtils.isBlank(ip, "Params :[path] is null !");ExceptionUtils.isTrue(!ip.contains(":"), "Ip port not null!");ExceptionUtils.isTrue(!ip.contains("http://"), "Ip formal error, lack \"http://\"");try {//构建Feign基础实例Feign.Builder client = feigenClient();ExceptionUtils.isNull(client, "Feign client is null !");//自定义配置client.encoder(new FeignEncoder()); //API请求 编译器client.decoder(new FeignDecoder()); //API响应 解码器client.logger(new Slf4jLogger()); //日志client.logLevel(Logger.Level.FULL); //日志级别//构建工厂//注意:这里的url参数不能为空字符串,但是可以设置为任意字符串值,在这里设置为“EMPTY”FeignFactory factory = client.target(FeignFactory.class, "EMPTY");//跨服务请求result = factory.doGet(URI.create(ip), path);} catch (Exception e) {log.error("HTTP get requset faild: {}", e.getMessage());}return result;}/*** @param ip 对应服务器公网IP* @param path API接口地址* @param body Json数据体* @Author: Owen* @Date: 2022/10/22* @Description:跨服务POST请求接口,类型:application/json*/public static <T> T doPost(String ip, String path, Object body) {T result = null;ExceptionUtils.isBlank(ip, "Params :[ip] is null !");ExceptionUtils.isBlank(ip, "Params :[path] is null !");ExceptionUtils.isNull(body, "Params :[body] is null !");ExceptionUtils.isTrue(!ip.contains(":"), "ip port not null!");ExceptionUtils.isTrue(!ip.contains("http://"), "Ip formal error, lack \"http://\"");try {//构建Feign基础实例Feign.Builder client = feigenClient();ExceptionUtils.isNull(client, "Feign client is null !");//自定义配置client.encoder(new FeignEncoder()); //API请求 编译器client.decoder(new FeignDecoder()); //API响应 解码器client.logger(new Slf4jLogger()); //日志client.logLevel(Logger.Level.FULL); //日志级别FeignFactory factory = client.target(FeignFactory.class, ip);//跨服务请求result = factory.doPost(URI.create(ip), path, body);} catch (Exception e) {log.error("HTTP post requset faild: {}", e.getMessage());}return result;}/*** @author: Owen* @date: 2020/12/4* @description:获取Feign实例(单例模式)*/private static Feign.Builder feigenClient() {try {//feign客户端(http跨服务请求 单例模式)if (Objects.isNull(feigenClient)) {//第一次判空//保证线程安全synchronized (Feign.Builder.class) {//第二次判空,保证单例对象的唯一性,防止第一次有多个线程进入第一个if判断if (Objects.isNull(feigenClient)) {try {feigenClient = Feign.builder();} catch (Exception e) {log.error("Feigen client initialize fail: " +e.getMessage());}}}}} catch (Exception e) {log.error("Feigen client get faild: {}", e.getMessage());}return feigenClient;}
}
方式2:FeignApiFactory.class
import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.slf4j.Slf4jLogger;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.net.URI;/*** @Author: Owen* @Date: 2022/10/22* @Description:Feign公共接口(走网关转发)*/
@FeignClient(value = "server-gateway", url = "EMPTY", configuration = FeignApiFactory.CallbackConfiguration.class)
public interface FeignApiFactory {/*** @param host 接口主机地址,如:http://localhost:8080* @param path 接口路径,如:/test/hello* @param body 请求消息体对象* @Author: Owen* @Date: 2022/10/22* @Description: 统一回调接口方法,请求消息体格式为JSON,响应消息体格式也为JSON*/@RequestMapping(value = "{path}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)<T> T doPost(URI host, @PathVariable("path") String path, @RequestBody Object body);/*
==========《Deme》==========:String uri = "http://localhost:8080";Map<String, Object> queryMap = new HashMap<>(0);queryMap.put("k","v");Map<String,Object> body = new hashMap<String,Object>();body.put("params1","value");Object result = this.callbackAPI.callback(URI.create(uri), "/test/apiTest", queryMap, body);
*///自定义回调接口配置@Componentclass CallbackConfiguration {@Beanpublic Encoder feignEncoder() {return new FeignEncoder();}@Beanpublic Decoder feignDecoder() {return new FeignDecoder();}@Beanpublic Retryer feignRetryer() {return new Retryer.Default();}@Beanpublic Logger feignLogger() {return new Slf4jLogger();}@Beanpublic Logger.Level feignLoggerLevel() {return Logger.Level.FULL;}}
}
SpringBoot项目整合OpenFeign、实现动态IP+URL请求、自定义(编码器\解码器)相关推荐
- Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数Demo
Docker 部署SpringBoot项目整合 Redis 镜像做访问计数Demo 最终效果如下 大概就几个步骤 1.安装 Docker CE 2.运行 Redis 镜像 3.Java 环境准备 4. ...
- springboot项目整合mybatis
SpringBoot项目整合mybatis 本章内容 使用 idea创建 SpringBoot项目 SpringBoot项目中配制 mybatis 框架 1 创建 SpringBoot项目 1.1 在 ...
- springboot项目整合阿里云oss的内容审核
springboot项目整合阿里云 内容审核 第一 添加依赖 <dependency><groupId>com.aliyun</groupId><artifa ...
- Nginx安装配置与SpringBoot项目整合
本篇文章将在上篇<Redis安装与SpringBoot项目整合详细教程>(上文链接:https://blog.csdn.net/sp958831205/article/details/88 ...
- Java springBoot项目整合海康威视摄像头抓拍车辆功能
Java springBoot项目整合海康威视摄像头抓拍获取车辆信息功能 这篇文字写于去年的11月份,项目部署上去一段时间后,被反应有自动停止抓拍的BUG,我在代码中的解决办法是写了一个定时任务, 让 ...
- SpringBoot项目整合Retrofit最佳实践,这才是最优雅的HTTP客户端工具!
作者:六点半起床 juejin.im/post/6854573211426750472 大家都知道okhttp是一款由square公司开源的java版本http客户端工具.实际上,square公司还开 ...
- springboot系列学习(十九):springboot项目整合Druid,Druid到底是什么,他是在项目中如何使用的
目录 Druid是什么 先看一下之前的整合的jdbc使用的数据源是什么 创建一个springboot项目,导入Druid依赖 写一个Druid的配置类 yml文件和配置类绑定,这个之前就写过 解释以上 ...
- spring-boot项目整合obs服务器-华为云
目录 前言 1.购买服务并从官网获得我们项目所需的配置参数 1-1.登录华为云 1-2.进入控制台 1-3.创建桶 1-4.获取sk.ak 2.spring-boot项目集成OBS服务器 2-1 ...
- OAuth2.0 社交登录-Gitee springboot项目整合(微服务分布式)完整代码包括 数据库、前、后端
文章目录 社交登录(Gitee) 1.模拟请求 项目整合 1.数据库增加字段 2.前端 2.后端 社交登录(Gitee) 完成这个踩了很多坑,包括第一时间忘了浏览器缓存这回事以及微博一些平台申请社交登 ...
最新文章
- SortedMap接口
- Java基于FTPClient上传文件到FTP服务器
- JDBC详解系列之流程
- javascript权威指南--学习笔记
- win10开机时不显示锁屏壁纸
- sublime 执行print带有中文时出错Decode error - output not utf-8
- 1. COM编程——什么是组件
- 客户关系管理软件的作用是什么?
- ms17010漏洞复现-2003
- oracle磁带库清洁带标签,LTO-1/2/3/4/5/6/7/8 Ultrium数据磁带 清洗带 清洁带 磁带标签批发...
- Unity 鼠标进入UI控件,显示控件名称
- java论坛 基于SSM框架的游戏论坛 java游戏贴吧 java游戏论坛 java论坛 ssm论坛 ssm贴吧 可以改为各种论坛,分类可在后台自己控制,图片可任意换
- 开关电源中电容与电感时间常数
- 怎么用python编写心形图案,python编程爱心形状turtle
- 50个SQL语句练习题
- OSChina 周六乱弹 —— 周六啦,我们一起去堆雪人吧~
- 网站底部的统计代码HTML
- 如何用VR改变驾驶陋习?
- unix sed命令
- 关于键盘asdw键和上下左右键互换问题
热门文章
- 【网络设备配置与管理实验一】PT 设置主机名,IP 地址
- 机器学习算法系列(十五)-软间隔支持向量机算法(Soft-margin Support Vector Machine)
- webflux oracle,從MVC到WebFlux
- 安装baidupcs-go
- oracle踩坑: [Err] ORA-00911: invalid character
- pcap文件格式及文件解析
- 计算机找不到wlan,Win10网络设置找不到wlan选项怎么办?
- 时间频度,时间复杂度的计算
- 服务器安装Centos教程
- Slackel Live ,惊艳与惊讶并存