Springboot项目-实战2-实现

文章目录

    • 接口接收数据并进行数据清洗
    • mysql读取到redis
    • 接口返回参数对象
    • java函数使用备注
    • 返回参数分析
    • stream操作
    • Thread线程
    • 队列
    • 集合
    • 存储
    • 统计
    • 加密
    • 日志以及aspect对接口的时间影响?
    • war包和jar包的区别?
    • filter、interceptor、aspect区别?
    • 探针
    • Gson
    • JsonObject和JSONObject
    • hutool包的request请求
    • 网络传输 ByteBuffer
    • Base64安全方式与非安全方式
    • 最后

接口接收数据并进行数据清洗

  1. 基本信息
Java Spring Boot环境中,可以使用Spring Data JPA和Hibernate ORM来操作SQLite数据库,来实现如何创建一个接收并同步数据到服务器端数据库的RESTful API接口;
参考博客:https://blog.csdn.net/u013735734/article/details/136361244#%E9%85%8D%E7%BD%AE%20SQLite%20&%20JPA项目基础配置:
需要确保配置:Spring Data JPA和SQLite连接
参考博客:https://blog.csdn.net/zyd573803837/article/details/109263219

mysql读取到redis

通过实现CommandLineRunner接口重写run方法可以实现。

具体的run方法中,使用xxxMapper读取mysql数据,然后向RedisOpreation对象写入数据。

@Component
public class RedisDataLoader implements CommandLineRunner {@Autowiredprivate RedisOperations redisOperations;@Autowiredprivate XXXMapper xxxMapper;@Overridepublic void run(String... args) throws Exception {Object object = xxxMapper.selectById(1);redisOperations.set(key, object);}
}

接口返回参数对象

通常不同的运行情况,返回的对象是不同的。
通过采用构造方法-重载形式,可以实现该效果。
通过重载不同的静态方法,实现调用不同的构造方案。
该类需要实现Seriaizable。
需要添加@JsonInclude(JsonInclude.Include.NON_NULL),不返回参数值为null的。

@Slf4j
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResultDto implements Serializable {private String xx1;private String xx2;private String xx3;public ResultDto(String xx1, String xx2, String xx3){this.xx1 = xx1;this.xx2 = xx2;this.xx3 = xx3;}public ResultDto(String xx1, String xx2){this.xx1 = xx1;this.xx2 = xx2;}public static ResultDto result(String xx1, String xx2, String xx3){return new ResultDto(xx1, xx2, xx3);}public static ResultDto result(String xx1, String xx2){return new ResultDto(xx1, xx2);}
}

java函数使用备注

Math.min 和 Math.max函数

        int min = Math.min(111111, 111111);// 如果两个数相同,则返回其中任意一个。int max = Math.max(22,22);// 如果两个数相同,返回其中任意一个。System.out.println(min);System.out.println(max);

List集合

问题:
一个list集合执行add命令,报java.lang.NullPointerException: null  这是什么原因
分析:
List本身没有初始化,导致使用add方法的时候会报错;
list是由map.get(key)获取到的,但是key对应的value为null,也会报上述错误。

返回参数分析

一般采用JSON格式,该格式是轻量级的数据交换格式,易于人阅读和编写;
但返回值格式需要经过如下过程加以判断:

1. 使用@RestController@Controller + @ResponseBody
表示控制类的返回值直接写入HTTP的响应体,而不作为视图模型返回给视图层;2. 返回值类型
可以是原生的java对象(map)、自定义对象或者String。如果返回的是java对象,Spring自动将去转换为JSON对象;3. 响应头Content-Type
当返回为JSON格式时,响应头的Content-Tpye字段会被赋值为application/json

stream操作

情况1:

Collection<LzKey> lzKeys
LzKey errorKey = lzKeys.stream().filter(lzKey -> !validateId(lzKey.getId())).findAny().orElse(null);// 理解:
lzKeys.stream() --》 集合转换成流Stream,可以对其中的元素继续流式操作;
.filter(lzKey -> !validateId(lzKey.getId())) --》 过滤出通过getId获取到的lzKey对象无法通过validateId验证的lzKey
.findAny() --》 从结果中随机选择一个元素
.orElse(null) --》 如果存在元素就返回元素,不存在就返回null

情况2:

下划线是java7以及之后版本的数字分割符,即50000000 等于 5000_0000

情况3:

