feign的加解密封装

2023-11-01

功能描述

通过覆盖 feign.codec.Encoder 和 feign.codec.Decoder
实现 feign 请求的加解密操作

采用动态的 feignClient 调用,平台统一的通信加解密策略
同一个服务节点可以同时使用非加密的 customFeign 和 使用我方平台加密的 partnerFeign

1. 前言

我这边是支付渠道,调用第三方支付的callback请求
自我感觉良好,分享给同学们

2. 核心代码

2.1 FeignRequestEncoder 请求加密

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mea.pay.api.infrastructure.IFeignEncoder;
import com.mea.pay.common.constants.ConstantHttp;
import com.mea.pay.common.util.AESEncryptUtil;
import com.mea.pay.common.util.CommonUtil;
import com.mea.pay.common.util.RSAUtil;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;

import static com.mea.pay.notifycenter.config.SandboxNotifyConfig.PRIVATE_KEY;

/**
 * 覆盖 feign 的 加密操作
 *
 * @author Heng.Wei
 * @date 2022/4/20 9:44
 **/
@Slf4j
@Primary
@Component
public class FeignRequestEncoder implements IFeignEncoder {

    @Override
    public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {

        if(!String.class.equals(bodyType)){
            return;
        }
        // 我们和外围厂商交互默认是 application/json 格式,下面对 requestbody 做加密操作
        String requestBodyString = object.toString();
        // 随机生成的16位AES密钥
        String aesKey = CommonUtil.getValue();
        String encryptedAesKey;
        try {
            // 私钥加密AES密钥
            encryptedAesKey = RSAUtil.encryptByPrivateKey(PRIVATE_KEY, aesKey);
        } catch (Exception e) {
            log.error("meapay feign encode exception, message:{}, detail:{}", e.getMessage(), JSON.toJSONString(e));
            throw new EncodeException("meapay feign encode exception:" + e.getMessage());
        }
        // 对 requestBody 做AES对称加密
        String data = AESEncryptUtil.encryptBase64(requestBodyString, aesKey);
        // 组装 requestBody
        JSONObject requestBody = new JSONObject();
        requestBody.put(ConstantHttp.CODE, encryptedAesKey);
        requestBody.put(ConstantHttp.DATA, data);
        template.body(requestBody.toJSONString());
    }
}

2.2 响应解密

FeignResponseDecoder 响应解密

package com.mea.pay.notifycenter.config;

import com.alibaba.fastjson.JSON;
import com.mea.pay.api.infrastructure.IFeignDecoder;
import com.mea.pay.common.exception.BusinessException;
import com.mea.pay.common.util.AESEncryptUtil;
import com.mea.pay.common.util.RSAUtil;
import com.mea.pay.notifycenter.domain.dto.FeignResponseDTO;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Type;

import static com.mea.pay.notifycenter.config.SandboxNotifyConfig.PRIVATE_KEY;
import static java.lang.String.format;

/**
 * 覆盖 feign 的 Decoder 实现类,实现解密操作
 * @author Heng.Wei
 * @date 2022/4/19 18:15
 **/
@Slf4j
@Primary
@Component
public class FeignResponseDecoder implements IFeignDecoder {

    @Override
    public Object decode(Response response, Type type) throws IOException, FeignException {

        Response.Body body = response.body();
        if (response.status() == HttpStatus.NOT_FOUND.value() || response.status() == HttpStatus.NO_CONTENT.value()){
            return Util.emptyValueOf(type);
        }
        if (body == null){
            return null;
        }
        if (byte[].class.equals(type)) {
            return Util.toByteArray(body.asInputStream());
        }
        if (String.class.equals(type)) {
            String bodyString = Util.toString(body.asReader(Util.UTF_8));
            // 解密
            return decryptResponse(bodyString);
        }
        throw new DecodeException(response.status(),
                format("%s is not a type supported by this decoder.", type), response.request());
    }

