JSONObject的使用方法
文件上传的文件大小配置方法
springboot默认文件大小的限制是1MB,超过1MB会出现这个错误:org.springframework.web.multipart.MultipartException。
通过设置application.yml文件属性更改文件大小限制;
spring:
servlet:
multipart:
max-request-size: 100MB #最大请求文件的大小
max-file-size: 20MB #设置单个文件最大长度
file-size-threshold: 20MB #当文件达到多少时进行磁盘写入
或者使用配置类的方式
@Configuration
public class UploadConfig {
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//单个文件最大
factory.setMaxFileSize("20480KB"); //KB,MB
/// 设置总上传数据总大小
factory.setMaxRequestSize("1024000KB");
return factory.createMultipartConfig();
}
}
文件上传操作
/**
* 1.文件保存在服务器,url地址保存在数据库
* 上传成功之后返回成功保存的url地址
*/
@PostMapping("/upload")
public @ResponseBody String upload(@RequestParam MultipartFile file, HttpServletRequest request){
if(!file.isEmpty()){
String uploadPath = "C:\\uploadFile";
// 如果目录不存在则创建
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}
String OriginalFilename = file.getOriginalFilename();//获取原文件名
String suffixName = OriginalFilename.substring(OriginalFilename.lastIndexOf("."));//获取文件后缀名
//重新随机生成名字
String filename = UUID.randomUUID().toString() +suffixName;
File localFile = new File(uploadPath+"\\"+filename);
try {
file.transferTo(localFile); //把上传的文件保存至本地
/**
* 这里应该把filename保存到数据库,供前端访问时使用
*/
return filename;//上传成功,返回保存的文件地址
}catch (IOException e){
e.printStackTrace();
System.out.println("上传失败");
return "";
}
}else{
System.out.println("文件为空");
return "";
}
}
还可以参考网址,我觉得这里面写的也很好
实现文件预览功能
@GetMapping("/preview/{dirName:.+}/{fileName:.+}")
@ApiOperation(value = "根据文件名实现预览功能")
public void previewFile(@PathVariable String dirName,
@PathVariable String fileName, HttpServletResponse response) throws IOException {
showImg("./"+storageProperties.getLocation()+"/"+dirName+"/"+fileName, response);
}
public static void showImg(String path, HttpServletResponse response){
if(path!=null&&!path.equals("")){
try {
FileInputStream fis = new FileInputStream(path);
ServletOutputStream os = response.getOutputStream();
byte [] b = new byte[1024*8];
while(fis.read(b)!=-1){
os.write(b);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
参考网址:Springboot实现上传文件以及文件实时预览(包括图片预览,视频预览)
Maven添加本地依赖
参考网址:maven使用本地jar以及pom文件中${project.basedir}
<dependency>
<groupId>org.patchca</groupId>
<artifactId>patchca</artifactId>
<version>0.5.0</version>
<systemPath>${project.basedir}/lib/patchca-0.5.0.jar</systemPath>
</dependency>
project 是 pom.xml 的根节点, project.basedir 就是pom文件所在的目录。
${project.basedir}/…/ 其中…表示跳到上级目录
<dependency>
<groupId>com.xxx.akkg</groupId>
<artifactId>akkg</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../lib/akkg.jar</systemPath>
</dependency>
Java实现定时器
方式1:使用Timer和TimerTask类
1、Timer和TimerTask是java.util包下的类,用于实现定时任务
步骤1:创建TimerTask定时器任务,可以通过匿名内部类的方式创建
步骤2:创建Timer定时器,调用定时器的方法执行定时器任务
2、Timer的两个方法schedule()和scheduleAtFixedRate():
①schedule(TimerTask task, long delay):在指定时间后执行1次任务,其中delay表示时延,单位是毫秒,设置为1000,则表示1秒后执行一次定时器任务;
②schedule(TimerTask task, long delay, long period):指定延迟指定时间后周期性地执行任务(每period毫秒执行一次),和scheduleAtFixedRate(TimerTask task, long delay, long period)的效果一样;
③这两个方法还有一个参数包含Date对象的重载方法,尝试运行报错,在这里就不介绍了。
public class TimerExample {
public static void main(String[] args) {
// 创建定时器任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("Hello world!");
}
};
// 创建定时器
Timer timer = new Timer();
timer.schedule(timerTask, 5);
timer.schedule(timerTask, 5, 5000);
timer.scheduleAtFixedRate(timerTask, 5, 5000);
}
}
方法2:使用线程池
其中线程池的方法使用和Timer一样,TimeUnit是一个枚举类型,用于指定时间单位,有NANOSECONDS(纳秒)、MICROSECONDS(微秒)、MILISECONDS(毫秒)、SECONDS(秒)、MINUTE(分钟)、HOURS(小时)和DAYS(天)。
public class TimerExample {
public static void main(String[] args) {
// 创建定时器任务
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
System.out.println("Hello world!");
}
};
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.schedule(timerTask, 1000, TimeUnit.MILLISECONDS);
scheduledThreadPool.scheduleAtFixedRate(timerTask, 1000, 1000, TimeUnit.MILLISECONDS);
}
}
方法3:使用Spring Task
步骤1:在springBoot启动类上添加@EnableScheduling注解
@EnableScheduling
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
步骤2:创建一个定时任务类的bean,在类的方法上使用@Schedule注解,通过注解的cron属性设置定时器的属性
@Component
public class TimerTask {
@Scheduled(cron = "0 7 2 26 7 *")
public void task() {
System.out.println("定时任务...");
}
}
以上代码指定在2022年7月26日02:07:00执行一次定时任务,对cron表达式感兴趣的可以去了解一下,这里就不介绍了。
方法4:通过Quartz任务调度工具
步骤1:创建quartz的配置类
@Configuration
public class QuartzConfig {
// 创建一个JobDetail(工作详情)类对象,保存到Spring容器中,这个类用于封装我们编写的job接口实现类
@Bean
public JobDetail jobDetail(){
System.out.println("showTime方法运行");
return JobBuilder.newJob(QuartzJob.class) // 绑定要运行的任务类的类对象
.withIdentity("job") // 设置job的名称
.storeDurably() // 信息持久
// 设置storeDurably之后,当没有触发器指向这个JobDetail时,JobDetail也不会从
// Spring容器中删除,如果不设置这行,就会自动从Spring容器中删除
.build();
}
// 声明触发器,触发器决定我们的工作\任务何时触发
@Bean
public Trigger trigger(){
System.out.println("showTime触发器运行");
// 定义Cron表达式,每分钟触发一次
CronScheduleBuilder cronScheduleBuilder =
CronScheduleBuilder.cronSchedule("0/10 * * * * ?");
return TriggerBuilder.newTrigger()
.forJob(jobDetail()) // 绑定JobDetail对象
.withIdentity("trigger") // 定义触发器名称
.withSchedule(cronScheduleBuilder) // 绑定Cron表达式
.build();
}
}
步骤2:定义Job
public class QuartzJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext) {
// 输出当前时间
System.out.println(LocalDateTime.now());
}
}
Spring 实现动态定时任务
这篇文章也写的很不错:Spring 实现动态定时任务 这篇文章实现的是动态定时任务
实质上是服务启动时,将cron表达式注册到触发器trigger中,然后,每次在cron表达式的时间到来时执行任务,并且重新将cron表达式再次在触发器中注册,以达到动态进行定时任务的功能
cron表达式详解
cron表达式时spring定时执行任务的关键
参考文章:cron表达式详解,cron表达式写法,cron表达式例子
cron表达式格式:
{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}
例 “0 0 12 ? * WED” 在每星期三下午12:00 执行(年份通常 省略)
每个字段允许的值
字段 允许值 允许的特殊字符
- 秒 0-59 , - * /
- 分 0-59 , - * /
- 小时 0-23 , - * /
- 日期 1-31 , - * ? / L W C
- 月份 1-12 或者 JAN-DEC , - * /
- 星期 1-7 或者 SUN-SAT , - * ? / L C #
- 年(可选) 留空, 1970-2099 , - * /
允许值的意思:
Seconds (秒) :可以用数字0-59 表示,
Minutes(分) :可以用数字0-59 表示,
Hours(时) :可以用数字0-23表示,
Day-of-Month(天) :可以用数字1-31 中的任一一个值,但要注意一些特别的月份
Month(月) :可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
Day-of-Week(每周):可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
表达式中特殊符号的含义
*表示所有值;
? 表示未说明的值,即不关心它为何值,一般只在日和星期(周)中指定作用,其作用为不指定具体的时间;
-表示一个指定的范围;
, 表示附加一个可能值;
/ 符号前表示开始时间,符号后表示每次递增的值;
L(“last”) (“last”) “L” 用在day-of-month字段意思是 “这个月最后一天”;用在 day-of-week字段, 它简单意思是 “7” or “SAT”。 如果在day-of-week字段里和数字联合使用,它的意思就是 “这个月的最后一个星期几” – 例如: “6L” means “这个月的最后一个星期五”. 当我们用“L”时,不指明一个列表值或者范围是很重要的,不然的话,我们会得到一些意想不到的结果。
W(“weekday”) 只能用在day-of-month字段。用来描叙最接近指定天的工作日(周一到周五)。例如:在day-of-month字段用“15W”指“最接近这个 月第15天的工作日”,即如果这个月第15天是周六,那么触发器将会在这个月第14天即周五触发;如果这个月第15天是周日,那么触发器将会在这个月第 16天即周一触发;如果这个月第15天是周二,那么就在触发器这天触发。注意一点:这个用法只会在当前月计算值,不会越过当前月。“W”字符仅能在 day-of-month指明一天,不能是一个范围或列表。也可以用“LW”来指定这个月的最后一个工作日。
#只能用在day-of-week字段。用来指定这个月的第几个周几。例:在day-of-week字段用"6#3"指这个月第3个周五(6指周五,3指第3个)。如果指定的日期不存在,触发器就不会触发。
C 指和calendar联系后计算过的值。例:在day-of-month 字段用“5C”指在这个月第5天或之后包括calendar的第一天;在day-of-week字段用“1C”指在这周日或之后包括calendar的第一天
yaml文件中配置添加带空格的字符串
使用单引号,特殊字符不会转义,使用双引号,则特殊字符会被转义
关于在测试文件夹中添加配置类是否会在主程序运行的过程中注入
在测试文件中添加的配置类不会在运行主程序的过程中注入到spring容器中
Springboot中,各种代码运行顺序问题
参考文章:Spring Boot 启动时自动执行代码的4种方式
- 运行被标记为组件(@Component,包括标记为@Service这样注解的各种组件)的static的代码块(静态代码块)
- 执行被标记为组件的构造器
- 执行被标记为组件中添加了@PostConstruct的方法
- 根据@Order(“序号值”)中的序号值顺序执行实现了
ApplicationRunner
或CommandLineRunner
类中的run()方法,序号值越小,执行顺序越靠前
类的各部分的执行顺序
- 首先执行静态代码块
- 执行非静态代码块
- 执行构造器
Java属性赋值顺序
- 属性的默认初始化(即直接定义属性,并未对属性赋值)
- 显示初始化(在定义变量后直接使用=赋值)
- (优先级与2并列,谁写在前谁先执行)代码块初始化
- 构造器初始化
- 使用变量.属性赋值
关于Springboot单元测试启动不了
- 查看test文件夹所在位置和test文件夹的层级结构是否与主启动类在同一位置(相同文件夹)
配置文件的使用,日志部分
我们知道配置文件可以配置多个环境,但是当有多个环境的时候,在主配置文件中写的日志信息会使用到所有的配置文件中,在其他配置文件中使用的日志配置将会被主配置文件覆盖
分析各种常见数据所占位数
1个字节:8位(byte)
1个字:2个字节 16位
1位: (bit)比特是表示信息的最小单位,是二进制数的一位包含的信息
1个十六进制位(数):0.5个字节,即4位(4bit),0x01占1个字节长度
swagger测试Date类型参数出现转换失败的情况
- get请求:在@RequestParm(“变量名”)注解后添加注解@DateTimeFomat(pattern = “yyyy-MM-dd HH:mm:ss”),即可
- post请求,且形参列表中接收为@RequestBody ,则在VO类上添加注解
@ApiModelProperty(value = "开始时间", example = "2021-10-05 00:00:00")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
WSDL
Web Service描述语言WSDL 就是用机器能阅读的方式提供的一个正式描述文档而基于XML(标准通用标记语言下的一个子集)的语言,用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。
一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应Web service的代码。