Collection<LzKey> lzKeys
Map<Integer, List<LzKey>> map = lzKeys.stream().collect(Collectors.groupingBy(lzKey -> getTableIndex(lzKey.getId())));// 理解;
lzKeys.stream() --》 将lzKeys列表转化成一个流;
.collect(....) --》 流操作的终止操作之一,收集元素并将其转化为Map类型;
Collectors.groupingBy(....) --Collector工厂方法,用于创建一个Collector实例,元素根据分类函数groupingBy进行分组;
lzKey -> getTableIndex(lzKey.getId()) --》 根据id得到tableIndex,其作为Map的key,值为lzKeys组成的列表;

情况4:

List<Integer> indexList = list.stream().map(LzKey::getId).collect(Collectors.toList());
// 理解:
list.stream() --》 基于list集合创建流
map(LzKey::getId) --》 将list集合中的lzKey对象的id元素提取出来
collect(Collectors.toList()) --》将提取出来的id组成新的ListCollections.shuffle(indexList, ThreadLocalRandom.current());
// 理解:
对indexList进行随机重排,参数2 确保多线程环境下速记数生成的安全性;

Thread线程

extends Thread:

public class function extends Thread{}
public function(int a,long b,int c) {super("ConsumerKeyThread");setDaemon(true);this.a = a;this.b = b;this.c = c;
}
// 理解:
super("ConsumerKeyThread") --》 调用父类的构造方法,传入字符串s,作为新线程的名字;
setDaemon(true) --》将创建的线程设置为守护线程;
守护线程是一种特殊的过程,它在后台运行,不会组织程序的退出,当所有的非守护线程都结束时,守护线程也将自动终止;

队列

使用1:

private ArrayBlockingQueue<LzKey> bufferKeys
// 理解:
定义阻塞队列;用于存储和管理LzKey对象;

集合

使用1:

list.forEach(key -> cache.put(key)); 
// 理解:
遍历list中的每个元素,并对元素执行cache.put操作,将每个元素都存入cache中。

存储

使用1:

long keyMemory = RamUsageEstimator.sizeOf(keysCache)/1024;
// 理解:
RamUsageEstimator.sizeOf(keysCache) --》 评估keysCache对象在内存中所占用的空间;
/1024 --》 将对象占用内存的大小,设置单位为KB;

统计

使用1:Guage

// 学习:
GaugePrometheus 支持的一种指标类型,它可以记录任意浮点数值,既可以增加也可以减少,适合用来表示像内存使用量、活跃连接数这类可以随时变化的值。Gauge CHANGE_GAUGE = Gauge.build().name("server").help("number of current.").labelNames(NAME).register();
// 理解:
Gauge.build() --》 构建一个新的Gauge对象;
.name() --》 指定名字;
.help() --》 添加描述信息;
.labelNames() --》设置标签,区分相同类型指标的不同实例;
.register() --》 构建好的Gauge注册到Prometheus的客户端库中;

加密

SM3
使用1:

String str = "12345";
String secret = "000000";
String checkSign = SmUtil.sm3WithSalt(secret.getBytes()).digestHex(str);
// secret.getBytes() 将字符串转换成字节数组
// SmUtil.sm3WithSalt() 生成SM3的盐值
// .digestHex() 执行散列运算,将转换为字节流,并将结果转为16进制字符串格式;
String out = SmUtil.sm3(str);
System.out.println(checkSign);
System.out.println(out);

日志以及aspect对接口的时间影响?

描述:某接口中,存在大量的日志处理以及通过aspect在返回结果前进行处理,这样会导致接口返回消耗更多的时间?
解决:日志通过异步处理,不影响主线程正常执行;aspect处理,优化处理逻辑;

war包和jar包的区别?

war包:可以部署到支持java web容器的服务器,比如tomcat、jetty等。可结合容器的优势,实现多实例部署和负载均衡。
jar包:通过命令行或脚本可执行该jar包,适合单机部署;

filter、interceptor、aspect区别?

filter、interceptor、aspect
分别是过滤器、拦截器、切面;
拦截顺序是:filter、interceptor、controllerAdvice、aspect、controller
filter:控制最初请求,和框架无关;作用于servlet
interceptor:可以控制请求的控制器和方法,但控制不了请求方法里的参数;作用于URL
aspect:可以自定义切入点,有方法参数,但是拿不到http请求;作用的对象可以是任何一个方法

在这里插入图片描述

探针

