mirror of
https://github.com/chillzhuang/blade-tool
synced 2024-12-12 12:19:27 +08:00
🎉 2.3.2.RELEASE
This commit is contained in:
parent
adcd42b62a
commit
1d6f118774
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -75,7 +75,7 @@ mybatis-plus:
|
||||
swagger:
|
||||
title: SpringBlade 接口文档系统
|
||||
description: SpringBlade 接口文档系统
|
||||
version: 2.3.1
|
||||
version: 2.3.2
|
||||
license: Powered By SpringBlade
|
||||
licenseUrl: https://bladex.vip
|
||||
terms-of-service-url: https://bladex.vip
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -27,6 +27,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 项目启动器,搞定环境变量问题
|
||||
@ -100,8 +101,10 @@ public class BladeApplication {
|
||||
props.setProperty("spring.cloud.nacos.config.file-extension", NacosConstant.NACOS_CONFIG_FORMAT);
|
||||
props.setProperty("spring.cloud.sentinel.transport.dashboard", SentinelConstant.SENTINEL_ADDR);
|
||||
// 加载自定义组件
|
||||
ServiceLoader<LauncherService> loader = ServiceLoader.load(LauncherService.class);
|
||||
loader.forEach(launcherService -> launcherService.launcher(builder, appName, profile));
|
||||
List<LauncherService> launcherList = new ArrayList<>();
|
||||
ServiceLoader.load(LauncherService.class).forEach(launcherList::add);
|
||||
launcherList.stream().sorted(Comparator.comparing(LauncherService::getOrder)).collect(Collectors.toList())
|
||||
.forEach(launcherService -> launcherService.launcher(builder, appName, profile));
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ public interface AppConstant {
|
||||
/**
|
||||
* 应用版本
|
||||
*/
|
||||
String APPLICATION_VERSION = "2.3.1";
|
||||
String APPLICATION_VERSION = "2.3.2";
|
||||
|
||||
/**
|
||||
* 基础包
|
||||
@ -68,6 +68,10 @@ public interface AppConstant {
|
||||
* 开发模块名称
|
||||
*/
|
||||
String APPLICATION_DEVELOP_NAME = APPLICATION_NAME_PREFIX + "develop";
|
||||
/**
|
||||
* 资源模块名称
|
||||
*/
|
||||
String APPLICATION_RESOURCE_NAME = APPLICATION_NAME_PREFIX + "resource";
|
||||
/**
|
||||
* 测试模块名称
|
||||
*/
|
||||
|
@ -16,13 +16,14 @@
|
||||
package org.springblade.core.launch.service;
|
||||
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* launcher 扩展 用于一些组件发现
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface LauncherService {
|
||||
public interface LauncherService extends Ordered, Comparable<LauncherService> {
|
||||
|
||||
/**
|
||||
* 启动时 处理 SpringApplicationBuilder
|
||||
@ -33,4 +34,25 @@ public interface LauncherService {
|
||||
*/
|
||||
void launcher(SpringApplicationBuilder builder, String appName, String profile);
|
||||
|
||||
/**
|
||||
* 获取排列顺序
|
||||
*
|
||||
* @return order
|
||||
*/
|
||||
@Override
|
||||
default int getOrder() {
|
||||
return Ordered.HIGHEST_PRECEDENCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对比排序
|
||||
*
|
||||
* @param o LauncherService
|
||||
* @return compare
|
||||
*/
|
||||
@Override
|
||||
default int compareTo(LauncherService o) {
|
||||
return Integer.compare(this.getOrder(), o.getOrder());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
32
blade-core-oss/pom.xml
Normal file
32
blade-core-oss/pom.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>blade-core-oss</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<version>${blade.tool.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!--Blade-->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-tool</artifactId>
|
||||
<version>${blade.tool.version}</version>
|
||||
</dependency>
|
||||
<!--QiNiu-->
|
||||
<dependency>
|
||||
<groupId>com.qiniu</groupId>
|
||||
<artifactId>qiniu-java-sdk</artifactId>
|
||||
<version>7.2.18</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.oss;
|
||||
|
||||
import com.qiniu.common.Zone;
|
||||
import com.qiniu.http.Response;
|
||||
import com.qiniu.storage.BucketManager;
|
||||
import com.qiniu.storage.UploadManager;
|
||||
import com.qiniu.storage.model.FileInfo;
|
||||
import com.qiniu.util.Auth;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springblade.core.oss.model.BladeFile;
|
||||
import org.springblade.core.oss.model.OssFile;
|
||||
import org.springblade.core.oss.props.OssProperties;
|
||||
import org.springblade.core.oss.rule.OssRule;
|
||||
import org.springblade.core.tool.utils.CollectionUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* QiniuTemplate
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class QiniuTemplate {
|
||||
private Auth auth;
|
||||
private UploadManager uploadManager;
|
||||
private BucketManager bucketManager;
|
||||
private OssProperties ossProperties;
|
||||
private OssRule ossRule;
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void makeBucket(String bucketName) {
|
||||
if (!CollectionUtil.contains(bucketManager.buckets(), getBucketName(bucketName))) {
|
||||
bucketManager.createBucket(getBucketName(bucketName), Zone.zone0().getRegion());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void removeBucket(String bucketName) {
|
||||
bucketManager.deleteBucket(getBucketName(bucketName));
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public boolean bucketExists(String bucketName) {
|
||||
return CollectionUtil.contains(bucketManager.buckets(), getBucketName(bucketName));
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void copyFile(String bucketName, String fileName, String destBucketName) {
|
||||
bucketManager.copy(getBucketName(bucketName), fileName, getBucketName(destBucketName), fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void copyFile(String bucketName, String fileName, String destBucketName, String destFileName) {
|
||||
bucketManager.copy(getBucketName(bucketName), fileName, getBucketName(destBucketName), destFileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public OssFile statFile(String fileName) {
|
||||
return statFile(ossProperties.getBucketName(), fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public OssFile statFile(String bucketName, String fileName) {
|
||||
FileInfo stat = bucketManager.stat(getBucketName(bucketName), fileName);
|
||||
OssFile ossFile = new OssFile();
|
||||
ossFile.setName(stat.key);
|
||||
ossFile.setName(Func.isEmpty(stat.key) ? fileName : stat.key);
|
||||
ossFile.setLink(fileLink(ossFile.getName()));
|
||||
ossFile.setHash(stat.hash);
|
||||
ossFile.setLength(stat.fsize);
|
||||
ossFile.setPutTime(new Date(stat.putTime / 10000));
|
||||
ossFile.setContentType(stat.mimeType);
|
||||
return ossFile;
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public String filePath(String fileName) {
|
||||
return getBucketName().concat(StringPool.SLASH).concat(fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public String filePath(String bucketName, String fileName) {
|
||||
return getBucketName(bucketName).concat(StringPool.SLASH).concat(fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public String fileLink(String fileName) {
|
||||
return ossProperties.getEndpoint().concat(StringPool.SLASH).concat(fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public String fileLink(String bucketName, String fileName) {
|
||||
return ossProperties.getEndpoint().concat(StringPool.SLASH).concat(fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public BladeFile putFile(MultipartFile file) {
|
||||
return putFile(ossProperties.getBucketName(), file.getOriginalFilename(), file);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public BladeFile putFile(String fileName, MultipartFile file) {
|
||||
return putFile(ossProperties.getBucketName(), fileName, file);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public BladeFile putFile(String bucketName, String fileName, MultipartFile file) {
|
||||
return putFile(bucketName, fileName, file);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public BladeFile putFile(String fileName, InputStream stream) {
|
||||
return putFile(ossProperties.getBucketName(), fileName, stream);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public BladeFile putFile(String bucketName, String fileName, InputStream stream) {
|
||||
return put(bucketName, stream, fileName, false);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public BladeFile put(String bucketName, InputStream stream, String key, boolean cover) {
|
||||
makeBucket(bucketName);
|
||||
key = getFileName(key);
|
||||
// 覆盖上传
|
||||
if (cover) {
|
||||
uploadManager.put(stream, key, getUploadToken(bucketName, key), null, null);
|
||||
} else {
|
||||
Response response = uploadManager.put(stream, key, getUploadToken(bucketName), null, null);
|
||||
int retry = 0;
|
||||
int retryCount = 5;
|
||||
while (response.needRetry() && retry < retryCount) {
|
||||
response = uploadManager.put(stream, key, getUploadToken(bucketName), null, null);
|
||||
retry++;
|
||||
}
|
||||
}
|
||||
BladeFile file = new BladeFile();
|
||||
file.setName(key);
|
||||
file.setLink(fileLink(bucketName, key));
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void removeFile(String fileName) {
|
||||
bucketManager.delete(getBucketName(), fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void removeFile(String bucketName, String fileName) {
|
||||
bucketManager.delete(getBucketName(bucketName), fileName);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void removeFiles(List<String> fileNames) {
|
||||
fileNames.forEach(this::removeFile);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public void removeFiles(String bucketName, List<String> fileNames) {
|
||||
fileNames.forEach(fileName -> removeFile(getBucketName(bucketName), fileName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据规则生成存储桶名称规则
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
private String getBucketName() {
|
||||
return getBucketName(ossProperties.getBucketName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据规则生成存储桶名称规则
|
||||
*
|
||||
* @param bucketName 存储桶名称
|
||||
* @return String
|
||||
*/
|
||||
private String getBucketName(String bucketName) {
|
||||
return ossRule.bucketName(bucketName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据规则生成文件名称规则
|
||||
*
|
||||
* @param originalFilename 原始文件名
|
||||
* @return string
|
||||
*/
|
||||
private String getFileName(String originalFilename) {
|
||||
return ossRule.fileName(originalFilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传凭证,普通上传
|
||||
*/
|
||||
public String getUploadToken(String bucketName) {
|
||||
return auth.uploadToken(getBucketName(bucketName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传凭证,覆盖上传
|
||||
*/
|
||||
private String getUploadToken(String bucketName, String key) {
|
||||
return auth.uploadToken(getBucketName(bucketName), key);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.oss.config;
|
||||
|
||||
import com.qiniu.common.Zone;
|
||||
import com.qiniu.storage.BucketManager;
|
||||
import com.qiniu.storage.UploadManager;
|
||||
import com.qiniu.util.Auth;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.oss.QiniuTemplate;
|
||||
import org.springblade.core.oss.props.OssProperties;
|
||||
import org.springblade.core.oss.rule.BladeOssRule;
|
||||
import org.springblade.core.oss.rule.OssRule;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Oss配置类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableConfigurationProperties(OssProperties.class)
|
||||
@ConditionalOnProperty(value = "oss.enable", havingValue = "true")
|
||||
public class OssConfiguration {
|
||||
|
||||
private OssProperties ossProperties;
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(OssRule.class)
|
||||
public OssRule ossRule() {
|
||||
return new BladeOssRule();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public com.qiniu.storage.Configuration qiniuConfiguration() {
|
||||
return new com.qiniu.storage.Configuration(Zone.zone0());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Auth auth() {
|
||||
return Auth.create(ossProperties.getAccessKey(), ossProperties.getSecretKey());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(com.qiniu.storage.Configuration.class)
|
||||
public UploadManager uploadManager(com.qiniu.storage.Configuration cfg) {
|
||||
return new UploadManager(cfg);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(com.qiniu.storage.Configuration.class)
|
||||
public BucketManager bucketManager(com.qiniu.storage.Configuration cfg) {
|
||||
return new BucketManager(auth(), cfg);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(QiniuTemplate.class)
|
||||
@ConditionalOnBean({Auth.class, UploadManager.class, BucketManager.class, OssRule.class})
|
||||
public QiniuTemplate qiniuTemplate(Auth auth, UploadManager uploadManager, BucketManager bucketManager, OssRule ossRule) {
|
||||
return new QiniuTemplate(auth, uploadManager, bucketManager, ossProperties, ossRule);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.oss.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* BladeFile
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class BladeFile {
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
private String link;
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String name;
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.oss.model;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* OssFile
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class OssFile {
|
||||
/**
|
||||
* 文件地址
|
||||
*/
|
||||
private String link;
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 文件hash值
|
||||
*/
|
||||
public String hash;
|
||||
/**
|
||||
* 文件大小
|
||||
*/
|
||||
private long length;
|
||||
/**
|
||||
* 文件上传时间
|
||||
*/
|
||||
private Date putTime;
|
||||
/**
|
||||
* 文件contentType
|
||||
*/
|
||||
private String contentType;
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.oss.props;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* Minio参数配置类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "oss")
|
||||
public class OssProperties {
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Boolean enable;
|
||||
|
||||
/**
|
||||
* 对象存储名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 是否开启租户模式
|
||||
*/
|
||||
private Boolean tenantMode;
|
||||
|
||||
/**
|
||||
* 对象存储服务的URL
|
||||
*/
|
||||
private String endpoint;
|
||||
|
||||
/**
|
||||
* Access key就像用户ID,可以唯一标识你的账户
|
||||
*/
|
||||
private String accessKey;
|
||||
|
||||
/**
|
||||
* Secret key是你账户的密码
|
||||
*/
|
||||
private String secretKey;
|
||||
|
||||
/**
|
||||
* 默认的存储桶名称
|
||||
*/
|
||||
private String bucketName = "bladex";
|
||||
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.oss.rule;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springblade.core.tool.utils.FileUtil;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
|
||||
/**
|
||||
* 默认存储桶生成规则
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
public class BladeOssRule implements OssRule {
|
||||
|
||||
@Override
|
||||
public String bucketName(String bucketName) {
|
||||
return bucketName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fileName(String originalFilename) {
|
||||
return "upload" + StringPool.SLASH + DateUtil.today() + StringPool.SLASH + StringUtil.randomUUID() + StringPool.DOT + FileUtil.getFileExtension(originalFilename);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.oss.rule;
|
||||
|
||||
/**
|
||||
* Oss通用规则
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface OssRule {
|
||||
|
||||
/**
|
||||
* 获取存储桶规则
|
||||
*
|
||||
* @param bucketName 存储桶名称
|
||||
* @return String
|
||||
*/
|
||||
String bucketName(String bucketName);
|
||||
|
||||
/**
|
||||
* 获取文件名规则
|
||||
*
|
||||
* @param originalFilename 文件名
|
||||
* @return String
|
||||
*/
|
||||
String fileName(String originalFilename);
|
||||
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<groupId>org.springblade</groupId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -53,7 +53,7 @@ public class SwaggerProperties {
|
||||
/**
|
||||
* 版本
|
||||
**/
|
||||
private String version = "2.3.1";
|
||||
private String version = "2.3.2";
|
||||
/**
|
||||
* 许可证
|
||||
**/
|
||||
|
31
blade-core-test/pom.xml
Normal file
31
blade-core-test/pom.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>blade-core-test</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<version>${blade.tool.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<!-- Blade -->
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-launch</artifactId>
|
||||
<version>${blade.tool.version}</version>
|
||||
</dependency>
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springblade.core.test;
|
||||
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
|
||||
/**
|
||||
* boot test 基类
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@RunWith(BladeSpringRunner.class)
|
||||
public abstract class BladeBaseTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springblade.core.test;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 简化 测试
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@SpringBootTest
|
||||
public @interface BladeBootTest {
|
||||
/**
|
||||
* 服务名:appName
|
||||
* @return appName
|
||||
*/
|
||||
@AliasFor("appName")
|
||||
String value() default "blade-test";
|
||||
/**
|
||||
* 服务名:appName
|
||||
* @return appName
|
||||
*/
|
||||
@AliasFor("value")
|
||||
String appName() default "blade-test";
|
||||
/**
|
||||
* profile
|
||||
* @return profile
|
||||
*/
|
||||
String profile() default "dev";
|
||||
/**
|
||||
* 启用 ServiceLoader 加载 launcherService
|
||||
* @return 是否启用
|
||||
*/
|
||||
boolean enableLoader() default false;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springblade.core.test;
|
||||
|
||||
/**
|
||||
* blade test 异常
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
class BladeBootTestException extends RuntimeException {
|
||||
|
||||
BladeBootTestException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springblade.core.test;
|
||||
|
||||
|
||||
import org.junit.runners.model.InitializationError;
|
||||
import org.springblade.core.launch.BladeApplication;
|
||||
import org.springblade.core.launch.constant.AppConstant;
|
||||
import org.springblade.core.launch.constant.NacosConstant;
|
||||
import org.springblade.core.launch.constant.SentinelConstant;
|
||||
import org.springblade.core.launch.service.LauncherService;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 设置启动参数
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public class BladeSpringRunner extends SpringJUnit4ClassRunner {
|
||||
|
||||
public BladeSpringRunner(Class<?> clazz) throws InitializationError {
|
||||
super(clazz);
|
||||
setUpTestClass(clazz);
|
||||
}
|
||||
|
||||
private void setUpTestClass(Class<?> clazz) {
|
||||
BladeBootTest bladeBootTest = AnnotationUtils.getAnnotation(clazz, BladeBootTest.class);
|
||||
if (bladeBootTest == null) {
|
||||
throw new BladeBootTestException(String.format("%s must be @BladeBootTest .", clazz));
|
||||
}
|
||||
String appName = bladeBootTest.appName();
|
||||
String profile = bladeBootTest.profile();
|
||||
boolean isLocalDev = BladeApplication.isLocalDev();
|
||||
Properties props = System.getProperties();
|
||||
props.setProperty("blade.env", profile);
|
||||
props.setProperty("blade.name", appName);
|
||||
props.setProperty("blade.is-local", String.valueOf(isLocalDev));
|
||||
props.setProperty("blade.dev-mode", profile.equals(AppConstant.PROD_CODE) ? "false" : "true");
|
||||
props.setProperty("blade.service.version", AppConstant.APPLICATION_VERSION);
|
||||
props.setProperty("spring.application.name", appName);
|
||||
props.setProperty("spring.profiles.active", profile);
|
||||
props.setProperty("info.version", AppConstant.APPLICATION_VERSION);
|
||||
props.setProperty("info.desc", appName);
|
||||
props.setProperty("spring.cloud.nacos.discovery.server-addr", NacosConstant.NACOS_ADDR);
|
||||
props.setProperty("spring.cloud.nacos.config.server-addr", NacosConstant.NACOS_ADDR);
|
||||
props.setProperty("spring.cloud.nacos.config.prefix", NacosConstant.NACOS_CONFIG_PREFIX);
|
||||
props.setProperty("spring.cloud.nacos.config.file-extension", NacosConstant.NACOS_CONFIG_FORMAT);
|
||||
props.setProperty("spring.cloud.sentinel.transport.dashboard", SentinelConstant.SENTINEL_ADDR);
|
||||
props.setProperty("spring.main.allow-bean-definition-overriding", "true");
|
||||
// 加载自定义组件
|
||||
if (bladeBootTest.enableLoader()) {
|
||||
List<LauncherService> launcherList = new ArrayList<>();
|
||||
SpringApplicationBuilder builder = new SpringApplicationBuilder(clazz);
|
||||
ServiceLoader.load(LauncherService.class).forEach(launcherList::add);
|
||||
launcherList.stream().sorted(Comparator.comparing(LauncherService::getOrder)).collect(Collectors.toList())
|
||||
.forEach(launcherService -> launcherService.launcher(builder, appName, profile));
|
||||
}
|
||||
System.err.println(String.format("---[junit.test]:[%s]---启动中,读取到的环境变量:[%s]", appName, profile));
|
||||
}
|
||||
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.tool.utils;
|
||||
|
||||
/**
|
||||
* char 常量池
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public interface CharPool {
|
||||
|
||||
char UPPER_A = 'A';
|
||||
char LOWER_A = 'a';
|
||||
char UPPER_Z = 'Z';
|
||||
char LOWER_Z = 'z';
|
||||
char DOT = '.';
|
||||
char AT = '@';
|
||||
char LEFT_BRACE = '{';
|
||||
char RIGHT_BRACE = '}';
|
||||
char LEFT_BRACKET = '(';
|
||||
char RIGHT_BRACKET = ')';
|
||||
|
||||
}
|
@ -1,119 +1,264 @@
|
||||
/**
|
||||
* Copyright (c) 2018-2028, DreamLu 卢春梦 (qq596392912@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.core.tool.utils;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.time.*;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.Temporal;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.time.temporal.TemporalAmount;
|
||||
import java.time.temporal.TemporalQuery;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* 日期工具类
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@UtilityClass
|
||||
public class DateUtil {
|
||||
|
||||
public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String PATTERN_DATE = "yyyy-MM-dd";
|
||||
public static final String PATTERN_TIME = "HH:mm:ss";
|
||||
/**
|
||||
* 设置年
|
||||
* 老 date 格式化
|
||||
*/
|
||||
public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
|
||||
public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
|
||||
public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
|
||||
/**
|
||||
* java 8 时间格式化
|
||||
*/
|
||||
public static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
|
||||
public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
|
||||
public static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
|
||||
|
||||
/**
|
||||
* 添加年
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 年数,-1表示减少
|
||||
* @param yearsToAdd 添加的年数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setYears(Date date, int amount) {
|
||||
return set(date, Calendar.YEAR, amount);
|
||||
public static Date plusYears(Date date, int yearsToAdd) {
|
||||
return DateUtil.set(date, Calendar.YEAR, yearsToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置月
|
||||
* 添加月
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 月数,-1表示减少
|
||||
* @param monthsToAdd 添加的月数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setMonths(Date date, int amount) {
|
||||
return set(date, Calendar.MONTH, amount);
|
||||
public static Date plusMonths(Date date, int monthsToAdd) {
|
||||
return DateUtil.set(date, Calendar.MONTH, monthsToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置周
|
||||
* 添加周
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 周数,-1表示减少
|
||||
* @param weeksToAdd 添加的周数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setWeeks(Date date, int amount) {
|
||||
return set(date, Calendar.WEEK_OF_YEAR, amount);
|
||||
public static Date plusWeeks(Date date, int weeksToAdd) {
|
||||
return DateUtil.plus(date, Period.ofWeeks(weeksToAdd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置天
|
||||
* 添加天
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 天数,-1表示减少
|
||||
* @param daysToAdd 添加的天数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setDays(Date date, int amount) {
|
||||
return set(date, Calendar.DATE, amount);
|
||||
public static Date plusDays(Date date, long daysToAdd) {
|
||||
return DateUtil.plus(date, Duration.ofDays(daysToAdd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置小时
|
||||
* 添加小时
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 小时数,-1表示减少
|
||||
* @param hoursToAdd 添加的小时数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setHours(Date date, int amount) {
|
||||
return set(date, Calendar.HOUR_OF_DAY, amount);
|
||||
public static Date plusHours(Date date, long hoursToAdd) {
|
||||
return DateUtil.plus(date, Duration.ofHours(hoursToAdd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置分钟
|
||||
* 添加分钟
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 分钟数,-1表示减少
|
||||
* @param minutesToAdd 添加的分钟数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setMinutes(Date date, int amount) {
|
||||
return set(date, Calendar.MINUTE, amount);
|
||||
public static Date plusMinutes(Date date, long minutesToAdd) {
|
||||
return DateUtil.plus(date, Duration.ofMinutes(minutesToAdd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置秒
|
||||
* 添加秒
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 秒数,-1表示减少
|
||||
* @param secondsToAdd 添加的秒数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setSeconds(Date date, int amount) {
|
||||
return set(date, Calendar.SECOND, amount);
|
||||
public static Date plusSeconds(Date date, long secondsToAdd) {
|
||||
return DateUtil.plus(date, Duration.ofSeconds(secondsToAdd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置毫秒
|
||||
* 添加毫秒
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 毫秒数,-1表示减少
|
||||
* @param millisToAdd 添加的毫秒数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date setMilliseconds(Date date, int amount) {
|
||||
return set(date, Calendar.MILLISECOND, amount);
|
||||
public static Date plusMillis(Date date, long millisToAdd) {
|
||||
return DateUtil.plus(date, Duration.ofMillis(millisToAdd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加纳秒
|
||||
*
|
||||
* @param date 时间
|
||||
* @param nanosToAdd 添加的纳秒数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date plusNanos(Date date, long nanosToAdd) {
|
||||
return DateUtil.plus(date, Duration.ofNanos(nanosToAdd));
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期添加时间量
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 时间量
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date plus(Date date, TemporalAmount amount) {
|
||||
Instant instant = date.toInstant();
|
||||
return Date.from(instant.plus(amount));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少年
|
||||
*
|
||||
* @param date 时间
|
||||
* @param years 减少的年数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusYears(Date date, int years) {
|
||||
return DateUtil.set(date, Calendar.YEAR, -years);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少月
|
||||
*
|
||||
* @param date 时间
|
||||
* @param months 减少的月数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusMonths(Date date, int months) {
|
||||
return DateUtil.set(date, Calendar.MONTH, -months);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少周
|
||||
*
|
||||
* @param date 时间
|
||||
* @param weeks 减少的周数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusWeeks(Date date, int weeks) {
|
||||
return DateUtil.minus(date, Period.ofWeeks(weeks));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少天
|
||||
*
|
||||
* @param date 时间
|
||||
* @param days 减少的天数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusDays(Date date, long days) {
|
||||
return DateUtil.minus(date, Duration.ofDays(days));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少小时
|
||||
*
|
||||
* @param date 时间
|
||||
* @param hours 减少的小时数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusHours(Date date, long hours) {
|
||||
return DateUtil.minus(date, Duration.ofHours(hours));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少分钟
|
||||
*
|
||||
* @param date 时间
|
||||
* @param minutes 减少的分钟数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusMinutes(Date date, long minutes) {
|
||||
return DateUtil.minus(date, Duration.ofMinutes(minutes));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少秒
|
||||
*
|
||||
* @param date 时间
|
||||
* @param seconds 减少的秒数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusSeconds(Date date, long seconds) {
|
||||
return DateUtil.minus(date, Duration.ofSeconds(seconds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少毫秒
|
||||
*
|
||||
* @param date 时间
|
||||
* @param millis 减少的毫秒数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusMillis(Date date, long millis) {
|
||||
return DateUtil.minus(date, Duration.ofMillis(millis));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少纳秒
|
||||
*
|
||||
* @param date 时间
|
||||
* @param nanos 减少的纳秒数
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minusNanos(Date date, long nanos) {
|
||||
return DateUtil.minus(date, Duration.ofNanos(nanos));
|
||||
}
|
||||
|
||||
/**
|
||||
* 日期减少时间量
|
||||
*
|
||||
* @param date 时间
|
||||
* @param amount 时间量
|
||||
* @return 设置后的时间
|
||||
*/
|
||||
public static Date minus(Date date, TemporalAmount amount) {
|
||||
Instant instant = date.toInstant();
|
||||
return Date.from(instant.minus(amount));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,14 +278,6 @@ public class DateUtil {
|
||||
return c.getTime();
|
||||
}
|
||||
|
||||
public static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String PATTERN_DATE = "yyyy-MM-dd";
|
||||
public static final String PATTERN_TIME = "HH:mm:ss";
|
||||
|
||||
public static final ConcurrentDateFormat DATETIME_FORMAT = ConcurrentDateFormat.of(PATTERN_DATETIME);
|
||||
public static final ConcurrentDateFormat DATE_FORMAT = ConcurrentDateFormat.of(PATTERN_DATE);
|
||||
public static final ConcurrentDateFormat TIME_FORMAT = ConcurrentDateFormat.of(PATTERN_TIME);
|
||||
|
||||
/**
|
||||
* 日期时间格式化
|
||||
*
|
||||
@ -182,6 +319,47 @@ public class DateUtil {
|
||||
return ConcurrentDateFormat.of(pattern).format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* java8 日期时间格式化
|
||||
*
|
||||
* @param temporal 时间
|
||||
* @return 格式化后的时间
|
||||
*/
|
||||
public static String formatDateTime(TemporalAccessor temporal) {
|
||||
return DATETIME_FORMATTER.format(temporal);
|
||||
}
|
||||
|
||||
/**
|
||||
* java8 日期时间格式化
|
||||
*
|
||||
* @param temporal 时间
|
||||
* @return 格式化后的时间
|
||||
*/
|
||||
public static String formatDate(TemporalAccessor temporal) {
|
||||
return DATE_FORMATTER.format(temporal);
|
||||
}
|
||||
|
||||
/**
|
||||
* java8 时间格式化
|
||||
*
|
||||
* @param temporal 时间
|
||||
* @return 格式化后的时间
|
||||
*/
|
||||
public static String formatTime(TemporalAccessor temporal) {
|
||||
return TIME_FORMATTER.format(temporal);
|
||||
}
|
||||
|
||||
/**
|
||||
* java8 日期格式化
|
||||
*
|
||||
* @param temporal 时间
|
||||
* @param pattern 表达式
|
||||
* @return 格式化后的时间
|
||||
*/
|
||||
public static String format(TemporalAccessor temporal, String pattern) {
|
||||
return DateTimeFormatter.ofPattern(pattern).format(temporal);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串转换为时间
|
||||
*
|
||||
@ -213,4 +391,196 @@ public class DateUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将字符串转换为时间
|
||||
*
|
||||
* @param dateStr 时间字符串
|
||||
* @param pattern 表达式
|
||||
* @return 时间
|
||||
*/
|
||||
public static <T> T parse(String dateStr, String pattern, TemporalQuery<T> query) {
|
||||
return DateTimeFormatter.ofPattern(pattern).parse(dateStr, query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 时间转 Instant
|
||||
*
|
||||
* @param dateTime 时间
|
||||
* @return Instant
|
||||
*/
|
||||
public static Instant toInstant(LocalDateTime dateTime) {
|
||||
return dateTime.atZone(ZoneId.systemDefault()).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instant 转 时间
|
||||
*
|
||||
* @param instant Instant
|
||||
* @return Instant
|
||||
*/
|
||||
public static LocalDateTime toDateTime(Instant instant) {
|
||||
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成 date
|
||||
*
|
||||
* @param dateTime LocalDateTime
|
||||
* @return Date
|
||||
*/
|
||||
public static Date toDate(LocalDateTime dateTime) {
|
||||
return Date.from(DateUtil.toInstant(dateTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成 date
|
||||
*
|
||||
* @param localDate LocalDate
|
||||
* @return Date
|
||||
*/
|
||||
public static Date toDate(final LocalDate localDate) {
|
||||
return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts local date time to Calendar.
|
||||
*/
|
||||
public static Calendar toCalendar(final LocalDateTime localDateTime) {
|
||||
return GregorianCalendar.from(ZonedDateTime.of(localDateTime, ZoneId.systemDefault()));
|
||||
}
|
||||
|
||||
/**
|
||||
* localDateTime 转换成毫秒数
|
||||
*
|
||||
* @param localDateTime LocalDateTime
|
||||
* @return long
|
||||
*/
|
||||
public static long toMilliseconds(final LocalDateTime localDateTime) {
|
||||
return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
|
||||
}
|
||||
|
||||
/**
|
||||
* localDate 转换成毫秒数
|
||||
*
|
||||
* @param localDate LocalDate
|
||||
* @return long
|
||||
*/
|
||||
public static long toMilliseconds(LocalDate localDate) {
|
||||
return toMilliseconds(localDate.atStartOfDay());
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成java8 时间
|
||||
*
|
||||
* @param calendar 日历
|
||||
* @return LocalDateTime
|
||||
*/
|
||||
public static LocalDateTime fromCalendar(final Calendar calendar) {
|
||||
TimeZone tz = calendar.getTimeZone();
|
||||
ZoneId zid = tz == null ? ZoneId.systemDefault() : tz.toZoneId();
|
||||
return LocalDateTime.ofInstant(calendar.toInstant(), zid);
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成java8 时间
|
||||
*
|
||||
* @param instant Instant
|
||||
* @return LocalDateTime
|
||||
*/
|
||||
public static LocalDateTime fromInstant(final Instant instant) {
|
||||
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成java8 时间
|
||||
*
|
||||
* @param date Date
|
||||
* @return LocalDateTime
|
||||
*/
|
||||
public static LocalDateTime fromDate(final Date date) {
|
||||
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成java8 时间
|
||||
*
|
||||
* @param milliseconds 毫秒数
|
||||
* @return LocalDateTime
|
||||
*/
|
||||
public static LocalDateTime fromMilliseconds(final long milliseconds) {
|
||||
return LocalDateTime.ofInstant(Instant.ofEpochMilli(milliseconds), ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较2个时间差,跨度比较小
|
||||
*
|
||||
* @param startInclusive 开始时间
|
||||
* @param endExclusive 结束时间
|
||||
* @return 时间间隔
|
||||
*/
|
||||
public static Duration between(Temporal startInclusive, Temporal endExclusive) {
|
||||
return Duration.between(startInclusive, endExclusive);
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较2个时间差,跨度比较大,年月日为单位
|
||||
*
|
||||
* @param startDate 开始时间
|
||||
* @param endDate 结束时间
|
||||
* @return 时间间隔
|
||||
*/
|
||||
public static Period between(LocalDate startDate, LocalDate endDate) {
|
||||
return Period.between(startDate, endDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较2个 时间差
|
||||
*
|
||||
* @param startDate 开始时间
|
||||
* @param endDate 结束时间
|
||||
* @return 时间间隔
|
||||
*/
|
||||
public static Duration between(Date startDate, Date endDate) {
|
||||
return Duration.between(startDate.toInstant(), endDate.toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* 将秒数转换为日时分秒
|
||||
*
|
||||
* @param second 秒数
|
||||
* @return 时间
|
||||
*/
|
||||
public static String secondToTime(Long second) {
|
||||
// 判断是否为空
|
||||
if (second == null || second == 0L) {
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
//转换天数
|
||||
long days = second / 86400;
|
||||
//剩余秒数
|
||||
second = second % 86400;
|
||||
//转换小时
|
||||
long hours = second / 3600;
|
||||
//剩余秒数
|
||||
second = second % 3600;
|
||||
//转换分钟
|
||||
long minutes = second / 60;
|
||||
//剩余秒数
|
||||
second = second % 60;
|
||||
if (days > 0) {
|
||||
return StringUtil.format("{}天{}小时{}分{}秒", days, hours, minutes, second);
|
||||
} else {
|
||||
return StringUtil.format("{}小时{}分{}秒", hours, minutes, second);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取今天的日期
|
||||
*
|
||||
* @return 时间
|
||||
*/
|
||||
public static String today() {
|
||||
return format(new Date(), "yyyyMMdd");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2028, DreamLu All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: DreamLu 卢春梦 (596392912@qq.com)
|
||||
*/
|
||||
|
||||
package org.springblade.core.tool.utils;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 文件工具类
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
@UtilityClass
|
||||
public class FileUtil extends org.springframework.util.FileCopyUtils {
|
||||
|
||||
/**
|
||||
* 默认为true
|
||||
*
|
||||
* @author L.cm
|
||||
*/
|
||||
public static class TrueFilter implements FileFilter, Serializable {
|
||||
private static final long serialVersionUID = -6420452043795072619L;
|
||||
|
||||
public final static TrueFilter TRUE = new TrueFilter();
|
||||
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录下的文件
|
||||
*
|
||||
* @param path 路径
|
||||
* @return 文件集合
|
||||
*/
|
||||
public static List<File> list(String path) {
|
||||
File file = new File(path);
|
||||
return list(file, TrueFilter.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录下的文件
|
||||
*
|
||||
* @param path 路径
|
||||
* @param fileNamePattern 文件名 * 号
|
||||
* @return 文件集合
|
||||
*/
|
||||
public static List<File> list(String path, final String fileNamePattern) {
|
||||
File file = new File(path);
|
||||
return list(file, pathname -> {
|
||||
String fileName = pathname.getName();
|
||||
return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录下的文件
|
||||
*
|
||||
* @param path 路径
|
||||
* @param filter 文件过滤
|
||||
* @return 文件集合
|
||||
*/
|
||||
public static List<File> list(String path, FileFilter filter) {
|
||||
File file = new File(path);
|
||||
return list(file, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录下的文件
|
||||
*
|
||||
* @param file 文件
|
||||
* @return 文件集合
|
||||
*/
|
||||
public static List<File> list(File file) {
|
||||
List<File> fileList = new ArrayList<>();
|
||||
return list(file, fileList, TrueFilter.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录下的文件
|
||||
*
|
||||
* @param file 文件
|
||||
* @param fileNamePattern Spring AntPathMatcher 规则
|
||||
* @return 文件集合
|
||||
*/
|
||||
public static List<File> list(File file, final String fileNamePattern) {
|
||||
List<File> fileList = new ArrayList<>();
|
||||
return list(file, fileList, pathname -> {
|
||||
String fileName = pathname.getName();
|
||||
return PatternMatchUtils.simpleMatch(fileNamePattern, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录下的文件
|
||||
*
|
||||
* @param file 文件
|
||||
* @param filter 文件过滤
|
||||
* @return 文件集合
|
||||
*/
|
||||
public static List<File> list(File file, FileFilter filter) {
|
||||
List<File> fileList = new ArrayList<>();
|
||||
return list(file, fileList, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描目录下的文件
|
||||
*
|
||||
* @param file 文件
|
||||
* @param filter 文件过滤
|
||||
* @return 文件集合
|
||||
*/
|
||||
private static List<File> list(File file, List<File> fileList, FileFilter filter) {
|
||||
if (file.isDirectory()) {
|
||||
File[] files = file.listFiles();
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
list(f, fileList, filter);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 过滤文件
|
||||
boolean accept = filter.accept(file);
|
||||
if (file.exists() && accept) {
|
||||
fileList.add(file);
|
||||
}
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件后缀名
|
||||
* @param fullName 文件全名
|
||||
* @return {String}
|
||||
*/
|
||||
public static String getFileExtension(String fullName) {
|
||||
Assert.notNull(fullName, "file fullName is null.");
|
||||
String fileName = new File(fullName).getName();
|
||||
int dotIndex = fileName.lastIndexOf('.');
|
||||
return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件名,去除后缀名
|
||||
* @param file 文件
|
||||
* @return {String}
|
||||
*/
|
||||
public static String getNameWithoutExtension(String file) {
|
||||
Assert.notNull(file, "file is null.");
|
||||
String fileName = new File(file).getName();
|
||||
int dotIndex = fileName.lastIndexOf(CharPool.DOT);
|
||||
return (dotIndex == -1) ? fileName : fileName.substring(0, dotIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the system temporary directory.
|
||||
*
|
||||
* @return the path to the system temporary directory.
|
||||
*/
|
||||
public static String getTempDirPath() {
|
||||
return System.getProperty("java.io.tmpdir");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link File} representing the system temporary directory.
|
||||
*
|
||||
* @return the system temporary directory.
|
||||
*/
|
||||
public static File getTempDir() {
|
||||
return new File(getTempDirPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of a file into a String.
|
||||
* The file is always closed.
|
||||
*
|
||||
* @param file the file to read, must not be {@code null}
|
||||
* @return the file contents, never {@code null}
|
||||
*/
|
||||
public static String readToString(final File file) {
|
||||
return readToString(file, Charsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of a file into a String.
|
||||
* The file is always closed.
|
||||
*
|
||||
* @param file the file to read, must not be {@code null}
|
||||
* @param encoding the encoding to use, {@code null} means platform default
|
||||
* @return the file contents, never {@code null}
|
||||
*/
|
||||
public static String readToString(final File file, final Charset encoding) {
|
||||
try (InputStream in = Files.newInputStream(file.toPath())) {
|
||||
return IoUtil.toString(in, encoding);
|
||||
} catch (IOException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of a file into a String.
|
||||
* The file is always closed.
|
||||
*
|
||||
* @param file the file to read, must not be {@code null}
|
||||
* @return the file contents, never {@code null}
|
||||
*/
|
||||
public static byte[] readToByteArray(final File file) {
|
||||
try (InputStream in = Files.newInputStream(file.toPath())) {
|
||||
return IoUtil.toByteArray(in);
|
||||
} catch (IOException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a String to a file creating the file if it does not exist.
|
||||
*
|
||||
* @param file the file to write
|
||||
* @param data the content to write to the file
|
||||
*/
|
||||
public static void writeToFile(final File file, final String data) {
|
||||
writeToFile(file, data, Charsets.UTF_8, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a String to a file creating the file if it does not exist.
|
||||
*
|
||||
* @param file the file to write
|
||||
* @param data the content to write to the file
|
||||
* @param append if {@code true}, then the String will be added to the
|
||||
* end of the file rather than overwriting
|
||||
*/
|
||||
public static void writeToFile(final File file, final String data, final boolean append){
|
||||
writeToFile(file, data, Charsets.UTF_8, append);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a String to a file creating the file if it does not exist.
|
||||
*
|
||||
* @param file the file to write
|
||||
* @param data the content to write to the file
|
||||
* @param encoding the encoding to use, {@code null} means platform default
|
||||
*/
|
||||
public static void writeToFile(final File file, final String data, final Charset encoding) {
|
||||
writeToFile(file, data, encoding, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a String to a file creating the file if it does not exist.
|
||||
*
|
||||
* @param file the file to write
|
||||
* @param data the content to write to the file
|
||||
* @param encoding the encoding to use, {@code null} means platform default
|
||||
* @param append if {@code true}, then the String will be added to the
|
||||
* end of the file rather than overwriting
|
||||
*/
|
||||
public static void writeToFile(final File file, final String data, final Charset encoding, final boolean append) {
|
||||
try (OutputStream out = new FileOutputStream(file, append)) {
|
||||
IoUtil.write(data, out, encoding);
|
||||
} catch (IOException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成file
|
||||
* @param multipartFile MultipartFile
|
||||
* @param file File
|
||||
*/
|
||||
public static void toFile(MultipartFile multipartFile, final File file) {
|
||||
try {
|
||||
FileUtil.toFile(multipartFile.getInputStream(), file);
|
||||
} catch (IOException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转成file
|
||||
* @param in InputStream
|
||||
* @param file File
|
||||
*/
|
||||
public static void toFile(InputStream in, final File file) {
|
||||
try (OutputStream out = new FileOutputStream(file)) {
|
||||
FileUtil.copy(in, out);
|
||||
} catch (IOException e) {
|
||||
throw Exceptions.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves a file.
|
||||
* <p>
|
||||
* When the destination file is on another file system, do a "copy and delete".
|
||||
*
|
||||
* @param srcFile the file to be moved
|
||||
* @param destFile the destination file
|
||||
* @throws NullPointerException if source or destination is {@code null}
|
||||
* @throws IOException if source or destination is invalid
|
||||
* @throws IOException if an IO error occurs moving the file
|
||||
*/
|
||||
public static void moveFile(final File srcFile, final File destFile) throws IOException {
|
||||
Assert.notNull(srcFile, "Source must not be null");
|
||||
Assert.notNull(destFile, "Destination must not be null");
|
||||
if (!srcFile.exists()) {
|
||||
throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
|
||||
}
|
||||
if (srcFile.isDirectory()) {
|
||||
throw new IOException("Source '" + srcFile + "' is a directory");
|
||||
}
|
||||
if (destFile.exists()) {
|
||||
throw new IOException("Destination '" + destFile + "' already exists");
|
||||
}
|
||||
if (destFile.isDirectory()) {
|
||||
throw new IOException("Destination '" + destFile + "' is a directory");
|
||||
}
|
||||
final boolean rename = srcFile.renameTo(destFile);
|
||||
if (!rename) {
|
||||
FileUtil.copy(srcFile, destFile);
|
||||
if (!srcFile.delete()) {
|
||||
FileUtil.deleteQuietly(destFile);
|
||||
throw new IOException("Failed to delete original file '" + srcFile + "' after copy to '" + destFile + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file, never throwing an exception. If file is a directory, delete it and all sub-directories.
|
||||
* <p>
|
||||
* The difference between File.delete() and this method are:
|
||||
* <ul>
|
||||
* <li>A directory to be deleted does not have to be empty.</li>
|
||||
* <li>No exceptions are thrown when a file or directory cannot be deleted.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param file file or directory to delete, can be {@code null}
|
||||
* @return {@code true} if the file or directory was deleted, otherwise
|
||||
* {@code false}
|
||||
*/
|
||||
public static boolean deleteQuietly(@Nullable final File file) {
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (file.isDirectory()) {
|
||||
FileSystemUtils.deleteRecursively(file);
|
||||
}
|
||||
} catch (final Exception ignored) {
|
||||
}
|
||||
|
||||
try {
|
||||
return file.delete();
|
||||
} catch (final Exception ignored) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -27,7 +27,7 @@ public interface StringPool {
|
||||
String AT = "@";
|
||||
String ASTERISK = "*";
|
||||
String STAR = ASTERISK;
|
||||
char SLASH = '/';
|
||||
String SLASH = "/";
|
||||
char BACK_SLASH = '\\';
|
||||
String DOUBLE_SLASH = "#//";
|
||||
String COLON = ":";
|
||||
|
10
pom.xml
10
pom.xml
@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-tool</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<version>2.3.2</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>blade-tool</name>
|
||||
<description>
|
||||
@ -36,19 +36,19 @@
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<blade.tool.version>2.3.1</blade.tool.version>
|
||||
<blade.tool.version>2.3.2</blade.tool.version>
|
||||
|
||||
<java.version>1.8</java.version>
|
||||
<maven.plugin.version>3.8.0</maven.plugin.version>
|
||||
<swagger.version>2.9.2</swagger.version>
|
||||
<swagger.models.version>1.5.21</swagger.models.version>
|
||||
<swagger.bootstrapui.version>1.9.3</swagger.bootstrapui.version>
|
||||
<swagger.bootstrapui.version>1.9.4</swagger.bootstrapui.version>
|
||||
<mybatis.plus.version>3.1.0</mybatis.plus.version>
|
||||
<curator.framework.version>4.0.1</curator.framework.version>
|
||||
<protostuff.version>1.6.0</protostuff.version>
|
||||
<disruptor.version>3.4.2</disruptor.version>
|
||||
<spring.boot.admin.version>2.1.4</spring.boot.admin.version>
|
||||
<mica.auto.version>1.0.1</mica.auto.version>
|
||||
<mica.auto.version>1.1.0</mica.auto.version>
|
||||
<alibaba.cloud.version>0.9.0.RELEASE</alibaba.cloud.version>
|
||||
|
||||
<spring.boot.version>2.1.5.RELEASE</spring.boot.version>
|
||||
@ -68,7 +68,9 @@
|
||||
<module>blade-core-mybatis</module>
|
||||
<module>blade-core-secure</module>
|
||||
<module>blade-core-swagger</module>
|
||||
<module>blade-core-test</module>
|
||||
<module>blade-core-tool</module>
|
||||
<module>blade-core-oss</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
Loading…
Reference in New Issue
Block a user