当前位置: 首页> 健康> 知识 > 二级分销利润分配模式_深圳建设网站排名_网站seo怎么操作_建设网官方网站

二级分销利润分配模式_深圳建设网站排名_网站seo怎么操作_建设网官方网站

时间:2025/8/27 7:00:33来源:https://blog.csdn.net/FBB360JAVA/article/details/143975328 浏览次数:0次
二级分销利润分配模式_深圳建设网站排名_网站seo怎么操作_建设网官方网站

文章目录

  • 前言
  • 正文
    • 一、项目环境
    • 二、项目结构
      • 2.1 包的含义
      • 2.2 代理的场景
    • 三、完整代码示例
      • 3.1 定义FeignClient
      • 3.2 定义拦截器
      • 3.3 配置类
      • 3.4 okhttp配置
      • 3.5 响应体
        • 3.5.1 天行基础响应
        • 3.5.2 热点新闻响应
      • 3.6 代理类
        • 3.6.1 代理工厂
        • 3.6.2 代理客户端
        • 3.6.3 FeignClient的建造器
    • 四、调用&测试
      • 4.1 配置信息
      • 4.2 测试代码
      • 4.3 调用结果
  • 附录

前言

一般来说我们的项目中难免会涉及到调用三方接口的场景。
以前我们可能用 RestTemplate,或者再用OkHttp优化一下。

但是,在读了本文之后,你将发现使用OpenFeign的 FeignClient来调用三方接口,也是纵享丝滑的。

注意,本文旨在使用FeignClient调用三方接口,不讨论其他情况。比如高版本JDK自带的工具类,或者响应式API。

