SpringBoot RestTemplate 设置挡板

news2024/10/5 21:16:50

项目结构

image.png

代码

BaffleConfig

/**
 * @Description 记录配置信息
 * @Author wjx
 * @Date 2024/2/1 14:47
 **/
public interface BaffleConfig {
  
  // 是否开启挡板的开关
  public static boolean SWITCH = true;
  
  // 文件根目录
  public static String ROOT_PATH = "D:\\TIS\\mock";
  
  // http 挡板存在位置的文件名
  public static String HTTP_FILE_NAME = "http";
  
}

BaffleInfos

import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description 存储挡板信息
 * @Author wjx
 * @Date 2024/2/1 11:25
 **/
public interface BaffleInfos {

  // http请求挡板 信息(会将文件中挡板的信息存在该处,用于全局使用)  key fileName  value 挡板内容
  public static ConcurrentHashMap<String, MockClientHttpResponse> HTTP_MOCK = new ConcurrentHashMap<>();
}

InitializeBaffleInfoRunner

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;

/**
 * @Description 初始化挡板信息
 * @Author wjx
 * @Date 2024/2/1 11:38
 **/
@Slf4j
@Component
public class InitializeBaffleInfoRunner implements ApplicationRunner {
  
  @Autowired
  private BaffleRead[] baffleReads;
  
  @Override
  public void run(ApplicationArguments args) throws Exception {
    // 判断挡板开关是否开启
    if (BaffleConfig.SWITCH){
      log.warn("*****************************挡板功能开启*****************************");
      // 开启。
      Arrays.asList(baffleReads).parallelStream().forEach(e -> e.read());
    }
  }
}

BaffleRead

/**
 * @Description 读取挡板
 * @Author wjx
 * @Date 2024/2/1 14:59
 **/
public interface BaffleRead {
  
  void read();
}

MockClientHttpResponse

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

public class MockClientHttpResponse implements ClientHttpResponse {

        private final byte[] body;

        public MockClientHttpResponse(byte[] body) {
            this.body = body;
        }

        @Override
        public HttpStatus getStatusCode() throws IOException {
            return HttpStatus.OK;
        }

        @Override
        public int getRawStatusCode() throws IOException {
            return HttpStatus.OK.value();
        }

        @Override
        public String getStatusText() throws IOException {
            return HttpStatus.OK.getReasonPhrase();
        }

        @Override
        public void close() {
            // Do nothing here
        }

        @Override
        public InputStream getBody() throws IOException {
            return new ByteArrayInputStream(body);
        }

        @Override
        public HttpHeaders getHeaders() {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            return headers;
        }
    }

HttpBaffleRead

import com.tianqiauto.baffle.BaffleInfos;
import com.tianqiauto.baffle.BaffleConfig;
import com.tianqiauto.baffle.BaffleRead;
import com.tianqiauto.baffle.MockClientHttpResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;

/**
 * @Description http 挡板读取
 * @Author wjx
 * @Date 2024/2/1 14:59
 **/
@Slf4j
@Component
public class HttpBaffleRead implements BaffleRead {
  @Override
  public void read() {
    // 判断文件夹是否存在
    File file = new File(BaffleConfig.ROOT_PATH + File.separator + BaffleConfig.HTTP_FILE_NAME);
    if (file.exists()){
      // 遍历文件,异步读取,并存储
      File[] files = file.listFiles();
      Arrays.asList(files).parallelStream().forEach(e -> {
        String name = StringUtils.stripFilenameExtension(e.getName());
        byte[] bytes = new byte[0];
        try {
          bytes = Files.readAllBytes(e.toPath());
        } catch (IOException ex) {
          log.error("【挡板建设时发生错误】文件名:{}",name,ex);
        }
        MockClientHttpResponse mockClientHttpResponse = new MockClientHttpResponse(bytes);
        BaffleInfos.HTTP_MOCK.put(name,mockClientHttpResponse);
      });
    }
    
  }
}

MockHttpInterceptor

import com.tianqiauto.baffle.BaffleConfig;
import com.tianqiauto.baffle.BaffleInfos;
import com.tianqiauto.baffle.MockClientHttpResponse;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import java.io.IOException;

/**
 * @Description http 拦截
 * @Author wjx
 * @Date 2024/2/1 16:26
 **/
