垃圾收费站
使用form-data传递数组和x-www-form-urlencoded传递的区别
项目场景:
我将后端接口的一个接收参数设计成了数组,然后前端使用form-data去传递问题描述
访问的时候出现了问题,后端接收到的数组多出了一层中括号,也就是被两层中括号包裹,获取数组的值的时候,头尾都会多半边中括号
原因分析:
反复调试了一下,确定是前端传完,后端接收时就出现的问题,猜想会不会是form-data这个传参方式不对,改成了x-www-form-urlencoded,就不会有了。form-data和x-www-form-urlencoded的区别主要体现在以下三个方面:
编码方式:x-www-form-urlencoded将表单内的数据转换为键值对,如name=java&age=23,而form-data则将表单数据处理为一条消息,以标签为单元,用分隔符分开,既可以上传键值对,也可以上传文件。
传输内容:x-www-form-urlencoded只能上传键值对,并且键值对都是间隔分开的,而form-data既可以上传文件等二进制数据,也可以上传表单键值对,只是最后会转化为一条信息。
使用情况:x-www-form-urlencoded常用于表单请求,而form-data则多用于HTTP协议的客户端向服务器端发送数据。
解决方案:
不使用数组接收参数,使用字符串约定用‘ ,’进行分隔,到时候在后端进行数据处理就行了
FFmpeg截取一个视频中的一张图
String videoPath = "D:\\班迪\\bandicam 2023-09-12 13-43-08-842.mp4";// 输入视频文件路径
String thumbnailPath = "D:\\班迪\\bandicam 2023-09-12 13-43-08-842.mp4.jpg";// 输出图片文件路径
// 构建FFmpeg命令
ProcessBuilder processBuilder = new ProcessBuilder("ffmpeg", "-i", videoPath, "-ss", "00:00:01", "-vframes", "1", thumbnailPath);
try {
// 执行FFmpeg命令
Process process = processBuilder.start();
process.waitFor();
System.out.println("截图成功");
} catch (Exception e) {
e.printStackTrace();
}
提示
在项目中引入这种插件的时候,需要考虑的东西很多,是否有引入这个插件的必要,它能给项目带来什么,会不会影响原有项目的稳定性,社区是否活跃,技术是否稳定等等。
在经过一系列考虑以后,才是将这个插件开始安装在服务器上。
安装前的准备工作
首先需要在本地,或者自己个人的服务器上先进行安装使用,
并整理安装文档,
对于出现的问题要有解决方案,将一切可能出现的问题解决在准备阶段,
最后在正式的机器上进行部署的时候也需要对具体的安装位置有对应的考量
最后安装完成后要注意是否影响其他项目
接收压缩包文件直接处理的demo
package com.hbmeta.controller;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.Charset;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author Chromer
* @title
* @description
* @date 2023/10/11 9:02
*/
@CrossOrigin
@Slf4j
@Controller
public class TestController {
@ResponseBody
@RequestMapping(value = "/test")
public String test(MultipartFile file) throws IOException {
if (file.isEmpty()){
return "文件为空";
}
//获取文件输入流
ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream(), Charset.forName("GBK"));
//定义ZipEntry置为null,避免由于重复调用zipInputStream.getNextEntry造成的不必要的问题
ZipEntry ze;
List<List<Object>> list;
StringBuffer a = new StringBuffer();
while ((ze = zipInputStream.getNextEntry()) != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (!ze.isDirectory() && ze.toString().endsWith("txt")) {
System.out.println(ze.getName());
//读取
byte[] buffer = new byte[1024];
int len;
while ((len = zipInputStream.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
System.out.println(len);
baos.flush();
InputStream stream = new ByteArrayInputStream(baos.toByteArray());
//根据txt输入流读取txt中的数据
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader buffReader = new BufferedReader(reader);
String strTmp = "";
while((strTmp = buffReader.readLine())!=null){
a.append(strTmp);
System.out.println(strTmp);
}
}
}
//关闭流
file.getInputStream().close();
zipInputStream.closeEntry();
return a.toString();
}
}
1、首先得到这个文件
使用if进行判断是否接收到这个文件
2、获取文件的输入流
这里使用zip的输入流 ,这里必须设置编码格式
ZipInputStream zipInputStream = new ZipInputStream(file.getInputStream(), Charset.forName("GBK"));
3、按字节大小读取就行了
4、最后返回一个字符串类型的数据,根据业务需求进行处理就可以了
Linux目录结构
bin目录:直接可以执行的常用命令
本身是一个文件夹的链接,实际指向的是user下的bin目录
sbin目录:系统级的系统管理命令,也是指向user目录下的sbin目录
lib目录(lib64):库目录,系统和应用文件所需要的共享库文件,等同于windows下的system文件。也是链接到user下的lib(lib64)库
boot:挂载引导分区里面存放的一些东西,单独划分分区
dev:设备目录,管理我们所有的设备
etc:系统管理所需要的配置文件,比如数据库安装完了,对应的配置文件就会放到这
home:在linux中每一个用户都有一个自己的主目录,包含普通用户的文件夹,注意:不含root用户的主文件夹
root:root用户的主文件夹
opt:可选目录,给第三方软件包划分的目录
media:可以识别一些可移动媒体设备,相当于可移动媒体设备挂载点,如:U盘,光驱
mnt:也是一个挂载点,相当于media,移动化设备的另一个挂载点
proc:进程目录
run:运行目录,系统运行以来的临时信息,系统重启就被干掉
srv:跟系统服务相关的文件
sys:存放的是系统硬件信息的相关文件
tmp:临时目录,可以操作
user:应用程序和用户相关的文件
var:可变目录,经常被修改的目录,一般放置日志什么的。
一般常用的是bin和etc目录,bin是使用命令,etc是修改配置文件
一般不建议改动的目录boot、dev、media、proc、srv、sys
Calendar对象获取当前周的bug
项目场景:
双周项目管理,需要获取当前周为一年之中的第几周,原先的代码是用Calendar对象,先用setTime()把当前时间传入,再用get(3)获取一年中的第几周
问题描述
实际发现会比真实的周少一点,且时间是周日到周六为一周
原因分析:
经排除发现,这个api的计算规则是有一定问题的。
首先它是以星期日为一周的开始,星期六为一周的结束。
解决方案:
获取当前年1号的星期几,再去用当前时间+星期几-1day得到一个时间,将这个时间传入setTime()中,get(3)得到的就是正常的当前周了
获取微信小程序二维码的bug
项目场景:
获取微信小程序二维码的bug,原来测试一直是没问题的,上线后也没啥问题,这次突然爆错
问题描述
access_token已失效或已过期
{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r rid: 64f87aca-59cf3102-17206889"}
原因分析:
重新获取access_key,正常返回图片二进制文件,随后在测试站和正式站分别测试,测试站生成新的access_key,看返回数据正常,正式站也生成新的access_key,数据正常,等待一段时间(1分钟左右,如果期间一直ping,旧的access_key也可能不失效),再分别访问正式站和测试站,其中测试站的失效,也就是生成新的access_key,旧的会失效。
解决方案:
将生成access_key的数据库保持唯一,不要测试站一个,正式站一个。