本文使用FeignClient来调用天行API接口。(https://www.tianapi.com/)
在天行官网注册账号后,可以申请自己想要调用的API接口。拿到key之后即可调用。每天都有免费的使用次数。

正文

一、项目环境

项目使用 Java 17、SpringBoot 3.3.4 、SpringCloud 2023.0.3

<properties><java.version>17</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><spring-boot.version>3.3.4</spring-boot.version><spring-cloud.version>2023.0.3</spring-cloud.version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.32</version><optional>true</optional></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.32</version></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-okhttp --><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-loadbalancer --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency></dependencies><dependencyManagement><dependencies><!-- springboot依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

二、项目结构

在这里插入图片描述

2.1 包的含义

  • com.pine.client.core.tianxing: 定义FeignClient接口;
  • com.pine.client.interceptor:拦截器
  • com.pine.client.config:配置类
  • com.pine.client.proxy:代理相关内容
  • com.pine.client.beans:请求体+响应体

2.2 代理的场景

在这里插入图片描述
假设你现在有内网和外网两种网络环境,应用部署在内网,现在你的应用需要访问外部三方接口,需要开白名单;

但是,一般而言,不会直接给你的应用开启白名单,会统一经过一个代理机进行跳转,也就是给内网中的代理机开启白名单,而你的应用使用它作为代理去访问三方接口。

三、完整代码示例

我这里接入三方接口的是:https://www.tianapi.com/apiview/68

温馨提示:天行API的接口文档不可尽信,有的响应体结构对应不上,建议在开发时,可以先用JsonNode接收,然后看实际的响应结构是什么,再定义对象去接收。

3.1 定义FeignClient

package com.pine.client.core.tianxing;import com.pine.client.beans.TianXingNetHotResponse;
import com.pine.client.config.TianXingRequestConfiguration;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;/*** 天行feign client** @author pine manage* @since 2024-11-22*/
@FeignClient(name = "tianXing", url = "${rpc.tianxing.url}", configuration = TianXingRequestConfiguration.class)
public interface TianXingFeignClient {@PostMapping(value = "/nethot/index")TianXingNetHotResponse netHot();
}

3.2 定义拦截器

package com.pine.client.interceptor;import feign.RequestInterceptor;
import feign.RequestTemplate;/*** 天行 feign请求拦截器** @author pine manage* @since 2024-11-22*/
public class TianXingRequestInterceptor implements RequestInterceptor {private final String key;public TianXingRequestInterceptor(String key) {this.key = key;}@Overridepublic void apply(RequestTemplate requestTemplate) {// 请求头增加参数 content-typerequestTemplate.header("Content-Type", "application/x-www-form-urlencoded");// 请求参数增加keyrequestTemplate.query("key", key);}
}

3.3 配置类

package com.pine.client.config;import com.pine.client.interceptor.TianXingRequestInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 天行接口请求配置** @author pine manage* @since 2024-11-22*/
@Configuration
public class TianXingRequestConfiguration {@Value("${rpc.tianxing.key}")private String tianXingKey;@Beanpublic TianXingRequestInterceptor tianXingRequestInterceptor() {return new TianXingRequestInterceptor(tianXingKey);}
}

3.4 okhttp配置

package com.pine.client.config;import lombok.extern.slf4j.Slf4j;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;import java.io.IOException;/*** okhttp配置** @author pine manage* @since 2024-11-22*/
@Slf4j
@Configuration
public class OkHttpConfig {@Beanpublic okhttp3.OkHttpClient.Builder okHttpClientBuilder() {return new okhttp3.OkHttpClient.Builder().addInterceptor(new LoggingInterceptor());}/*** okhttp3 请求日志拦截器*/static class LoggingInterceptor implements Interceptor {@NonNull@Overridepublic Response intercept(Chain chain) throws IOException {Request request = chain.request();long start = System.nanoTime();log.info(String.format("Sending request %s on %s%n%s",request.url(), chain.connection(), request.headers()));Response response = chain.proceed(request);long end = System.nanoTime();log.info(String.format("Received response for %s in %.1fms%n%s",response.request().url(), (end - start) / 1e6d, response.headers()));return response;}}
}

3.5 响应体

3.5.1 天行基础响应
package com.pine.client.beans;import lombok.Data;import java.io.Serial;
import java.io.Serializable;/*** 天行基础响应类** @author pine manage* @since 2024-11-22*/
@Data
public class TianXingBaseResponse implements Serializable {@Serialprivate static final long serialVersionUID = 4154999614348985895L;private Long code;private String msg;}
3.5.2 热点新闻响应
package com.pine.client.beans;import lombok.Data;
import lombok.EqualsAndHashCode;import java.io.Serial;
import java.io.Serializable;
import java.util.List;/*** 天行热点新闻查询响应** @author pine manage* @since 2024-11-22*/
@EqualsAndHashCode(callSuper = true)
@Data
public class TianXingNetHotResponse extends TianXingBaseResponse implements Serializable {@Serialprivate static final long serialVersionUID = 52499588383169858L;private List<Body> newslist;private String tip;@Datapublic static class Body implements Serializable {@Serialprivate static final long serialVersionUID = -1264805102673130063L;private String brief;private String index;private String keyword;private String trend;}
}

3.6 代理类

注意:代理的使用,我这里没做测试,如果你的应用场景涉及到了,建议先测试下。在使用代理的时候,@FeignClient 注解中的 url参数就要去掉,使用代理的proxiedUrl传入。

3.6.1 代理工厂
package com.pine.client.proxy;import java.net.InetSocketAddress;
import java.net.Proxy;/*** 代理工厂** @author pine manage* @since 2024-11-22*/
public class ProxyFactory {public static Proxy newHttpProxy(String hostname, int port) {return new Proxy(Proxy.Type.HTTP,new InetSocketAddress(hostname, port));}public static Proxy newDirectProxy(String hostname, int port) {return new Proxy(Proxy.Type.DIRECT,new InetSocketAddress(hostname, port));}public static Proxy newSocksProxy(String hostname, int port) {return new Proxy(Proxy.Type.SOCKS,new InetSocketAddress(hostname, port));}
}
3.6.2 代理客户端
package com.pine.client.proxy;import feign.Client;
import feign.Request;
import feign.Response;import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import java.io.IOException;
import java.net.Proxy;/*** 代理客户端** @author pine manage* @since 2024-11-22*/
public class ProxyClient extends Client.Proxied {public ProxyClient(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier, Proxy proxy) {super(sslContextFactory, hostnameVerifier, proxy);}@Overridepublic Response execute(Request request, Request.Options options) throws IOException {return super.execute(request, options);}}
3.6.3 FeignClient的建造器
package com.pine.client.proxy;import feign.Feign;
import feign.Request;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.cloud.openfeign.DefaultFeignLoggerFactory;
import org.springframework.cloud.openfeign.support.SpringMvcContract;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import java.net.Proxy;
import java.time.Duration;
import java.util.Optional;/*** FeignClient建造器** @author pine manage* @since 2024-11-22*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
public class FeignClientBuilder {private static final Long DEFAULT_CONNECT_TIMEOUT = 5L;private static final Long DEFAULT_READ_TIMEOUT = 10L;private static final boolean DEFAULT_FOLLOW_REDIRECTS = true;@Nullableprivate Encoder encoder;@Nullableprivate Decoder decoder;@NonNullprivate Proxy proxy;@Nullableprivate SSLSocketFactory sslContextFactory;@Nullableprivate HostnameVerifier hostnameVerifier;@Nullableprivate Retryer retryer;@Nullableprivate Long connectTimeout;@Nullableprivate Long readTimeout;@Nullableprivate Boolean followRedirects;public <T> T build(Class<T> clazz, String proxiedUrl) {this.connectTimeout = Optional.ofNullable(this.connectTimeout).orElse(DEFAULT_CONNECT_TIMEOUT);this.readTimeout = Optional.ofNullable(this.readTimeout).orElse(DEFAULT_READ_TIMEOUT);this.followRedirects = Optional.ofNullable(this.followRedirects).orElse(DEFAULT_FOLLOW_REDIRECTS);this.retryer = Optional.ofNullable(retryer).orElse(Retryer.NEVER_RETRY);this.encoder = Optional.ofNullable(encoder).orElse(new Encoder.Default());this.decoder = Optional.ofNullable(decoder).orElse(new Decoder.Default());Request.Options options = new Request.Options(Duration.ofSeconds(connectTimeout), Duration.ofSeconds(readTimeout), followRedirects);ProxyClient proxyClient = new ProxyClient(sslContextFactory, hostnameVerifier, proxy);return Feign.builder().client(proxyClient).retryer(this.retryer).options(options).encoder(encoder).decoder(decoder).logger(new DefaultFeignLoggerFactory(null).create(clazz)).contract(new SpringMvcContract()).target(clazz, proxiedUrl);}//    public static void main(String[] args) {
//        com.pine.client.core.tianxing.TianXingFeignClient tianXingFeignClient = new FeignClientBuilder()
//                .setProxy(ProxyFactory.newHttpProxy("代理地址", 1003))
//                .build(com.pine.client.core.tianxing.TianXingFeignClient.class, "localhost");
//    }
}

四、调用&测试

4.1 配置信息

spring:cloud:openfeign:# 启用okhttp配置okhttp:enabled: trueloadbalancer:# 关闭负载重试retry:enabled: falserpc:tianxing:key: 你自己申请的天行keyurl: http://api.tianapi.com

4.2 测试代码

在controller中添加代码:

@Resource
private TianXingFeignClient tianXingFeignClient;@PostMapping("/test")
public ResultVo<TianXingNetHotResponse> test() {TianXingNetHotResponse netHotResponse = tianXingFeignClient.netHot();return ResultVo.success(netHotResponse);
}

4.3 调用结果

控制台输出了okhttp的拦截内容:

2024-11-22 16:04:35.177  INFO  82746 --- [http-nio-8080-exec-1] com.pine.client.config.OkHttpConfig$LoggingInterceptor.intercept(OkHttpConfig.java:39) : [logId=default] Sending request http://api.tianapi.com/nethot/index?key=你自己申请的天行key on null
Accept: */*2024-11-22 16:04:35.477  INFO  82746 --- [http-nio-8080-exec-1] com.pine.client.config.OkHttpConfig$LoggingInterceptor.intercept(OkHttpConfig.java:43) : [logId=default] Received response for http://api.tianapi.com/nethot/index?key=你自己申请的天行key in 298.1ms
Server: nginx
Date: Fri, 22 Nov 2024 08:04:35 GMT
Content-Type: application/json;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 604800
Strict-Transport-Security: max-age=31536000

接口响应结果:省略(自行调用即可)

附录

附1:本系列文章链接
SpringCloud系列文章目录(总纲篇)

关键字:二级分销利润分配模式_深圳建设网站排名_网站seo怎么操作_建设网官方网站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: