springboot使用feign调用不依赖cloud
在使用spring boot调用第三方api中,常用的是okhttp、apache http client等,但是直接使用下来还是有点繁琐,需要手动转换实体。
在springcloud中有个openfeign调用,第一次体验到调用接口还能这么丝滑。注解写道接口上,配置一下,其他交给框架处理。搜了一下这种方式叫做声明式调用。类似的还有Retrofit、forest框架。
openfeign集成到springboot中有何优点:openfeign吸收了Retrofit框架的优点,做了声明式API,但是没有Retrofit多余的Call层。forest是一款国产优秀的框架,单独使用问题不大,但对于后续升级到cloud的boot项目,共存时存在不少问题,并且对上传大文件部分场景的支持有点问题。
这里分两步,先介绍@RequestLine注解调用,后介绍@GetMapping的spring注解调用。
一、传统注解@RequestLine调用
1.加依赖
<!-- feign --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId><version>11.0</version></dependency><dependency><groupId>com.netflix.feign</groupId><artifactId>feign-jackson</artifactId><version>8.18.0</version></dependency>
2.写代码
以天气api接口为例
controller层
package com.vvvtimes.demo.controller;import com.vvvtimes.demo.common.dto.RestResponse;
import com.vvvtimes.demo.domain.dto.WeatherCityDTO;
import com.vvvtimes.demo.domain.mybatis.City;
import com.vvvtimes.demo.domain.vo.WeatherVo;
import com.vvvtimes.demo.service.WeatherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/weather")
public class WeatherController {@Autowiredprivate WeatherService weatherService;@RequestMapping(value = "city/{id:1[0-9]{8}}", method = {RequestMethod.POST, RequestMethod.GET})public RestResponse<WeatherVo> loadApi(@PathVariable("id") String id) {return weatherService.loadApi(id);}}
service层
/*** 获取数据* @param id* @return*/@Cacheable(cacheNames = "weather_cache", key = "#id")// 从缓存获取,key为ID,缓存具体看 ehcache.xml 配置文件public RestResponse<WeatherVo> loadApi(String id) {RestResponse<WeatherVo> result =new RestResponse<>();WeatherVo weatherVo = sojsonApiClient.getCityWeather(id);if(weatherVo!=null && weatherVo.isSuccess()){result.setResult(weatherVo);}return result;}
//client层
package com.vvvtimes.demo.client;import com.vvvtimes.demo.domain.vo.WeatherVo;
import feign.Param;
import feign.RequestLine;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;import java.util.Map;@Component
public interface SojsonApiClient {//@GetMapping(value = "/api/weather/city/{id}")@RequestLine("GET /api/weather/city/{id}")WeatherVo getCityWeather(@Param("id") String id);}
client拦截器
package com.vvvtimes.demo.client.interception;import feign.RequestInterceptor;
import feign.RequestTemplate;public class SojsonInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate requestTemplate) {}
}
feign配置
package com.vvvtimes.demo.config;import com.vvvtimes.demo.client.IpinfoApiClient;
import com.vvvtimes.demo.client.SojsonApiClient;
import com.vvvtimes.demo.client.interception.IpinfoInterceptor;
import com.vvvtimes.demo.client.interception.SojsonInterceptor;
import feign.Feign;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ApiRegisterConfig {@Value("${sojson.base.url:http://t.weather.sojson.com/}")private String sojsonRegisterUrl;@Beanpublic SojsonApiClient sojsonApiRegister() {return Feign.builder().encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).requestInterceptor(new SojsonInterceptor()).target(SojsonApiClient.class, sojsonRegisterUrl);}}
3.测试访问
http://localhost:9000/weather/city/101010100
二、spring注解@GetMapping使用
上面使用的注解多少有点别扭,实际上我们可以通过feign-contract Feign的契约方式来使用spring的注解。
这里只对比上的代码讲解改造过程,不给出全代码
1.改造依赖
上面的feign依赖替换如下
<!-- feign --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-core</artifactId><version>11.6</version></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-spring4</artifactId><version>11.6</version></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-jackson</artifactId><version>11.6</version></dependency><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-httpclient</artifactId><version>11.6</version></dependency><dependency><groupId>io.github.openfeign.form</groupId><artifactId>feign-form</artifactId><version>3.8.0</version></dependency>
2.配置契约
ApiRegisterConfig的Bean加一句.contract(new SpringContract())
对应bean代码如下
@Beanpublic SojsonApiClient sojsonApiRegister() {return Feign.builder().encoder(new JacksonEncoder()).decoder(new JacksonDecoder()).requestInterceptor(new SojsonInterceptor()).contract(new SpringContract()).target(SojsonApiClient.class, sojsonRegisterUrl);}
3.改注解
将@RequestLine注解改成@GetMapping注解,代码如下
@GetMapping(value = "/api/weather/city/{id}")//@RequestLine("GET /api/weather/city/{id}")WeatherVo getCityWeather(@PathVariable("id") String id);
至此改造完成。
注意:本文没有设置feign的全局拦截器,因为在第三方接口中,每种接口的鉴权方式不一样,建议每种类型的接口单独设置拦截器做鉴权
相关文章:
springboot使用feign调用不依赖cloud
在使用spring boot调用第三方api中,常用的是okhttp、apache http client等,但是直接使用下来还是有点繁琐,需要手动转换实体。 在springcloud中有个openfeign调用,第一次体验到调用接口还能这么丝滑。注解写道接口上,…...
springboot中使用springboot cache
前言:SpringBoot中使用Cache缓存可以提高对缓存的开发效率 此图片是SpringBootCache常用注解 Springboot Cache中常用注解 第一步:引入依赖 <!--缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId…...
Promise,async/await的运用
一,了解Promise Promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,它的出现避免了地狱回调。 (1)Promise的实例有三个状态: Pending(进行中) Re…...
图论·多源最短路径Floyddijsktra
例题地址 多源最短路径 多个源点多个终点可以使用Floyd算法直接求各源点到终点的最短距离,也可以直接多次使用dijsktra算法求单源点到终点的最短距离 Floyd算法 使用条件 多源最短路径权值正负皆可 核心思想:动态规划 子问题: 设(A,B)…...
微服务 | Springboot整合GateWay+Nacos实现动态路由
1、简介 路由转发 执行过滤器链。 网关,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。同时,基于Filter链的方式提供了网关的基本功能,比如:鉴权、流量控制、熔断、路径重写、黑白名单、日志监控等。 基本功能…...
做google SEO 有哪些好用的工具?这12款谷歌SEO工具值得收藏!
1、Google Trends 谷歌旗下一款基于搜索数据推出的一款免费分析工具 外贸人有句老话,七分靠选品,三分靠运营。在你开始做独立站之前,在你不清楚你的行业在Google上面能否有足够的流量时,那么Google Trends则是你最好的工具。 你只…...
【变频调速在锅炉引风机控制中的应用】
变频调速在锅炉引风机控制中的应用 变频器的选型 变频器是利用电力半导体器件的通断作用将工频电源变换为另一种频率的电能控制装置,能宏观对交流异步电机软启动,变频调速,提高运转精度,改变功率因数,过流/过压/过载保护等功能,国内技术较领先的品牌有汇川、欧瑞(原烟台…...
网络配置(IP、NETMASK、GATEWAY、DNS、DHCP) <持续更新中>
参考: 初学Linux之网络配置(IP、NETMASK、GATEWAY、DNS、DHCP)-CSDN博客【学习笔记】网关 & 路由_网关和路由-CSDN博客【学习笔记】计算机网络 IP地址与MAC地址_根据mac分配ip-CSDN博客【学习笔记】TCP 和 UDP 协议_tcp 发送 syn 应答没有syn ack-CSDN博客 一…...
【ArcGIS 脚本工具】拯救密恐,隐藏唯一值渲染图层的标记符号
最近拿到了【Hello 图狗】制作的三调/变更样式符号库,确实比之前网上下载的版本好用很多。 ArcGIS Pro三调23变更符号库V1.02(汇总)_中大比例尺.stylx和样式属性对调 不过使用过程中触发了一个旧病,就是匹配样式之后,…...
tensorflow学习1.3-创建会话,启动会话
tensorflow学习1.3-创建会话,启动会话 会话的由来与作用由来作用 会话的定义与结构定义 用法基本用法上下文管理器执行部分计算图获取多个结果 总结 练习代码报错原因:TensorFlow 2.x中的Eager Execution使用兼容模式来启用SessionEager Execution和计算…...
QT基本对话框(基本对话框、工具盒类、进度条、调色板与电子钟、可扩展对话框、程序启动画面)
此篇文章通过实例介绍基本对话框的用法。首先介绍标准文件对话框(QFileDialog)、标准颜色对话框(QColorDialog)、标准字体对话框(QFontDialog)、标准输入对话框(QInputDialog)以及标…...
Docker 部署 MariaDB 数据库 与 Adminer 数据库管理工具
文章目录 MariaDBmariadb.cnf开启 binlog Adminerdocker-compose.ymlAdminer 连接 MariaDB MariaDB MariaDB是一个流行的开源关系型数据库管理系统(RDBMS),它是MySQL的一个分支和替代品。 官网:https://mariadb.com/镜像ÿ…...
qt 可以在一个函数中读一个文件,然后再将内容写入另一个文件中
是的,Qt 允许你在一个函数中读取一个文件的内容,并将这些内容写入到另一个文件中。这可以通过结合使用 QFile 和 QTextStream(或 QDataStream,取决于你的具体需求)来实现。以下是一个简单的示例,展示了如何…...
Dijkstra算法C代码
一个带权图n个点m条边,求起点到终点的最短距离 先定义一个邻接矩阵graph,graph[i][j]表示从i到j的距离,i到j没有路就表示为无穷 然后定义一个visit数组,visit[i]表示i结点是否被访问 然后定义一个dist数组,dist[i]表…...
P1064 [NOIP2006 提高组] 金明的预算方案
[NOIP2006 提高组] 金明的预算方案 题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置࿰…...
大型企业组网如何规划网络
大型企业组网是一个复杂的过程,它需要细致的规划和设计,以确保网络能够满足企业的业务需求,同时保证性能、安全性和可扩展性。以下是规划大型企业网络的一些关键步骤和考虑因素: 1. 需求分析 业务需求:与各个业务部门…...
java:aocache的单实例缓存(二)
之前一篇博客《java:aocache的单实例缓存》介绍了aoocache使用注解AoCacheable实现单实例缓存的方式,同时也指出了这种方式的使用限制,就是这个注解定义的构造方法,不能再创建出新实例。 为了更灵活方便的实现单实例。aocache最新版本0.4.0增…...
ElasticSearch安装部署
简介 Elasticsearch 是一个开源的分布式搜索和分析引擎,用于实时地存储、检索和分析大数据量。它基于 Apache Lucene 搜索引擎库构建而成,提供了一个强大、稳定且易于扩展的搜索解决方案。 主要特点和用途: 分布式存储和搜索: E…...
数据赋能(132)——开发:数据转换——影响因素、直接作用、主要特征
影响因素 数据转换过程中需要考虑的一些影响因素: 数据格式与结构: 不同系统或应用可能使用不同的数据格式(如JSON、XML、CSV等)和数据结构(如关系型数据库、非关系型数据库等)。数据转换需要确保原始数据…...
TMGM:ASIC撤销禁令,TMGM强化合规、重启差价合约服务
TMGM作为差价合约(CFDs)与保证金外汇交易领域的领航者,安全、合规、高效被奉为我集团的终身使命。澳大利亚证券和投资委员会(ASIC)已正式撤销了早前针对TMGM差价合约业务实施的临时止损令。这一误会的解除,…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
简约商务通用宣传年终总结12套PPT模版分享
IOS风格企业宣传PPT模版,年终工作总结PPT模版,简约精致扁平化商务通用动画PPT模版,素雅商务PPT模版 简约商务通用宣传年终总结12套PPT模版分享:商务通用年终总结类PPT模版https://pan.quark.cn/s/ece1e252d7df...
Vue3学习(接口,泛型,自定义类型,v-for,props)
一,前言 继续学习 二,TS接口泛型自定义类型 1.接口 TypeScript 接口(Interface)是一种定义对象形状的强大工具,它可以描述对象必须包含的属性、方法和它们的类型。接口不会被编译成 JavaScript 代码,仅…...
rk3506上移植lvgl应用
本文档介绍如何在开发板上运行以及移植LVGL。 1. 移植准备 硬件环境:开发板及其配套屏幕 开发板镜像 主机环境:Ubuntu 22.04.5 2. LVGL启动 出厂系统默认配置了 LVGL,并且上电之后默认会启动 一个LVGL应用 。 LVGL 的启动脚本为/etc/init.d/pre_init/S00-lv_demo,…...