描述:创建ServiceTrace类,构建bind方法;案例代码:public static final TransmittableThreadLocal<BusinessTrace> BUSINESS_TRACE = new TransmittableThreadLocal<>();// ThreadLocal 允许将数据绑定到当前线程,对于跨多个方法调用 或 再同一个线程中跟踪业务逻辑特别有用;public static void bind(String serviceId, String serviceName){// 初始化或更新与线程相关的上下文信息,通常用于日志记录和跟踪分布式系统中的事务;MDC.put(SystemConsts.SERVICE_ID, serviceId);MDC.put(SystemConsts.SERVICE_NAME, serviceName);// MDC 来存储键值对,是Logback或Log4j库的一部分,用于附加诊断信息到当前线程的日志事件中;BUSINESS_TRACE.set(BusinessTrace.builder()// 创建BusinessTrace对象,.cover(Boolean.FALSE).threadId(getCurrentThreadId())// 获取当前线程的id.callerId(getCurrentCallerId())// 获取调用者的id.serviceId(serviceId).serviceName(serviceName).build());}

Gson

定义:Gson 是一个流程的java库,用于实现java对象与JSON格式,相互转换;案例:Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();// setDateFormat,表示在执行序列化/反序列化的时候,日期时间按照上述格式转化;gson.fromJson // Json -》 java对象gson.toJson // java对象 -》 Json

JsonObject和JSONObject

两者都用于处理JSON数据,但属于不同的库;
JSONObject:来自于org.json包,提供多种方法操作JSON数据,如添加键值对、获取特定键的值;
JsonObject:来自于com.google.gson包,可以用来将Java对象转化为JSON表示形式,也可以将JSON字符串转换成Java对象。

hutool包的request请求

get请求-方式1:

Map<String,String> param = new HashMap<>();
param.put("appId",appId);
param.put("version", version);
param.put("algorithm", algorithm);
param.put("timestamp",timestamp);HttpResponse response = HttpRequest.get(url).form(param).execute();
// 该方式可行;

post请求-方式1:

JsonObject requestObj = new JsonObject();
JsonObject Head = new JsonObject();
JsonObject Body = new JsonObject();
JsonObject Attache = new JsonObject();requestObj.add("HEAD",Head);
requestObj.add("BODY",Body);
requestObj.add("ATTACHED",Attache);String param = gson.toJson(requestObj);
String httpRes = HttpRequest.post(url).header(Header.ACCEPT_ENCODING, "") .body(param).execute().body();
JSONObject jsonresult = new JSONObject(httpRes);
// 该方法可行

Post请求-方式2:

JsonObject requestJson = new JsonObject();
requestJson.addProperty("aaa",aaa);
Gson gson = new Gson();HttpResponse result = HttpRequest.post(encryptLocalUrl).body(gson.toJson(requestJson)).execute();
System.out.println("请求参数:-》"+requestJson);
// 该方式不可行,参数无法通过请求传递给接口;HttpResponse result = HttpRequest.post(encryptLocalUrl).form(param).execute();
// 通过这样的方式可以实现,且param是map集合;

网络传输 ByteBuffer

Base64安全方式与非安全方式

来自于包package java.util.Base64;这个类Base64 是一种常用的二进制到文本的编码方案,常用于将二进制数据(如图片、音频等)转换成可以在文本环境中安全传输的格式。
不安全方式:
public static Encoder getEncoder() {return Encoder.RFC4648;
}
// 返回一个遵循 RFC 4648 标准的 Base64 编码器。RFC 4648 描述了 Base64 编码的标准形式,其中使用的字符包括大写字母、小写字母、数字、加号 (+) 和斜线 (/)。编码后的字符串还会使用等号 (=) 作为填充字符。
public static Decoder getDecoder() {return Decoder.RFC4648;}安全方式:
public static Encoder getUrlEncoder() {return Encoder.RFC4648_URLSAFE;
}
// 返回一个 URL 和文件名安全的 Base64 编码器。这种编码方式遵循 RFC 4648 中描述的 URL 和文件名安全的 Base64 变体。在这种情况下,加号 (+) 被替换为下划线 (_),斜线 (/) 被替换为减号 (-);
public static Decoder getUrlDecoder() {return Decoder.RFC4648_URLSAFE;}

案例:

