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的加解密封装 的相关文章

  • Oracle Java 教程 - 回答问题时可能出现错误

    我是 Java 新手 正在阅读 Oracle 教程 每个部分之后都有问题和答案 我不明白一个答案中的一句话 见下面的粗体线 来源是https docs oracle com javase tutorial java javaOO QandE
  • (Java) App Engine 中的静态文件无法访问

    The 示例文档 http code google com appengine docs java gettingstarted staticfiles html表示您只需将文件放在 war 或子目录 中 并且应该可以从主机访问它们 只要它
  • 删除优先级队列的尾部元素

    如何删除优先级队列的尾部元素 我正在尝试使用优先级队列实现波束搜索 一旦优先级队列已满 我想删除最后一个元素 优先级最低的元素 Thanks 没有简单的方法 将元素从原始元素复制到新元素 最后一个除外 PriorityQueue remov
  • 埃拉托色尼筛法 - 实现返回一些非质数值?

    我用 Java 实现了埃拉托斯特尼筛法 通过伪代码 public static void sieveofEratosthenes int n boolean numArray numArray new boolean n for int i
  • tomcat 7.0.50 java websocket 实现给出 404 错误

    我正在尝试使用 Java Websocket API 1 0 JSR 356 中指定的带注释端点在 tomcat 7 0 50 上实现 websocket 以下是我如何对其进行编码的简要步骤 1 使用 ServerEndpoint注解编写w
  • 在 MongoDB 和 Apache Solr 之间同步数据的简单方法

    我最近开始使用 MongoDB 和 Apache Solr 我使用 MongoDB 作为数据存储 并且希望 Apache Solr 为我的数据创建索引 以实现应用程序中的搜索功能 经过一些研究 我发现 基本上有两种方法可以在 MongoDB
  • 如何通过注解用try-catch包装方法?

    如果应该在方法调用中忽略异常 则可以编写以下内容 public void addEntryIfPresent String key Dto dto try Map
  • 如何删除日期对象的亚秒部分

    当 SQL 数据类型为时间戳时 java util Date 存储为 2010 09 03 15 33 22 246 如何在存储记录之前将亚秒设置为零 例如 在本例中为 246 最简单的方法是这样的 long time date getTi
  • Java:如何确定文件所在的驱动器类型?

    Java 是否有一种独立于平台的方法来检测文件所在的驱动器类型 基本上我有兴趣区分 硬盘 可移动驱动器 如 USB 记忆棒 和网络共享 JNI JNA 解决方案不会有帮助 可以假设 Java 7 您可以使用 Java 执行 cmd fsut
  • 寻找局部最小值

    下面的代码正确地找到了数组的局部最大值 但未能找到局部最小值 我已经进行了网络搜索 以找到找到最小值的最佳方法 并且根据这些搜索 我认为我正在使用下面的正确方法 但是 在几天的时间里多次检查每一行之后 下面的代码中有一些我仍然没有看到的错误
  • 在 Clojure 中解压缩 zlib 流

    我有一个二进制文件 其内容由zlib compress在Python上 有没有一种简单的方法可以在Clojure中打开和解压缩它 import zlib import json with open data json zlib wb as
  • 如何停止执行的 Jar 文件

    这感觉像是一个愚蠢的问题 但我似乎无法弄清楚 当我在 Windows 上运行 jar 文件时 它不会出现在任务管理器进程中 我怎样才能终止它 我已经尝试过 TASKKILL 但它对我也不起作用 On Linux ps ef grep jav
  • Lombok @Builder 不创建不可变对象?

    在很多网站上 我看到 lombok Builder 可以用来创建不可变的对象 https www baeldung com lombok builder singular https www baeldung com lombok buil
  • 集成 Spring Webflow 2 和 Apache Tiles [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我最近开始升级一些应用程序以使用 Spring Webflow 2 并且我想利用 Webflow 2
  • 如何在Java中对对象数组进行字段级别排序以进行等级比较?

    In Java Class StudentProgress String Name String Grade CTOR goes here main class main method StudentProgress arrayofObje
  • Hadoop NoSuchMethodError apache.commons.cli

    我在用着hadoop 2 7 2我用 IntelliJ 做了一个 MapReduce 工作 在我的工作中 我正在使用apache commons cli 1 3 1我把库放在罐子里 当我在 Hadoop 集群上使用 MapReduceJob
  • 何时在 hibernate 中使用 DiscriminatorValue 注解

    在 hibernate 中使用 DiscriminatorValue 注释的最佳场景是什么以及何时 这两个链接最能帮助我理解继承概念 http docs oracle com javaee 6 tutorial doc bnbqn html
  • 记录类名、方法名和行号的性能影响

    我正在我的 java 应用程序中实现日志记录 以便我可以调试应用程序投入生产后可能出现的潜在问题 考虑到在这种情况下 人们不会奢侈地使用 IDE 开发工具 以调试模式运行事物或单步执行完整代码 因此在每条消息中记录类名 方法名和行号将非常有
  • 使用 JFreeChart 为两个系列设置不同的 y 轴

    我正在使用 JFreeChart 使用折线图绘制两个数据系列 XYSeries 复杂的因素是 其中一个数据系列的 y 值通常远高于第二个数据系列的 y 值 假设第一个系列的 y 值约为数百万数量级 而第二个数据系列的 y 值约为数百万数量级
  • 将对象从手机共享到 Android Wear

    我创建了一个应用程序 在此应用程序中 您拥有包含 2 个字符串 姓名和年龄 和一个位图 头像 的对象 所有内容都保存到 sqlite 数据库中 现在我希望可以在我的智能手表上访问这些对象 所以我想实现的是你可以去启动 启动应用程序并向左和向

随机推荐

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

    三角函数及部分微积分函数图象整理 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 调用 平台统一的通信加解密策略 同一个服务节点可以同时使用非加密