@Component
public class MockHttpInterceptor implements ClientHttpRequestInterceptor {
  @Override
  public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    // 判断挡板开关是否开启
    if (BaffleConfig.SWITCH){
      // 开启。读取存储空间是否有对应的挡板
      String requestPart = request.getURI().getSchemeSpecificPart();
      String fileName = RequestFilenameMapping.mapping.get(requestPart);
      // 如果有对应的挡板,将挡板内容填充
      MockClientHttpResponse mockClientHttpResponse = BaffleInfos.HTTP_MOCK.get(fileName);
      if (mockClientHttpResponse != null) return mockClientHttpResponse;
    }
    return execution.execute(request,body);
  }
}

RequestFilenameMapping

import java.util.HashMap;

/**
 * @Description 请求路径和文件名映射
 * @Author wjx
 * @Date 2024/2/1 16:56
 **/
public class RequestFilenameMapping {
  
  // key 请求路径    value 文件名
  public static HashMap<String,String> mapping;
  
  static {
    mapping = new HashMap<String,String>();
    mapping.put("//61.××××:80××/yarn","xdd1");
  }
}

添加拦截器

在这里插入图片描述

文件存储位置

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1426824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Attack Lab:Phase1~Phase5【缓冲区溢出实验】

注&#xff1a;本实验所用文件不是csapp官网给出的&#xff0c;是学校下发的。可以参考我的思路。 phase 1 本阶段目标是使getbuf调用结束后&#xff0c;控制权交给touch1函数。 则我们要知道两件事&#xff1a;一是缓冲区大小&#xff0c;二是touch1在虚拟内存中的位置。 用…

如何取消隐藏Excel中的行?这里提供详细步骤

取消隐藏Microsoft Excel电子表格中的所有行就像按下键盘快捷键或使用功能区上的按钮一样简单。我们将向你展示如何操作。 如何使用快捷方式取消隐藏Excel中的所有行 若要在电子表格中显示隐藏行&#xff0c;请使用Microsoft Excel启动电子表格。然后&#xff0c;访问包含隐藏…

P1083 [NOIP2012 提高组] 借教室

P1083 [NOIP2012 提高组] 借教室 题目描述 在大学期间&#xff0c;经常需要租借教室。大到院系举办活动&#xff0c;小到学习小组自习讨论&#xff0c;都需要向学校申请借教室。教室的大小功能不同&#xff0c;借教室人的身份不同&#xff0c;借教室的手续也不一样。 面对海…

【项目日记(七)】第三层: 页缓存的具体实现(上)

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你做项目   &#x1f51d;&#x1f51d; 开发环境: Visual Studio 2022 项目日…

Armv8-M的TrustZone技术之在安全状态和非安全状态之间切换

Armv8-M安全扩展允许在安全和非安全软件之间直接调用。 Armv8-M处理器提供了几条指令来处理状态转换: 下图显示了安全状态转换。 如果入口点的第一条指令是SG且位于非安全可调用内存位置中,则允许从非安全到安全软件的直接API函数调用。 当非安全程序调用安全API时,API通过…

Linux系统管理和Shell脚本笔试题

1、写一个sed命令&#xff0c;修改/tmp/input.txt文件的内容&#xff0c;要求&#xff1a;(1) 删除所有空行&#xff1b;(2) 在非空行前面加一个"AAA"&#xff0c;在行尾加一个"BBB"&#xff0c;即将内容为11111的一行改为&#xff1a;AAA11111BBB #写入内…

JavaWeb前端——HTML/CSS

HTML/CSS概述 HTML&#xff1a;学习标签&#xff0c;CSS&#xff1a;学习样式 HTML 1. 不区分大小写。 2. 属性可以使用单引号/双引号 3. 在记事本/编辑器中编写html语言&#xff0c;通过浏览器解析渲染语言 4. 语法结构松散&#xff08;编写时要尽量严谨&#xff09; VSc…

github请求超时解决方法

github请求超时解决办法 我使用windows执行如下git命令,提示超时 git clone xxxxx命令行提示如下&#xff1a; Failed to connect to github.com port 443: Timed out问题排查 可我Chrome可以正常访问github甚至ChatGPT&#xff0c;但是为什么在命令行里面却无法访问&#…

AI大模型开发架构设计(7)——人人都需要掌握的AI编程及应用案例实战

文章目录 人人都需要掌握的AI编程及应用案例实战1 AI代码生成模型与AI编程助手介绍程序设计方式的发展自动代码生成AI编程工具 2 AI编程助手的代码生成模型架构剖析以 CodeGeeX 为例-发展过程以 CodeGeeX 为例-训练过程以 CodeGeeX 为例-大规模代码数据处理以 CodeGeeX 为例-模…

『C++成长记』string使用指南

&#x1f525;博客主页&#xff1a;小王又困了 &#x1f4da;系列专栏&#xff1a;C &#x1f31f;人之为学&#xff0c;不日近则日退 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、string类介绍 二、string类的常用接口说明 &#x1f4d2;2.1string类对象的常…

线下店铺的商品如何查价

品牌渠道主要分为线上和线下&#xff0c;线上的价格查价方式可以通过系统完成&#xff0c;系统筛选不同平台的数据&#xff0c;然后做价格的比较&#xff0c;输出是否破价的监测报表&#xff0c;这个过程多依赖系统去操作&#xff0c;但线下店铺的产品价格查价方式则没有固定的…

Windows下Cloudreve WebDAV挂载失败解决方法

如果你正在使用Windows的资源管理器挂载WebDAV&#xff0c;并且发现挂载失败&#xff0c;无论你如何去配置他 首先&#xff0c;Cloudreve 中可以为每个用户组单独设置“是否允许使用WebDAV访问”的开关&#xff0c;但是这玩意儿默认是开启的&#xff0c;所以如果不小心手残关掉…

机器学习系列——(六)数据降维

引言 在机器学习领域&#xff0c;数据降维是一种常用的技术&#xff0c;旨在减少数据集的维度&#xff0c;同时保留尽可能多的有用信息。数据降维可以帮助我们解决高维数据带来的问题&#xff0c;提高模型的效率和准确性。本文将详细介绍机器学习中的数据降维方法和技术&#…

解锁文档处理的全新维度:ONLYOFFICE 文档开发者版

前言 相信大家对于 ONLYOFFICE 这款办公软件可能已经有所耳闻&#xff0c;最近因工作需要&#xff0c;我在众多办公协作工具中选择了 ONLYOFFICE&#xff0c;原因主要是它开源经济实惠&#xff0c;可以部署在自己的服务器上并且能够轻松集成到我们的平台中。在数字化信息时代&…

10、数据结构与算法——堆

一、什么是堆 堆是一种特殊的树形数据结构&#xff0c;通常实现为完全二叉树或满二叉树。堆又分为两种类型最大堆&#xff08;Max Heap&#xff09; 和 最小堆&#xff08;Min Heap&#xff09; 1.1、什么是二叉树 二叉树是一种数据结构&#xff0c;它是由n&#xff08;n≥0&a…

Python 计算两个时间之间的耗时

博主按照自己的需求写的一个可以计算程序耗时的函数&#xff0c;各位有需要的自行改写哈 实现的大致功能 功能1 记录开始时间&#xff0c;返回一个时间字典。数据包括&#xff1a;开始时间的日期格式、文本格式 功能2 记录结束时间和耗时&#xff0c;返回一个时间字典。数据包…

Web3智能合约:重新定义商业合作的未来

随着区块链技术的飞速发展&#xff0c;Web3时代正逐渐到来&#xff0c;而其中的智能合约成为推动商业合作变革的关键力量。本文将深入探讨Web3智能合约的概念、特点以及对商业合作未来的巨大影响。 什么是Web3智能合约&#xff1f; 智能合约是一种以代码形式编写、自动执行合同…

Oracle 面试题 | 05.精选Oracle高频面试题

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Flask 入门4:Flask 模板

1. 前言 Flask 拥有丰富的扩展方法&#xff0c;且都有统一的特点&#xff1a;简单和即学即用。当我们要实现某个功能之前&#xff0c;可以提前去搜一搜这个功能包是否已经存在&#xff0c;这样也能帮助我剩下很多时间。那么要去哪里找到这些扩展包呢&#xff0c;这里推荐两个方…

Android:RecyclerView跨行跨列的LayoutManager:Spannedgridlayoutmanager

前言&#xff1a; RecyclerView可以使用GridLayoutManager实现跨行&#xff0c;但是不能跨列&#xff1b;瀑布流布局可以跨列但是又不能跨行。原生自带的各个LayoutManager中并没有可以又跨行又能跨列的。网上搜寻了一番&#xff0c;找到了一个亲测可行好用的三方库&#xff1…