public void  testxhj(){String data = "127.0.0.1";byte[] encode = getUrlEncoder().encode(data.getBytes());System.out.println("urlencoder:->"+new String(encode));// urlencoder:->MTI3LjAuMC4x// urlencoder:->MTI3LjAuMC4x
//        String encode1 = Base64.encode(data.getBytes());String encode1 = getEncoder().encodeToString(data.getBytes());System.out.println("encoder:->"+encode1);// encoder:->MTI3LjAuMC4x// encoder:->MTI3LjAuMC4x// 每次加密后的输出结果一样byte[] decode = getUrlDecoder().decode(encode);System.out.println("url-url decoder:——>"+new String(decode));// url-url decoder:——>127.0.0.1
//        byte[] decode1 = getDecoder().decode(encode.toString());
//        System.out.println("url-xxx decoder:——>"+new String(decode1)); // 异常byte[] decodex = getUrlDecoder().decode(encode1);System.out.println("xxx-url decoder:——>"+new String(decodex));// xxx-url decoder:——>127.0.0.1byte[] decodex1 = getDecoder().decode(encode1);System.out.println("xxx-xxx decoder:——>"+new String(decodex1));// xxx-xxx decoder:——>127.0.0.1
}

最后

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

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

相关文章

如何在 Kubernetes 上部署和配置开源数据集成平台 Airbyte?

在 Kubernetes 上部署和配置 Airbyte 是一个复杂但非常有价值的过程&#xff0c;特别是对于需要强大数据集成和数据处理能力的企业或团队。Airbyte 是一个开源的数据集成平台&#xff0c;允许用户从各种来源提取数据并加载到目标存储中。其强大的插件系统支持多种数据源与目标&…

C语言 | Leetcode C语言题解之第440题字典序的第K小数字

题目&#xff1a; 题解&#xff1a; #define MIN(x, y) ((x) < (y) ? (x) : (y))int getSteps(int curr, long n) {int steps 0;long first curr;long last curr;while (first < n) {steps MIN(last, n) - first 1;first first * 10;last last * 10 9;}return …

QT使用qss控制样式实现动态换肤

文章目录 设计QSS样式表动态加载QSS文件主函数调用QT提供了一种非常灵活的方式来使用QSS(Qt Style Sheet,类似于 CSS 的样式表),实现界面的动态换肤功能。QSS可以改变Qt应用程序中几乎所有可视组件的外观,包括颜色、字体、边框等。下面介绍一下如何通过QSS实现动态换肤。 设…

诗画紫砂壶

大家详细解答一首网络上流传的顺口溜&#xff0c;其中包含了很多的紫砂壶型。 // 紫砂壶型 // 秦权汉瓦唐羽仙&#xff0c;西施文旦美人肩。 逸公德钟对却月&#xff0c;仿鼓虚扁望方山。东坡提梁卧井栏&#xff0c;供春提璧看柿圆。荷花海棠吹松段。掇只君乐奏合欢&#xff…

vue3中< keep-alive >页面实现缓存及遇到的问题

vue3中< keep-alive >页面实现缓存及遇到的问题 实现原理&#xff1a;keep-alive 是 Vue 的内置组件&#xff0c;当它包裹动态组件时&#xff0c;会缓存不活动的组件实例&#xff0c;而不是销毁它们。实现不同路由是否缓存只需要设置对应路由参数keepAlive为true&#xf…

64.【C语言】再议结构体(下)

本文衔接第63篇63.【C语言】再议结构体(上) 目录 目录 6.复习 7.修改默认对齐数 8.结构体传参 01.传递非指针参数 02.传递指针参数(传递地址) 03.对比 9.结构体实现位段 01.位段的定义 02.格式 03.例题 答案速查 分析 10.位段跨平台问题 11.位段的应用 12.其他…

scrapy 爬取微博(五)【最新超详细解析】: 爬取微博文章

1 读取配置参数 爬取微博文章首先需要读取settings.py中的设置的配置变量&#xff0c;然后编写爬虫&#xff0c;读取的配置变量主要有爬取的关键词、时间范围、爬取区域等。 class WeiboSearchSpider(scrapy.Spider):name weibo_searchallowed_domains [weibo.com]settings…

完成UI界面的绘制

绘制UI 接上文&#xff0c;在Order90Canvas下创建Image子物体&#xff0c;图片资源ui_fish_lv1&#xff0c;设置锚点&#xff08;CountdownPanelImg同理&#xff09;&#xff0c;命名为LvPanelImg,创建Text子物体&#xff0c;边框宽高各50&#xff0c; &#xff0c;重名为LvT…

影刀---如何进行自动化操作

本文不是广告&#xff0c;没有人给我宣传费&#xff0c;只是单纯的觉得这个软件很好用 感谢大家的多多支持哦 本文 1.基本概念与操作&#xff08;非标准下拉框和上传下载&#xff09;非标准对话框的操作上传对话框、下载的对话框、提示的对话框 2.综合案例3.找不到元素怎么办&a…

css 中 ~ 符号、text-indent、ellipsis、ellipsis-2、text-overflow: ellipsis、::before的使用

1、~的使用直接看代码 <script setup> </script><template><div class"container"><p><a href"javascript:;">纪检委</a><a href"javascript:;">中介为</a><a href"javascript:…

架构师:消息队列的技术指南

1、简述 消息队列(Message Queue, MQ)是一种异步通信机制,允许系统的各个组件通过消息在彼此之间进行通信。消息队列通过解耦系统组件、缓冲高峰期请求和提高系统的可扩展性,成为分布式系统中不可或缺的一部分。 2、工作原理 消息队列的基本工作原理是生产者将消息发布到…

python爬虫案例——抓取链家租房信息(8)

文章目录 1、任务目标2、分析网页3、编写代码1、任务目标 目标站点:链家租房版块(https://bj.lianjia.com/zufang/) 要求:抓取该链接下前5页所有的租房信息,包括:标题、详情信息、详情链接、价格 如: 2、分析网页 用浏览器打开链接,按F12或右键检查,进入开发者模式;因…

Axure-本地发布,局域网内用户访问

目录 前言内容一. 选择Axure发布路径&#xff0c;进行相应配置二.添加IIS服务配置&#xff08;不在这里赘述&#xff01;&#xff09;三&#xff1a;添加IIS配置&#xff0c;创建网站四.添加安全策略&#xff1a;实践&#xff1a; 前言 最近加入了公司的积分系统&#xff0c;由…

Qt网络编程——QUdpSocket

文章目录 Qt网络编程QUdpSocketUdp回显服务器Udp客户端 Qt网络编程 网络编程本质上是写应用层代码&#xff0c;需要传输层提供支持。 而传输层最核心的协议就是UDP和TCP&#xff0c;这两个协议有较大差别&#xff0c;所以Qt提供了两套API。 要是有Qt网络编程的API&#xff0…

【CSS Tricks】css动画详解

目录 引言一、动画关键帧序列二、动画各属性拆解1. animation-name2. animation-duration3. animation-delay3.1 设置delay为正值3.2 设置delay为负值 4. animation-direction5. animation-iteration-count6. animation-fill-mode7. animation-play-state8. animation-timing-f…

Kubernetes云原生存储解决方案之 Rook Ceph实践探究

Kubernetes云原生存储解决方案之 Rook Ceph实践探究 除了手动部署独立的 Ceph 集群并配置与Kubernetes进行对接外&#xff0c;Rook Ceph 支持直接在 Kubernetes 集群上部署 Ceph 集群。 通过Rook Ceph云原生存储编排平台&#xff0c;使得 Kubernetes 集群中启用高可用的 Ceph…

RabbitMQ常用管理命令及管理后台

RabbitMQ管理命令 1、用户管理1.1、新增一个用户1.2、查看当前用户列表1.3、设置用户角色1.4、设置用户权限1.5、查看用户权限 2、RabbitMQ的web管理后台2.1、查看rabbitmq 的插件列表2.2、启用插件2.3、禁用插件2.4、访问RabbitMQ的web后台2.4、通过web页面新建虚拟主机 ./rab…

【计算机网络】详解HTTP请求和响应格式常见请求方法Header报头响应报文状态码URL

一、HTTP协议的定义 在互联网世界中&#xff0c;HTTP &#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一个至关重要的协议。它定义了客户端&#xff08;如浏览器&#xff09;与服务器之间如何通信&#xff0c;以交换或传输超文本&#xff08…

如何选择合适的跨境网络专线?

选择合适的跨境网络专线对于保障企业的国际业务顺畅运行至关重要。以下是一些选择跨境网络专线时可以参考的关键点&#xff1a; 服务商的信誉和经验&#xff1a;首先考察服务商的市场声誉和行业经验。一个好的服务商应该拥有良好的客户评价和成功案例&#xff0c;这表明他们有能…

【4.5】图搜索算法-BFS和DFS求岛屿的最大面积

一、题目 给定一个包含了一些 0 和 1 的非空二维数组 grid 。一个岛屿是由一些相邻的 1 (代表土地)构成的组合&#xff0c; 这里的「相邻」要求两个1必须在水 平或者竖直方向上相邻 。你可以假设 grid 的四个边缘都被0&#xff08;代表水&#xff09;包围着。 找到给定的二维…