    /**
     * 解密响应体
     *
     * @param encodedResponse 加密的响应内容
     * @return java.lang.String
     * @author Heng.Wei
     * @date 2022/4/18 18:20
     **/
    public String decryptResponse(String encodedResponse){

        FeignResponseDTO feignResponseDTO = JSON.parseObject(encodedResponse, FeignResponseDTO.class);
        String body;
        try {
            // 私钥对 secretKey 解密,得到AES KEY
            String aesKey = RSAUtil.decryptByPrivateKey(PRIVATE_KEY, feignResponseDTO.getSecretCode());
            body = AESEncryptUtil.decryptBase64(feignResponseDTO.getEncryptedData(), aesKey);
        } catch (Exception e) {
            log.error("feignResponse解密异常, 提示:{}, 异常:{}", e.getMessage(), JSON.toJSONString(e));
            throw new BusinessException("feignResponse decode exception:" + e.getMessage());
        }
        return body;
    }
}

3. 测试结果示例

feign的加解密示例

feign请求 - 加密前示例
在这里插入图片描述
FeignRequestEncoder 加密后示例
在这里插入图片描述
FeignResponseDecoder 解密前示例
在这里插入图片描述
FeignResponseDecoder 解密后示例
在这里插入图片描述

4. 其他辅助类提供 - 仅供参考

CustomFeign

import feign.HeaderMap;
import feign.RequestLine;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;

import java.net.URI;
import java.util.Map;


@FeignClient(value = "custom-feign")
public interface CustomFeign {

    @RequestLine("POST")
    String postRequest(URI baseUri, @HeaderMap Map<String, Object> headerMap, @RequestBody String request);

    @RequestLine("GET")
    String getRequest(URI baseUri, @HeaderMap Map<String, Object> headerMap, @RequestBody String request);

}

FeignClientEncryptedServiceImpl 平台统一加解密的 feignService

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;


/**
 * 动态feignClient - feign的加密请求
 * @author Heng.Wei
 * @date 2022/4/19 14:50
 **/
@Slf4j
@Component("feignClientEncryptedService")
@ConditionalOnBean({IFeignDecoder.class, IFeignEncoder.class})
public class FeignClientEncryptedServiceImpl implements IFeignClientService{

    private final CustomFeign partnerFeign;

    @Autowired
    public FeignClientEncryptedServiceImpl(@Qualifier("partnerFeign") CustomFeign partnerFeign) {
        this.partnerFeign = partnerFeign;
    }

    /**
     * POST请求远程API
     *
     * @param url 远程目标地址
     * @param header httpheader 请求头参数
     * @param content requestbody 请求体
     * @return java.lang.String requestbody 响应内容
     * @author Heng.Wei
     * @date 2022/4/19 14:45
     **/
    @Override
    public String postRequest(String url, Map<String, Object> header, String content) {
        try {
            return partnerFeign.postRequest(new URI(url), header, content);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            log.error("远程调用异常:{}", e.getMessage());
            throw new RuntimeException("postExecute exception:" + e.getMessage());
        }
    }


    /**
     * GET请求远程API
     *
     * @param url 远程目标地址
     * @param header httpheader 请求头参数
     * @param content requestbody 请求体
     * @return java.lang.String requestbody 响应内容
     * @author Heng.Wei
     * @date 2022/4/19 14:45
     **/
    @Override
    public String getRequest(String url, Map<String, Object> header, String content) {
        try {
            return partnerFeign.getRequest(new URI(url), header, content);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            log.error("远程调用异常:{}", e.getMessage());
            throw new RuntimeException("postExecute exception:" + e.getMessage());
        }
    }
}

FeignClientServiceImpl 通用的 feign service - 未作加解密操作的正常通信

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;


/**
 * 动态feignClient - feign的常规请求
 * @author Heng.Wei
 * @date 2022/4/19 14:58
 **/
@Slf4j
@Primary
@Component("feignClientService")
public class FeignClientServiceImpl implements IFeignClientService{

    private final CustomFeign customFeign;

    @Autowired
    public FeignClientServiceImpl(@Qualifier("customFeign") CustomFeign customFeign) {
        this.customFeign = customFeign;
    }

    /**
     * POST请求远程API
     *
     * @param url 远程目标地址
     * @param header httpheader 请求头参数
     * @param content requestbody 请求体
     * @return java.lang.String requestbody 响应内容
     * @author Heng.Wei
     * @date 2022/4/19 14:45
     **/
    @Override
    public String postRequest(String url, Map<String, Object> header, String content) {
        try {
            return customFeign.postRequest(new URI(url), header, content);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            log.error("远程调用异常:{}", e.getMessage());
            throw new RuntimeException("postExecute exception:" + e.getMessage());
        }
    }


    /**
     * GET请求远程API
     *
     * @param url 远程目标地址
     * @param header httpheader 请求头参数
     * @param content requestbody 请求体
     * @return java.lang.String requestbody 响应内容
     * @author Heng.Wei
     * @date 2022/4/19 14:45
     **/
    @Override
    public String getRequest(String url, Map<String, Object> header, String content) {
        try {
            return customFeign.getRequest(new URI(url), header, content);
        } catch (URISyntaxException e) {
            e.printStackTrace();
            log.error("远程调用异常:{}", e.getMessage());
            throw new RuntimeException("postExecute exception:" + e.getMessage());
        }
    }
}

FeignConfiguration 配置类

import feign.Feign;
import feign.Retryer;
import feign.Target;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.slf4j.Slf4jLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * feign配置
 *
 * @author Heng.Wei
 * @date 2022/4/19 13:52
 **/
@Slf4j
@Configuration
@Import(FeignClientsConfiguration.class)
public class FeignConfiguration {

    /**
     * 未做请求加解密的 正常的 feign 通信
     *
     * @return com.mea.pay.api.infrastructure.CustomFeign
     * @author Heng.Wei
     * @date 2022/4/20 11:46
     **/
    @Bean("customFeign")
    public CustomFeign custFeign(Decoder decoder, Encoder encoder) {
        return Feign.builder().encoder(encoder).decoder(decoder)
                .retryer(Retryer.NEVER_RETRY)
                .target(Target.EmptyTarget.create(CustomFeign.class));
    }

    /**
     * 第三方平台的feign请求
     * 走我方平台统一的 加解密协议
     * <p>
     * 这里暂时让业务服务节点自己实现 IFeignDecoder 和 IFeignEncoder 接口来使用 partnerFeign
     * 因为 partner 这块对应各个厂商的 密钥管理、如何从缓存中获取对应密钥 还没弄,弄完了的话可以再改造成通用的
     *
     * @return com.mea.pay.api.infrastructure.CustomFeign
     * @author Heng.Wei
     * @date 2022/4/19 14:33
     **/
    @Bean("partnerFeign")
    @ConditionalOnBean({IFeignDecoder.class, IFeignEncoder.class})
    public CustomFeign partnerFeign(IFeignDecoder decoder, IFeignEncoder encoder) {
        return Feign.builder().logLevel(Logger.Level.FULL)
        		.encoder(encoder).decoder(decoder)
                .retryer(Retryer.NEVER_RETRY)
                .target(Target.EmptyTarget.create(CustomFeign.class));
    }

    @Bean
    public feign.Logger logger() {
        return new Slf4jLogger();
    }

}

IFeignClientService 接口定义

package com.mea.pay.api.infrastructure;

import java.util.Map;

/**
 * 动态feignClient - 请求远程API
 * @author Heng.Wei
 * @date 2022/4/19 14:45
 **/
public interface IFeignClientService {

    /**
     * POST请求远程API
     *
     * @param url 远程目标地址
     * @param header httpheader 请求头参数
     * @param content requestbody 请求体
     * @return java.lang.String requestbody 响应内容
     * @author Heng.Wei
     * @date 2022/4/19 14:45
     **/
    String postRequest(String url, Map<String, Object> header, String content);

    /**
     * GET请求远程API
     *
     * @param url 远程目标地址
     * @param header httpheader 请求头参数
     * @param content requestbody 请求体
     * @return java.lang.String requestbody 响应内容
     * @author Heng.Wei
     * @date 2022/4/19 14:45
     **/
    String getRequest(String url, Map<String, Object> header, String content);
}

IFeignDecoder 接口定义

package com.mea.pay.api.infrastructure;

import feign.codec.Decoder;

/**
 * 自定义 feign 解密实现
 * @author Heng.Wei
 * @date 2022/4/20 11:01
 **/
public interface IFeignDecoder extends Decoder {
}

IFeignEncoder 接口定义

package com.mea.pay.api.infrastructure;

import feign.codec.Encoder;

/**
 * 自定义 feign 加密实现
 * @author Heng.Wei
 * @date 2022/4/20 11:01
 **/
public interface IFeignEncoder extends Encoder {
}

5. 使用

如下图所示,只需引入具体的service即可

  • feignClientEncryptedService 走平台统一加解密
  • feignClientService 正常的feign通信

在这里插入图片描述
亲测OK
觉得有帮助的同学请点赞哦( ̄▽ ̄)"

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

feign的加解密封装 的相关文章

  • 过滤两次 Lambda Java

    我有一个清单如下 1 2 3 4 5 6 7 和 预期结果必须是 1 2 3 4 5 6 7 我知道怎么做才能到7点 我的结果 1 2 3 4 5 6 我也想知道如何输入 7 我添加了i gt i objList size 1到我的过滤器
  • jQuery AJAX 调用 Java 方法

    使用 jQuery AJAX 我们可以调用特定的 JAVA 方法 例如从 Action 类 该 Java 方法返回的数据将用于填充一些 HTML 代码 请告诉我是否可以使用 jQuery 轻松完成此操作 就像在 DWR 中一样 此外 对于
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • 检测并缩短字符串中的所有网址

    假设我有一条字符串消息 您应该将 file zip 上传到http google com extremelylonglink zip http google com extremelylonglink zip not https stack
  • Eclipse Maven Spring 项目 - 错误

    I need help with an error which make me crazy I started to study Java EE and I am going through tutorial on youtube Ever
  • jdbc mysql loginTimeout 不起作用

    有人可以解释一下为什么下面的程序在 3 秒后超时 因为我将其设置为在 3 秒后超时 12秒 我特意关闭了mysql服务器来测试mysql服务器无法访问的这种场景 import java sql Connection import java
  • 像 Java 这样的静态类型语言中动态方法解析背后的原因是什么

    我对 Java 中引用变量的动态 静态类型和动态方法解析的概念有点困惑 考虑 public class Types Override public boolean equals Object obj System out println i
  • 为什么 Java 8 不允许非公共默认方法?

    让我们举个例子 public interface Testerface default public String example return Hello public class Tester implements Testerface
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • 我如何在java中读取二进制数据文件

    因此 我正在为学校做一个项目 我需要读取二进制数据文件并使用它来生成角色的统计数据 例如力量和智慧 它的设置是让前 8 位组成一个统计数据 我想知道执行此操作的实际语法是什么 是不是就像读文本文件一样 这样 File file new Fi
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 包 javax.el 不存在

    我正在使用 jre6 eclipse 并导入 javax el 错误 包 javax el 不存在 javac 导入 javax el 过来 这不应该是java的一部分吗 谁能告诉我为什么会这样 谢谢 米 EL 统一表达语言 是 Java
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 使用 CXF-RS 组件时,为什么我们使用 而不是普通的

    作为后续这个问题 https stackoverflow com questions 20598199 对于如何正确使用CXF RS组件我还是有点困惑 我很困惑为什么我们需要
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url
  • 通过浏览器关闭页面时出现 Websocket 错误:“已建立的连接被主机中的软件中止”

    我开发了一个实时通知系统Spring 4 代码可以在 Github 上找到 github com vdenotaris Spring Messaging https github com vdenotaris Spring Messagin
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp

随机推荐

  • 【数学】三角函数及部分微积分函数图象整理

    三角函数及部分微积分函数图象整理 1 三角函数 1 1 cosx secx 1 2 sinx cscx 1 3 tanx cotx 1 4 s e c
  • Easyx简单使用

    创建窗口大小为 initgraph 640 长 480 宽 showconsole 显示控制台 关闭窗口closegraph 绘图函数 例 画圆 radius半径 circle 无填充 fillcircle 有边框填充 solidcircl
  • Study Note:CSIN3 Chapter 2: C# Language Basic

    I should familiar with this chapter If not I should hit the wall 2 1 A First C Program I m very glad to see the first C
  • launch4j

    launch4j 3 5 win32 百度百科 http baike baidu com view 2254377 htm launch4j是Java应用程序的Windows本地 可执行文件 exe 封装器 提供了本地弹出屏幕 应用程序图标
  • 【大数据】HiveQL:索引

    HiveQL 索引 Hive 只有有限的索引功能 Hive 中没有普通关系型数据库中键的概念 但是还是可以对一些字段建立索引来加速某些操作的 一张表的索引数据存储在另外一张表中 这是一个相对比较新的功能 所以目前还没有提供很多的选择 Hiv
  • 计图:5秒训好NeRF!已开源

    金磊 转载整理自 图形学与几何计算量子位 公众号 QbitAI 计图 Jittor 框架的NeRF模型库JNeRF正式开源了 通过JNeRF可以5秒训练好NeRF模型 见图1 Jittor成为首个支持Instant NGP的深度学习框架 图
  • 实时车道线检测和智能告警

    导读 车道线检测 距离告警 转弯曲率半径计算 代码 https github com MaybeShewill CV lanenet lane detection 来自模型的车道线预测 介绍 自动驾驶将在未来十年给旅行带来革命性的变化 目前
  • 揭秘:谷歌是如何考核员工的?看看他们的OKR制度

    谷歌一直给人具有创新精神和人文关怀的公司 但其内部考评制度的曝光让人觉得 谷歌员工的压力也不小 谷歌还是小规模初创公司时 就开始使用一个叫做 目标和关键成果 Objectives and Key Results OKR的内部员工考核制度 O
  • git pull 与 git push 区别

    git pull 与 git push 区别 结论先行 1 git pull git fetch git merge 2 git fetch 只会将本地库所关联的远程库commit ID 更新到最新 3 git pull 将本地库所关联的远
  • ubuntu怎么关防火墙

    1 关闭ubuntu的防火墙 ufw disable2 卸载了iptables apt get remove iptables1 用iptables F这个命令来关闭防火墙 但是使用这个命令前 千万记得用iptables L查看一下你的系统
  • 【Qt】使用Qss设置QPushButton图标和显示文本的位置

    使用Qss设置QPushButton图标和显示文本的位置 一 背景 在开发中 经常使用到按钮作为一种输入部件 然而很多时候按钮又有不同的开发设计需求 本文重点分享 如何使用Qss来设置按钮的图标和按钮文本的位置 从而实现预期的开发效果 效果
  • ARouter(四) _ARouter类

    相对于ARouter类 ARouter类是真正内部开始做事的类 这里重点讲几个方法的作用 1 inject 方法 static void inject Object thiz AutowiredService autowiredServic
  • JS 循环发起请求

    写在前面 要求是等上一个请求完毕之后 再发起下一个请求 一般用不到 写的时候 发现forEach不行 得用for 注 我这里用setTimeOut与promise去模拟请求 步骤1 先写一个模拟请求的方法 function simulati
  • 配合小皮系统搭建Droabox靶场

    什么你还不会搭建 教你两招 无需使用命令行 即可搭建 一 将下载好的哆啦盒放进小皮系统的WWW目录下 二 启动小皮数据库 创建一个数据库 设置密码及用户 三 导入在哆啦盒文件下的pentest sql 四 打开刚刚放进小皮系统WWW目录下的
  • 前端若依框架路由跳转报错 Error: Cannot find module “@/views/xxx/xxx/xxx“

    前言 前端代码打包dist文件之后 部署后发现只有首页可以显现 然后跳转路由没生效 控制台报错 Error Cannot find module views xxx xxx xxx 原因 webpack4 不支持变量方式的动态 import
  • 十进制浮点数转成二进制(IEEE 754 在线计算器)

    IEEE 754 单精度浮点数转换 在线计算器 http www styb cn cms ieee 754 php 十进制小数的二进制表示 整数部分 除以2 取出余数 商继续除以2 直到得到0为止 将取出的余数逆序 小数部分 乘以2 然后取
  • [多尺度物体目标检测]技术概述/综述

    目录 1 绪论 1 1 引言 1 2 研究背景 1 3 研究意义 1 4 目前存在的问题 2 传统目标检测方法 2 1 HOG SVM 2 1 1 简介 2 1 2 检测流程 2 2 DPM 2 2 1 简介 2 2 2 检测流程 3 基于
  • C++拷贝构造器(Copy contructor)

    定义 由己存在的对象 创建新对象 也就是说新对象 不由构造器来构造 而是由拷贝构造器来完成 拷贝构造器的格式是固定的 class 类名 类名 const 类名 another 拷贝构造体 classA A const A another 规
  • 题目 1041: [编程入门]宏定义之找最大数

    分别用函数和带参的宏 从三个数中找出最大的数 输入格式 3个实数 输出格式 最大的数 输出两遍 先用函数 再用宏 保留3位小数 样例输入 复制 1 2 3 样例输出 复制 3 000 3 000 核心解法 我的是用三目运算符 int Max
  • feign的加解密封装

    功能描述 通过覆盖 feign codec Encoder 和 feign codec Decoder 实现 feign 请求的加解密操作 采用动态的 feignClient 调用 平台统一的通信加解密策略 同一个服务节点可以同时使用非加密