Commit f3d28a2d by yw

项目初始化

parent 3cd3df31
......@@ -5,11 +5,9 @@ import java.lang.reflect.Method;
import cn.datax.common.log.annotation.LogAop;
import cn.datax.common.log.async.AsyncTask;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import lombok.extern.slf4j.Slf4j;
......@@ -27,23 +25,39 @@ public class LogAspect {
public void logPointCut() {}
/**
* 前置通知 用于拦截操作
* 通知方法会在目标方法返回后执行
*
* @param joinPoint 切点
*/
@AfterReturning(pointcut = "logPointCut()")
public void doBefore(JoinPoint joinPoint) {
public void doAfterReturning(JoinPoint joinPoint) {
handleLog(joinPoint, null);
}
/**
* 拦截异常操作
* 通知方法会将目标方法封装起来
*
* @param joinPoint 切点
*/
@Around(value = "logPointCut()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = joinPoint.proceed();
log.info("响应结果为{}", result);
long endTime = System.currentTimeMillis();
log.info("响应时间为{}毫秒", endTime - startTime);
//如果这里不返回result,则目标对象实际返回值会被置为null
return result;
}
/**
* 通知方法会在目标方法抛出异常后执行
*
* @param joinPoint
* @param e
*/
@AfterThrowing(value = "logPointCut()", throwing = "e")
public void doAfter(JoinPoint joinPoint, Exception e) {
public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
handleLog(joinPoint, e);
}
......@@ -54,12 +68,10 @@ public class LogAspect {
if(logAop == null) {
return;
}
// 设置方法名称
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
log.info("[类名]:{},[方法]:{},[模块]:{},[描述]:{}", className, methodName, logAop.module(), logAop.value());
// 异步保存数据库
asyncTask.doTask();
} catch (Exception exp) {
......
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.2.0" level="project" />
<orderEntry type="module" module-name="datax-common-core" />
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.10" level="project" />
</component>
</module>
\ No newline at end of file
package cn.datax.service.file.api.entity;
import cn.datax.common.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* <p>
*
* </p>
*
* @author yuwei
* @since 2019-09-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("tbl_file")
public class FileEntity extends BaseEntity {
private static final long serialVersionUID=1L;
/**
* 文件名称
*/
private String fileName;
/**
* 文件大小
*/
private Long fileSize;
/**
* 访问路径
*/
private String filePath;
/**
* 文件类型
*/
private String contentType;
/**
* 文件来源
*/
private String fileType;
}
......@@ -22,9 +22,59 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 阿里云oss -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun-sdk-oss.version}</version>
</dependency>
<!-- 七牛oss -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>${qiniu-java-sdk.version}</version>
</dependency>
<!-- fastDFS -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${fastdfs-client.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger2.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>file-service-api</artifactId>
<artifactId>datax-common-mybatis</artifactId>
<version>${app.version}</version>
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>datax-common-security</artifactId>
<version>${app.version}</version>
</dependency>
<dependency>
......@@ -32,6 +82,11 @@
<artifactId>datax-common-log</artifactId>
<version>${app.version}</version>
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>file-service-api</artifactId>
<version>${app.version}</version>
</dependency>
</dependencies>
<build>
......
package cn.datax.service.file.config;
import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.service.file.properties.FileServerProperties;
import cn.datax.service.file.service.impl.FileServiceImpl;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.aliyun.oss.OSSClient;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* 阿里云配置
*/
@Configuration
@ConditionalOnProperty(name = "data.file-server.type", havingValue = "aliyun")
public class AliyunOSSAutoConfig {
@Autowired
private FileServerProperties fileProperties;
/**
* 阿里云文件存储client
* 只有配置了aliyun.oss.access-key才可以使用
*/
@Bean
public OSSClient ossClient() {
OSSClient ossClient = new OSSClient(fileProperties.getOss().getEndpoint()
, new DefaultCredentialProvider(fileProperties.getOss().getAccessKey(), fileProperties.getOss().getAccessKeySecret())
, new ClientConfiguration());
return ossClient;
}
@Service
public class AliyunOssServiceImpl extends FileServiceImpl {
@Autowired
private OSSClient ossClient;
@Override
protected String fileType() {
return fileProperties.getType();
}
@Override
protected void uploadFile(MultipartFile file, FileEntity fileEntity) {
try {
PutObjectResult result = ossClient.putObject(fileProperties.getOss().getBucketName(), fileEntity.getFileName(), file.getInputStream());
if(result.getResponse().getStatusCode() == 200){
fileEntity.setFilePath(fileProperties.getOss().getDomain() + "/" + fileEntity.getFileName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void deleteFile(FileEntity fileEntity) {
ossClient.deleteObject(fileProperties.getOss().getBucketName(), fileEntity.getFileName());
}
}
}
package cn.datax.service.file.config;
import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.service.file.properties.FileServerProperties;
import cn.datax.service.file.service.impl.FileServiceImpl;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* FastDFS配置
*/
@Configuration
@ConditionalOnProperty(name = "data.file-server.type", havingValue = "fastdfs")
public class FastdfsAutoConfig {
@Autowired
private FileServerProperties fileProperties;
@Service
public class FastdfsServiceImpl extends FileServiceImpl {
@Autowired
private FastFileStorageClient storageClient;
@Override
protected String fileType() {
return fileProperties.getType();
}
@Override
protected void uploadFile(MultipartFile file, FileEntity fileEntity) {
StorePath storePath = null;
try {
storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), null);
} catch (IOException e) {
e.printStackTrace();
}
// fileEntity.setFilePath("http://" + fileProperties.getFdfs().getWebUrl() + "/" + storePath.getFullPath());
fileEntity.setFilePath(storePath.getFullPath());
}
@Override
protected void deleteFile(FileEntity fileEntity) {
StorePath storePath = StorePath.parseFromUrl(fileEntity.getFilePath());
storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
}
}
}
package cn.datax.service.file.config;
import java.io.File;
import cn.datax.service.file.properties.FileServerProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 本地文件配置
*/
@Configuration
@ConditionalOnProperty(name = "data.file-server.type", havingValue = "local")
public class LocalFileAutoConfig {
@Autowired
private FileServerProperties fileProperties;
@Bean
public WebMvcConfigurer webMvcConfigurerAdapter() {
return new WebMvcConfigurer() {
/**
* 外部文件访问
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(fileProperties.getLocal().getPrefix() + "/**")
.addResourceLocations(ResourceUtils.FILE_URL_PREFIX + fileProperties.getLocal().getPath() + File.separator);
}
};
}
}
package cn.datax.service.file.config;
import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.service.file.properties.FileServerProperties;
import cn.datax.service.file.service.impl.FileServiceImpl;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* 七牛云配置
*/
@Configuration
@ConditionalOnProperty(name = "data.file-server.type", havingValue = "qiniu")
public class QiniuOSSAutoConfig {
@Autowired
private FileServerProperties fileProperties;
/**
* 华东机房
*/
@Bean
public com.qiniu.storage.Configuration qiniuConfig() {
return new com.qiniu.storage.Configuration(Zone.zone2());
}
/**
* 构建一个七牛上传工具实例
*/
@Bean
public UploadManager uploadManager() {
return new UploadManager(qiniuConfig());
}
/**
* 认证信息实例
*
* @return
*/
@Bean
public Auth auth() {
return Auth.create(fileProperties.getOss().getAccessKey(), fileProperties.getOss().getAccessKeySecret());
}
/**
* 构建七牛空间管理实例
*/
@Bean
public BucketManager bucketManager() {
return new BucketManager(auth(), qiniuConfig());
}
@Service
public class QiniuOssServiceImpl extends FileServiceImpl {
@Autowired
private UploadManager uploadManager;
@Autowired
private BucketManager bucketManager;
@Autowired
private Auth auth;
@Override
protected String fileType() {
return fileProperties.getType();
}
@Override
protected void uploadFile(MultipartFile file, FileEntity fileEntity) {
try {
Response response = uploadManager.put(file.getBytes(), fileEntity.getFileName(), auth.uploadToken(fileProperties.getOss().getBucketName()));
int retry = 0;
while (response.needRetry() && retry++ < 3) {
response = uploadManager.put(file.getBytes(), fileEntity.getFileName(), auth.uploadToken(fileProperties.getOss().getBucketName()));
}
if (response.statusCode == 200) {
fileEntity.setFilePath(fileProperties.getOss().getEndpoint() + "/" + fileEntity.getFileName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void deleteFile(FileEntity fileEntity) {
try {
Response response = bucketManager.delete(fileProperties.getOss().getBucketName(), fileEntity.getFilePath());
int retry = 0;
while (response.needRetry() && retry++ < 3) {
response = bucketManager.delete(fileProperties.getOss().getBucketName(), fileEntity.getFilePath());
}
} catch (QiniuException e) {
e.printStackTrace();
}
}
}
}
package cn.datax.service.file.controller;
import cn.datax.common.core.R;
import cn.datax.common.validate.ValidateGroupForSave;
import cn.datax.common.validate.ValidateGroupForUpdate;
import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.service.file.service.FileService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import cn.datax.common.base.BaseController;
import org.springframework.web.multipart.MultipartFile;
/**
* <p>
* 前端控制器
* </p>
*
* @author yuwei
* @since 2019-09-17
*/
@RestController
@RequestMapping("/file")
public class FileController extends BaseController {
@Autowired
private FileService fileService;
@GetMapping("/{id}")
public R getFileById(@PathVariable String id) {
return R.ok().setData(fileService.getById(id));
}
@GetMapping("/page")
public R getFilePage(Page page, FileEntity file) {
return R.ok().setData(fileService.page(page, null));
}
@PostMapping("/upload")
public R upload(@RequestParam("file") MultipartFile file) {
fileService.uploadFile(file);
return R.ok();
}
@DeleteMapping("/{id}")
public R deleteFile(@PathVariable String id) {
fileService.deleteFileById(id);
return R.ok();
}
}
package cn.datax.service.file.controller;
import cn.datax.common.core.R;
import cn.datax.common.log.annotation.LogAop;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogController {
@LogAop(module = "file", value = "testCESHI")
@GetMapping("/log")
public R get() {
return R.ok();
}
}
package cn.datax.service.file.mapper;
import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.common.base.BaseDao;
/**
* <p>
* Mapper 接口
* </p>
*
* @author yuwei
* @since 2019-09-17
*/
public interface FileMapper extends BaseDao<FileEntity> {
}
package cn.datax.service.file.properties;
import lombok.Data;
@Data
public class FdfsProperties {
/**
* fastdfs的http访问地址
*/
private String webUrl;
}
package cn.datax.service.file.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "data.file-server")
public class FileServerProperties {
/**
* 为以下3个值,指定不同的自动化配置
* qiniu:七牛oss
* aliyun:阿里云oss
* fastdfs:本地部署的fastDFS
*/
private String type;
/**
* oss配置
*/
OssProperties oss = new OssProperties();
/**
* fastDFS配置
*/
FdfsProperties fdfs = new FdfsProperties();
/**
* local配置
*/
LocalProperties local = new LocalProperties();
}
package cn.datax.service.file.properties;
import lombok.Data;
@Data
public class LocalProperties {
/**
* 上传文件存储在本地的根路径
*/
private String path;
/**
* url前缀
*/
private String prefix;
}
package cn.datax.service.file.properties;
import lombok.Data;
@Data
public class OssProperties {
/**
* 密钥key
*/
private String accessKey;
/**
* 密钥密码
*/
private String accessKeySecret;
/**
* 端点
*/
private String endpoint;
/**
* bucket名称
*/
private String bucketName;
/**
* 说明
*/
private String domain;
}
package cn.datax.service.file.service;
import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.common.base.BaseService;
import org.springframework.web.multipart.MultipartFile;
/**
* <p>
* 服务类
* </p>
*
* @author yuwei
* @since 2019-09-17
*/
public interface FileService extends BaseService<FileEntity> {
FileEntity uploadFile(MultipartFile file);
void deleteFileById(String id);
}
package cn.datax.service.file.service.impl;
import cn.datax.service.file.api.entity.FileEntity;
import cn.datax.service.file.mapper.FileMapper;
import cn.datax.service.file.service.FileService;
import cn.datax.common.base.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
/**
* <p>
* 服务实现类
* </p>
*
* @author yuwei
* @since 2019-09-17
*/
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public abstract class FileServiceImpl extends BaseServiceImpl<FileMapper, FileEntity> implements FileService {
@Override
public FileEntity uploadFile(MultipartFile file) {
FileEntity fileEntity = new FileEntity();
fileEntity.setContentType(file.getContentType())
.setFileName(file.getOriginalFilename())
.setFileSize(file.getSize());
uploadFile(file, fileEntity);
// 设置文件来源
fileEntity.setFileType(fileType());
// 将文件信息保存到数据库
baseMapper.insert(fileEntity);
return fileEntity;
}
@Override
public void deleteFileById(String id) {
FileEntity fileEntity = baseMapper.selectById(id);
if (fileEntity != null) {
baseMapper.deleteById(fileEntity.getId());
deleteFile(fileEntity);
}
}
/**
* 文件来源
*
* @return
*/
protected abstract String fileType();
/**
* 上传文件
*
* @param file
* @param fileEntity
*/
protected abstract void uploadFile(MultipartFile file, FileEntity fileEntity);
/**
* 删除文件资源
*
* @param fileEntity
* @return
*/
protected abstract void deleteFile(FileEntity fileEntity);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.datax.service.file.mapper.FileMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.datax.service.file.api.entity.FileEntity">
<result column="id" property="id" />
<result column="status" property="status" />
<result column="deleted" property="deleted" />
<result column="create_by" property="createBy" />
<result column="create_time" property="createTime" />
<result column="update_by" property="updateBy" />
<result column="update_time" property="updateTime" />
<result column="file_name" property="fileName" />
<result column="file_size" property="fileSize" />
<result column="file_path" property="filePath" />
<result column="content_type" property="contentType" />
<result column="file_type" property="fileType" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
id,
status,
deleted,
create_by,
create_time,
update_by,
update_time,
file_name, file_size, file_path, content_type, file_type
</sql>
</mapper>
......@@ -51,11 +51,6 @@
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>datax-common-core</artifactId>
<version>${app.version}</version>
</dependency>
<dependency>
<groupId>cn.datax</groupId>
<artifactId>datax-common-mybatis</artifactId>
<version>${app.version}</version>
</dependency>
......
......@@ -38,6 +38,9 @@
<swagger2.version>2.9.2</swagger2.version>
<swagger-bootstrap.version>1.9.6</swagger-bootstrap.version>
<mapstruct.version>1.3.1.Final</mapstruct.version>
<aliyun-sdk-oss.version>3.6.0</aliyun-sdk-oss.version>
<qiniu-java-sdk.version>7.2.25</qiniu-java-sdk.version>
<fastdfs-client.version>1.26.7</fastdfs-client.version>
</properties>
<modules>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment