diff --git a/DbInitScript/xyfs.sql b/DbInitScript/xyfs_mysql.sql similarity index 100% rename from DbInitScript/xyfs.sql rename to DbInitScript/xyfs_mysql.sql diff --git a/DbInitScript/xyfs_sqlite.sql b/DbInitScript/xyfs_sqlite.sql new file mode 100644 index 0000000..dcf586b --- /dev/null +++ b/DbInitScript/xyfs_sqlite.sql @@ -0,0 +1,41 @@ +CREATE TABLE "app" ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `appkey` varchar, + `available` varchar, + `code` varchar, + `name` varchar +) + +CREATE TABLE "dailyreport" ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `curdate` varchar, + `files` integer NOT NULL, + `groups` integer NOT NULL, + `spaces` integer NOT NULL +) + +CREATE TABLE diskfile (fileid varchar not null, appid integer not null, dfs_group_name varchar, download_num integer not null, download_pwd varchar, expiration_date timestamp, extra1 varchar, extra2 varchar, extra3 varchar, extra4 varchar, extra5 varchar, file_ext varchar, file_flag varchar, file_name varchar, file_size numeric, file_url varchar, filesource varchar, form_id varchar, group_id varchar, group_name varchar, ispublic varchar, upload_date timestamp, upload_user varchar, primary key (fileid)) + +CREATE TABLE diskgroup (group_id varchar not null, administrator varchar, create_date timestamp, extra1 varchar, extra2 varchar, extra3 varchar, extra4 varchar, extra5 varchar, father_group_id varchar, group_cn_name varchar, group_creator varchar, group_flag varchar, group_name varchar, group_type varchar, is_public varchar, max_num integer not null, primary key (group_id)) + +CREATE TABLE diskuser (user_name varchar not null, app_id integer not null, email varchar, extra1 varchar, extra2 varchar, extra3 varchar, extra4 varchar, extra5 varchar, first_date timestamp, is_admin varchar, last_date timestamp, max_space numeric, password varchar, phone varchar, used_space numeric, user_cn_name varchar, user_flag varchar, primary key (user_name)) + +CREATE TABLE "groupuser" ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `group_id` varchar, + `user_name` varchar +) + +CREATE TABLE "history" ( + `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + `extra1` varchar, + `extra2` varchar, + `extra3` varchar, + `extra4` varchar, + `extra5` varchar, + `file_name` varchar, + `group_name` varchar, + `operation` varchar, + `time` timestamp, + `user_name` varchar +) \ No newline at end of file diff --git a/DbSqlite/xyfs.db b/DbSqlite/xyfs.db new file mode 100644 index 0000000..1f18f27 Binary files /dev/null and b/DbSqlite/xyfs.db differ diff --git a/README.md b/README.md index c2d8380..bd2db45 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,14 @@ xyTalk地址:https://gitee.com/475660/xyTalk-pc xyFS不仅仅是独立可用的文件系统,还通过接口灵活集成以下服务: - 1.私有Xy.File OSS-FS文件服务 (自主开发,免费开源) -- 2.私有企业云存储:Seafile网盘 +- 2.私有分布式文件:MongoDB GridFS分布式文件系统 - 3.私有分布式文件:FastDFS文件系统 -- 4.私有分布式文件:MongoDB GridFS分布式文件系统 -- 5.私有分布式文件:百度文件系统 BFS -- 6.私有分布式文件:微信后台分布式存储数据库 PaxosStore -- 7.私有BASE64转存关系数据库存储(停用) -- 8.公有云存储:阿里OSS云存储 -- 9.公有云存储:七牛云 -- 10.公有云存储:腾讯文件云存储 CFS +- 4.私有分布式文件:SeaweedFS +- 5.私有企业云存储:Seafile网盘 +- 6.私有BASE64转存关系数据库存储(停用) +- 7.公有云存储:阿里OSS云存储 +- 8.公有云存储:七牛云 +- 9.公有云存储:腾讯文件云存储 CFS #### 项目详细文档 @@ -35,7 +34,7 @@ http://xyfs.mydoc.io/ #### 采用技术 -- 1.Spring Boot、MVC、AOP +- 1.Spring Boot、MVC、AOP、Actuator、Swagger - 2.Dbcp2/Druid - 3.JPA/Hibernate - 4.Ehcache diff --git a/bin/main/.gitignore b/bin/main/.gitignore deleted file mode 100644 index 52b9a6e..0000000 --- a/bin/main/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/xy/ -/templates/ diff --git a/bin/main/application.properties b/bin/main/application.properties index 99499e8..6fdcfe7 100644 --- a/bin/main/application.properties +++ b/bin/main/application.properties @@ -1,22 +1,73 @@ +# tomcat\u670d\u52a1\u7aef\u53e3 # server.port=9091 +#\u542f\u7528shutdown +endpoints.sensitive=false +# \u5b58\u50a8\u7684\u76f8\u5bf9\u8def\u5f84\uff0c\u5982\u679c storage.source = xyfs \u9700\u8981\u914d\u7f6e # storage.location = uploadfiledir +# \u662f\u5426\u91cd\u65b0\u547d\u540d\u6587\u4ef6\u540d\uff0c\u5982\u679c\u662f\u4e2a\u4eba\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1ausername_ + \u539f\u6587\u4ef6\u540d\uff1b\u5982\u679c\u662f\u7fa4\u7ec4\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1agroupid_ + \u539f\u6587\u4ef6\u540d # +storage.rename = true + +# \u5b58\u50a8\u6e90\uff0c\u7c7b\u578b\u6709\uff1axyfs\\Seafile\\FastDFS\\SeaweedFS\\MongoDB\\aliOSS\\qiniu\\CFS # +storage.todisk = true +storage.toqiniu = true +storage.tofastdfs = false +storage.tomongodb = false +storage.toseaweedfs = false +storage.toalioss = false +storage.tocfs = false + +storage.diskprefix = http://localhost:9091/files/ + +# \u4e03\u725b\u5b58\u50a8\u914d\u7f6e # +storage.qiniuprefix = http://pbby0yzdu.bkt.clouddn.com/ +storage.qiniuak = _IAafy8aX5x7h-4FBEvH2DqCtTq2c7sESPSlfGgI +storage.qiniusk = _8hy2LE6kfTKr3wDUWJONgFRxPKX4cDQhi79Bj3Y +storage.qiniubucket = xytalk + +# mongodb.gridfs\u914d\u7f6e # +storage.gridfshost = 127.0.0.1 +storage.gridfsdbname = xyfs +storage.gridfsport = 27017 +storage.gridfscollectionname = fs + +# fastDFS \u914d\u7f6e # +storage.fastdfsconnecttimeout = 5 +storage.fastdfsnetwork_timeout = 10 +storage.fastdfscharset = UTF-8 +storage.fastdfstrackerhttpport = 80 +storage.fastdfsantistealtoken = no +storage.fastdfssecret_key = 1234567890 +storage.fastdfstrackerserver = 192.168.17.112:22122 + +# SeaweedFS \u914d\u7f6e # +storage.seaweedfshost = localhost +storage.seaweedfsport = 9333 +storage.seaweedfstimeout = 5000 + # \u7b2c\u4e00\u6b21\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u81ea\u52a8\u521b\u5efa\u6570\u636e\u5e93\u8868\uff0c\u5982\u679c\u662f\u8fd0\u884cSQL\u811a\u672c\u5219\u65e0\u9700\u4f7f\u7528\u6b64\u914d\u7f6e # # spring.jpa.hibernate.ddl-auto = create - # \u7b2c\u4e8c\u6b21\u5f00\u59cb\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u636e\u5e93\u8868\u4f1a\u6839\u636eEntity\u7684\u53d8\u52a8\u800c\u66f4\u65b0 # -spring.jpa.hibernate.ddl-auto = update -spring.datasource.url=jdbc:mysql://localhost:3306/xyfs -spring.datasource.username=root -spring.datasource.password=mysql + spring.jpa.hibernate.ddl-auto = update + +# Sqlite\u6570\u636e\u6e90 # +spring.datasource.driver-class-name=org.sqlite.JDBC +spring.datasource.url=jdbc:sqlite:DbSqlite/xyfs.db +spring.datasource.platform=sqlite +spring.jpa.database-platform= xy.FileSystem.Dialect.SQLiteDialect + +# mysql\u6570\u636e\u6e90 # +#spring.datasource.url=jdbc:mysql://localhost:3306/xyfs +#spring.datasource.username=root +#spring.datasource.password=mysql # dbcp2\u8fde\u63a5\u6c60\u914d\u7f6e # spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource spring.datasource.dbcp2.max-wait-millis=10000 spring.datasource.dbcp2.min-idle=5 spring.datasource.dbcp2.initial-size=5 -spring.datasource.dbcp2.validation-query=SELECT 1 FROM App +spring.datasource.dbcp2.validation-query=SELECT 1 FROM app spring.datasource.dbcp2.connection-properties=characterEncoding=utf8 # druid\u8fde\u63a5\u6c60\u7684\u914d\u7f6e\u4fe1\u606f # diff --git a/build.gradle b/build.gradle index f61aff6..6ac23a1 100644 --- a/build.gradle +++ b/build.gradle @@ -28,14 +28,28 @@ dependencies { compile("org.springframework.boot:spring-boot-starter-web") compile("org.springframework.boot:spring-boot-starter-data-jpa") compile("org.springframework.boot:spring-boot-starter-cache") - compile("org.springframework.boot:spring-boot-starter-data-rest") + compile("org.springframework.boot:spring-boot-starter-data-rest") compile("org.springframework.boot:spring-boot-devtools") + compile("org.springframework.boot:spring-boot-starter-actuator") compile 'mysql:mysql-connector-java' compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.4.0' compile group: 'com.alibaba', name: 'druid', version: '1.1.10' - + compile group: 'org.xerial', name: 'sqlite-jdbc', version: '3.23.1' + compile group: 'com.enigmabridge', name: 'hibernate4-sqlite-dialect', version: '0.1.2' + compile group: 'com.qiniu', name: 'qiniu-java-sdk', version: '7.2.13' + compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5' + compile group: 'com.qiniu', name: 'happy-dns-java', version: '0.1.6' + compile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.10.0' + compile group: 'com.squareup.okio', name: 'okio', version: '1.14.1' + compile group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.10' + compile group: 'commons-logging', name: 'commons-logging', version: '1.2' + compile group: 'commons-codec', name: 'commons-codec', version: '1.11' + compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.5' + compile group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.5' + compile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.8.0' + testCompile("org.springframework.boot:spring-boot-starter-test") testCompile('com.jayway.jsonpath:json-path') testCompile("org.apache.httpcomponents:httpclient") diff --git a/src/main/java/xy/FileSystem/Cache/UsesCache.java b/src/main/java/xy/FileSystem/Cache/UsesCache.java new file mode 100644 index 0000000..37f45c7 --- /dev/null +++ b/src/main/java/xy/FileSystem/Cache/UsesCache.java @@ -0,0 +1,9 @@ +package xy.FileSystem.Cache; + +public class UsesCache { + + public static double usedspace; + public static int files; + public static int groups; + +} diff --git a/src/main/java/xy/FileSystem/Client/ClientMultipartFormDownload.java b/src/main/java/xy/FileSystem/Client/ClientMultipartFormDownload.java new file mode 100644 index 0000000..47c4d83 --- /dev/null +++ b/src/main/java/xy/FileSystem/Client/ClientMultipartFormDownload.java @@ -0,0 +1,18 @@ +package xy.FileSystem.Client; + +import xy.FileSystem.Utils.HttpHelper; + +//下载测试 + +public class ClientMultipartFormDownload { + public static void main(String[] args) throws Exception { + + HttpHelper.executeDownloadFile(HttpHelper.createHttpClient(), + "http://localhost:9091/files/abc.txt", + "D://XXX.txt", //要保存在本地的文件 + "UTF-8", + true); + + } + +} diff --git a/src/main/java/xy/FileSystem/Client/ClientMultipartFormPost.java b/src/main/java/xy/FileSystem/Client/ClientMultipartFormPost.java new file mode 100644 index 0000000..c994299 --- /dev/null +++ b/src/main/java/xy/FileSystem/Client/ClientMultipartFormPost.java @@ -0,0 +1,23 @@ +package xy.FileSystem.Client; + + +import xy.FileSystem.File.HttpResult; +import xy.FileSystem.Utils.HttpHelper; + +//上传测试 + +public class ClientMultipartFormPost { + + public static void main(String[] args) throws Exception { + + HttpResult result = HttpHelper.executeUploadFile(HttpHelper.createHttpClient(), + "http://localhost:9091/", + "D://nginx.conf", //要上传的本地文件 + "UTF-8", + true); + System.out.println(result.getStatusCode()); + System.out.println(result.getContent()); + + } + +} \ No newline at end of file diff --git a/src/main/java/xy/FileSystem/Controller/FileUploadController.java b/src/main/java/xy/FileSystem/Controller/FileUploadController.java index 836d247..cdb4b55 100644 --- a/src/main/java/xy/FileSystem/Controller/FileUploadController.java +++ b/src/main/java/xy/FileSystem/Controller/FileUploadController.java @@ -1,6 +1,11 @@ package xy.FileSystem.Controller; import java.io.IOException; +import java.math.BigInteger; +import java.nio.file.Paths; +import java.util.Date; +import java.util.Iterator; +import java.util.UUID; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; @@ -16,23 +21,33 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder; import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import xy.FileSystem.Cache.UsesCache; +import xy.FileSystem.Entity.Diskfile; +import xy.FileSystem.Entity.DiskfileRepository; import xy.FileSystem.Exception.StorageFileNotFoundException; -import xy.FileSystem.Service.StorageService; - - +import xy.FileSystem.Propert.StorageProperties; +import xy.FileSystem.Service.FileSystemStorageService; +import xy.FileSystem.Service.QiniuService; @Controller public class FileUploadController { - - private final StorageService storageService; - @Autowired - public FileUploadController(StorageService storageService) { - this.storageService = storageService; - } + private FileSystemStorageService storageService; + @Autowired + private QiniuService qiniuService; + @Autowired + private StorageProperties prop; + @Autowired + private DiskfileRepository diskfileRepository; + +// @Autowired +// public FileUploadController(FileSystemStorageService storageService) { +// this.storageService = storageService; +// } @GetMapping("/") public String listUploadedFiles(Model model) throws IOException { @@ -55,16 +70,90 @@ public class FileUploadController { } @PostMapping("/") - public String handleFileUpload(@RequestParam("file") MultipartFile file, - RedirectAttributes redirectAttributes) { - - storageService.store(file); + public String handleFileUpload(MultipartHttpServletRequest request, + RedirectAttributes redirectAttributes,@RequestParam int appid, + @RequestParam String username,@RequestParam String groupid) { + Iterator itr = request.getFileNames(); + MultipartFile file = request.getFile(itr.next()); //只取一个文件,不取多个 + String fileName = file.getOriginalFilename(); + + if (prop.isRename()){ + fileName = username +"_"+ file.getOriginalFilename(); + if (groupid!=null && !groupid.isEmpty()){ + fileName = groupid +"_"+ file.getOriginalFilename(); + } + } + storageService.store(file,fileName); + + if (prop.isToqiniu()){ + try { + qiniuService.store(file.getBytes(), fileName); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + dbSave(appid,username,groupid,file,fileName); + redirectAttributes.addFlashAttribute("message", - "You successfully uploaded " + file.getOriginalFilename() + "!"); + "Successfully uploaded: " + file.getOriginalFilename()); return "redirect:/"; } + public void dbSave(int appid, String username,String groupid, MultipartFile file,String fileName) { + //数据库存储 + Diskfile dbFile = new Diskfile(); + String fileId = UUID.randomUUID().toString(); + + dbFile.setFileid(fileId); + dbFile.setAppid(appid); + dbFile.setFileExt(file.getContentType()); + dbFile.setFileFlag("1"); + dbFile.setFileName(fileName); + dbFile.setFileSize(BigInteger.valueOf(file.getSize())); + dbFile.setIspublic("1"); + dbFile.setUploadDate(new Date()); + dbFile.setUploadUser(username); + dbFile.setUrldisk(prop.getDiskprefix()+fileName); + + //更新缓存 + UsesCache.files++; + UsesCache.usedspace = UsesCache.usedspace + file.getSize(); + + if (prop.isToqiniu()){ + dbFile.setUrlqiniu(prop.getQiniuprefix() + fileName); + } + + diskfileRepository.save(dbFile); + } + +// public String handleFileUpload(@RequestParam("file") MultipartFile file, +// RedirectAttributes redirectAttributes) { +// +// storageService.store(file); +// redirectAttributes.addFlashAttribute("message", +// "Successfully uploaded: " + file.getOriginalFilename()); +// +// return "redirect:/"; +// } + + @PostMapping("/upload") + public String upload(MultipartHttpServletRequest request,RedirectAttributes redirectAttributes) { + + Iterator itr = request.getFileNames(); + + MultipartFile mpf = request.getFile(itr.next()); + + storageService.store(mpf); + redirectAttributes.addFlashAttribute("message", + "Successfully uploaded: " + mpf.getOriginalFilename()); + + return "redirect:/"; + + } + @ExceptionHandler(StorageFileNotFoundException.class) public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) { return ResponseEntity.notFound().build(); diff --git a/src/main/java/xy/FileSystem/Dialect/SQLiteDialect.java b/src/main/java/xy/FileSystem/Dialect/SQLiteDialect.java new file mode 100644 index 0000000..7a5538a --- /dev/null +++ b/src/main/java/xy/FileSystem/Dialect/SQLiteDialect.java @@ -0,0 +1,155 @@ +package xy.FileSystem.Dialect; + +import java.sql.Types; + +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.StandardSQLFunction; +import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.type.StringType; + +public class SQLiteDialect extends Dialect { + public SQLiteDialect() { + registerColumnType(Types.BIT, "integer"); + registerColumnType(Types.TINYINT, "tinyint"); + registerColumnType(Types.SMALLINT, "smallint"); + registerColumnType(Types.INTEGER, "integer"); + registerColumnType(Types.BIGINT, "bigint"); + registerColumnType(Types.FLOAT, "float"); + registerColumnType(Types.REAL, "real"); + registerColumnType(Types.DOUBLE, "double"); + registerColumnType(Types.NUMERIC, "numeric"); + registerColumnType(Types.DECIMAL, "decimal"); + registerColumnType(Types.CHAR, "char"); + registerColumnType(Types.VARCHAR, "varchar"); + registerColumnType(Types.LONGVARCHAR, "longvarchar"); + registerColumnType(Types.DATE, "date"); + registerColumnType(Types.TIME, "time"); + registerColumnType(Types.TIMESTAMP, "timestamp"); + registerColumnType(Types.BINARY, "blob"); + registerColumnType(Types.VARBINARY, "blob"); + registerColumnType(Types.LONGVARBINARY, "blob"); + // registerColumnType(Types.NULL, "null"); + registerColumnType(Types.BLOB, "blob"); + registerColumnType(Types.CLOB, "clob"); + registerColumnType(Types.BOOLEAN, "integer"); + + registerFunction( "concat", new VarArgsSQLFunction(StringType.INSTANCE, "", "||", "") ); + registerFunction( "mod", new SQLFunctionTemplate( StringType.INSTANCE, "?1 % ?2" ) ); + registerFunction( "substr", new StandardSQLFunction("substr", StringType.INSTANCE) ); + registerFunction( "substring", new StandardSQLFunction( "substr", StringType.INSTANCE) ); + } + + public boolean supportsIdentityColumns() { + return true; + } + + /* + public boolean supportsInsertSelectIdentity() { + return true; // As specify in NHibernate dialect + } + */ + + public boolean hasDataTypeInIdentityColumn() { + return false; // As specify in NHibernate dialect + } + + /* + public String appendIdentitySelectToInsert(String insertString) { + return new StringBuffer(insertString.length()+30). // As specify in NHibernate dialect + append(insertString). + append("; ").append(getIdentitySelectString()). + toString(); + } + */ + + public String getIdentityColumnString() { + // return "integer primary key autoincrement"; + return "integer"; + } + + public String getIdentitySelectString() { + return "select last_insert_rowid()"; + } + + public boolean supportsLimit() { + return true; + } + + protected String getLimitString(String query, boolean hasOffset) { + return new StringBuffer(query.length()+20). + append(query). + append(hasOffset ? " limit ? offset ?" : " limit ?"). + toString(); + } + + public boolean supportsTemporaryTables() { + return true; + } + + public String getCreateTemporaryTableString() { + return "create temporary table if not exists"; + } + + public boolean dropTemporaryTableAfterUse() { + return false; + } + + public boolean supportsCurrentTimestampSelection() { + return true; + } + + public boolean isCurrentTimestampSelectStringCallable() { + return false; + } + + public String getCurrentTimestampSelectString() { + return "select current_timestamp"; + } + + public boolean supportsUnionAll() { + return true; + } + + public boolean hasAlterTable() { + return false; // As specify in NHibernate dialect + } + + public boolean dropConstraints() { + return false; + } + + public String getAddColumnString() { + return "add column"; + } + + public String getForUpdateString() { + return ""; + } + + public boolean supportsOuterJoinForUpdate() { + return false; + } + + public String getDropForeignKeyString() { + throw new UnsupportedOperationException("No drop foreign key syntax supported by SQLiteDialect"); + } + + public String getAddForeignKeyConstraintString(String constraintName, + String[] foreignKey, String referencedTable, String[] primaryKey, + boolean referencesPrimaryKey) { + throw new UnsupportedOperationException("No add foreign key syntax supported by SQLiteDialect"); + } + + public String getAddPrimaryKeyConstraintString(String constraintName) { + throw new UnsupportedOperationException("No add primary key syntax supported by SQLiteDialect"); + } + + public boolean supportsIfExistsBeforeTableName() { + return true; + } + + public boolean supportsCascadeDelete() { + return false; + } +} \ No newline at end of file diff --git a/src/main/java/xy/FileSystem/Entity/App.java b/src/main/java/xy/FileSystem/Entity/App.java index c93b68f..5ea45d1 100644 --- a/src/main/java/xy/FileSystem/Entity/App.java +++ b/src/main/java/xy/FileSystem/Entity/App.java @@ -20,7 +20,7 @@ public class App implements Serializable { private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) + @GeneratedValue(strategy=GenerationType.TABLE) private int id; private String appkey; diff --git a/src/main/java/xy/FileSystem/Entity/Dailyreport.java b/src/main/java/xy/FileSystem/Entity/Dailyreport.java index d2c0d2e..c33baec 100644 --- a/src/main/java/xy/FileSystem/Entity/Dailyreport.java +++ b/src/main/java/xy/FileSystem/Entity/Dailyreport.java @@ -13,7 +13,7 @@ public class Dailyreport implements Serializable { private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) + @GeneratedValue(strategy=GenerationType.TABLE) private Long id; private String curdate; diff --git a/src/main/java/xy/FileSystem/Entity/Diskfile.java b/src/main/java/xy/FileSystem/Entity/Diskfile.java index 85dbad8..e37a78a 100644 --- a/src/main/java/xy/FileSystem/Entity/Diskfile.java +++ b/src/main/java/xy/FileSystem/Entity/Diskfile.java @@ -58,6 +58,79 @@ public class Diskfile implements Serializable { private String groupName; private String ispublic; + private String urldisk; + private String urlqiniu; + private String urlfastdfs; + private String urlmongodb; + private String urlbfs; + private String urlpaxossurlre; + private String urlalioss; + + private String urlcfs; + + public String getUrldisk() { + return urldisk; + } + + public void setUrldisk(String urldisk) { + this.urldisk = urldisk; + } + + public String getUrlqiniu() { + return urlqiniu; + } + + public void setUrlqiniu(String urlqiniu) { + this.urlqiniu = urlqiniu; + } + + public String getUrlfastdfs() { + return urlfastdfs; + } + + public void setUrlfastdfs(String urlfastdfs) { + this.urlfastdfs = urlfastdfs; + } + + public String getUrlmongodb() { + return urlmongodb; + } + + public void setUrlmongodb(String urlmongodb) { + this.urlmongodb = urlmongodb; + } + + public String getUrlbfs() { + return urlbfs; + } + + public void setUrlbfs(String urlbfs) { + this.urlbfs = urlbfs; + } + + public String getUrlpaxossurlre() { + return urlpaxossurlre; + } + + public void setUrlpaxossurlre(String urlpaxossurlre) { + this.urlpaxossurlre = urlpaxossurlre; + } + + public String getUrlalioss() { + return urlalioss; + } + + public void setUrlalioss(String urlalioss) { + this.urlalioss = urlalioss; + } + + public String getUrlcfs() { + return urlcfs; + } + + public void setUrlcfs(String urlcfs) { + this.urlcfs = urlcfs; + } @Temporal(TemporalType.TIMESTAMP) private Date uploadDate; diff --git a/src/main/java/xy/FileSystem/Entity/Groupuser.java b/src/main/java/xy/FileSystem/Entity/Groupuser.java index 5773da7..34e0965 100644 --- a/src/main/java/xy/FileSystem/Entity/Groupuser.java +++ b/src/main/java/xy/FileSystem/Entity/Groupuser.java @@ -13,7 +13,7 @@ public class Groupuser implements Serializable { private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) + @GeneratedValue(strategy=GenerationType.TABLE) private Long id; private String groupId; diff --git a/src/main/java/xy/FileSystem/Entity/History.java b/src/main/java/xy/FileSystem/Entity/History.java index d4d7b3b..ef3d9a8 100644 --- a/src/main/java/xy/FileSystem/Entity/History.java +++ b/src/main/java/xy/FileSystem/Entity/History.java @@ -14,7 +14,7 @@ public class History implements Serializable { private static final long serialVersionUID = 1L; @Id - @GeneratedValue(strategy=GenerationType.IDENTITY) + @GeneratedValue(strategy=GenerationType.TABLE) private Long id; private String fileName; diff --git a/src/main/java/xy/FileSystem/File/HttpResult.java b/src/main/java/xy/FileSystem/File/HttpResult.java new file mode 100644 index 0000000..f819920 --- /dev/null +++ b/src/main/java/xy/FileSystem/File/HttpResult.java @@ -0,0 +1,38 @@ +package xy.FileSystem.File; + +import java.io.Serializable; + +public class HttpResult implements Serializable{ + + private static final long serialVersionUID = 5976014738363051675L; + private Integer statusCode; + private String content; + + public HttpResult(Integer statusCode, String content) { + this.statusCode = statusCode; + this.content = content; + } + public Integer getStatusCode() { + return statusCode; + } + + public void setStatusCode(Integer statusCode) { + this.statusCode = statusCode; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + @Override + public String toString() { + return "HttpResult{" + + "statusCode=" + statusCode + + ", content='" + content + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/src/main/java/xy/FileSystem/File/UploadedFile.java b/src/main/java/xy/FileSystem/File/UploadedFile.java new file mode 100644 index 0000000..3564d60 --- /dev/null +++ b/src/main/java/xy/FileSystem/File/UploadedFile.java @@ -0,0 +1,9 @@ +package xy.FileSystem.File; + +public class UploadedFile { + + public int length; + public byte[] bytes; + public String name; + public String type; +} \ No newline at end of file diff --git a/src/main/java/xy/FileSystem/FileSystemApplication.java b/src/main/java/xy/FileSystem/FileSystemApplication.java index fe91dc3..53acfd3 100644 --- a/src/main/java/xy/FileSystem/FileSystemApplication.java +++ b/src/main/java/xy/FileSystem/FileSystemApplication.java @@ -5,11 +5,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableScheduling; +import xy.FileSystem.Cache.UsesCache; import xy.FileSystem.Propert.StorageProperties; import xy.FileSystem.Service.StorageService; @SpringBootApplication +@EnableScheduling @EnableConfigurationProperties(StorageProperties.class) public class FileSystemApplication { @@ -22,6 +25,19 @@ public class FileSystemApplication { return (args) -> { storageService.deleteAll(); storageService.init(); + + initCache(); }; } + + public void initCache() { + //TODO init cache + UsesCache.files = 100; + UsesCache.groups = 100; + UsesCache.usedspace = 100000; + } + + } + + diff --git a/src/main/java/xy/FileSystem/Propert/StorageProperties.java b/src/main/java/xy/FileSystem/Propert/StorageProperties.java index 0b93f3a..0694bc4 100644 --- a/src/main/java/xy/FileSystem/Propert/StorageProperties.java +++ b/src/main/java/xy/FileSystem/Propert/StorageProperties.java @@ -5,24 +5,162 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties("storage") public class StorageProperties { - private String location = "uploadfiles"; - - private String source = "xyfs"; - - public String getLocation() { - return location; - } - - public void setLocation(String location) { - this.location = location; - } - - public String getSource() { - return source; + private String location = "uploadfiles"; + + private boolean rename = true; + + private boolean todisk = true; + private boolean toqiniu = true; + private boolean tofastdfs = false; + private boolean tomongodb = false; + private boolean toseaweedfs = false; + private boolean toalioss = false; + + private String diskprefix = ""; + private String qiniuprefix = ""; + private String qiniuak = ""; + private String qiniusk = ""; + private String qiniubucket = ""; + + private String gridfshost = ""; + private int gridfsport = 27017; + private String gridfsdbname = ""; + private String gridfscollectionname = ""; + + + public String getQiniuprefix() { + return qiniuprefix; } - public void setSource(String source) { - this.source = source; + public void setQiniuprefix(String qiniuprefix) { + this.qiniuprefix = qiniuprefix; } + public String getQiniuak() { + return qiniuak; + } + + public void setQiniuak(String qiniuak) { + this.qiniuak = qiniuak; + } + + public String getQiniusk() { + return qiniusk; + } + + public void setQiniusk(String qiniusk) { + this.qiniusk = qiniusk; + } + + public String getQiniubucket() { + return qiniubucket; + } + + public void setQiniubucket(String qiniubucket) { + this.qiniubucket = qiniubucket; + } + + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + public boolean isTodisk() { + return todisk; + } + + public void setTodisk(boolean todisk) { + this.todisk = todisk; + } + + public boolean isToqiniu() { + return toqiniu; + } + + public void setToqiniu(boolean toqiniu) { + this.toqiniu = toqiniu; + } + + public boolean isTofastdfs() { + return tofastdfs; + } + + public void setTofastdfs(boolean tofastdfs) { + this.tofastdfs = tofastdfs; + } + + public boolean isTomongodb() { + return tomongodb; + } + + public void setTomongodb(boolean tomongodb) { + this.tomongodb = tomongodb; + } + + public boolean isToalioss() { + return toalioss; + } + + public void setToalioss(boolean toalioss) { + this.toalioss = toalioss; + } + + public String getDiskprefix() { + return diskprefix; + } + + public void setDiskprefix(String diskprefix) { + this.diskprefix = diskprefix; + } + + public boolean isRename() { + return rename; + } + + public void setRename(boolean rename) { + this.rename = rename; + } + + public String getGridfshost() { + return gridfshost; + } + + public void setGridfshost(String gridfshost) { + this.gridfshost = gridfshost; + } + + public int getGridfsport() { + return gridfsport; + } + + public void setGridfsport(int gridfsport) { + this.gridfsport = gridfsport; + } + + public String getGridfsdbname() { + return gridfsdbname; + } + + public void setGridfsdbname(String gridfsdbname) { + this.gridfsdbname = gridfsdbname; + } + + public String getGridfscollectionname() { + return gridfscollectionname; + } + + public void setGridfscollectionname(String gridfscollectionname) { + this.gridfscollectionname = gridfscollectionname; + } + + public boolean isToseaweedfs() { + return toseaweedfs; + } + + public void setToseaweedfs(boolean toseaweedfs) { + this.toseaweedfs = toseaweedfs; + } } diff --git a/src/main/java/xy/FileSystem/Service/AliService.java b/src/main/java/xy/FileSystem/Service/AliService.java new file mode 100644 index 0000000..a5cc549 --- /dev/null +++ b/src/main/java/xy/FileSystem/Service/AliService.java @@ -0,0 +1,5 @@ +package xy.FileSystem.Service; + +public class AliService { + +} diff --git a/src/main/java/xy/FileSystem/Service/AppService.java b/src/main/java/xy/FileSystem/Service/AppService.java index 1929983..3de8d37 100644 --- a/src/main/java/xy/FileSystem/Service/AppService.java +++ b/src/main/java/xy/FileSystem/Service/AppService.java @@ -7,6 +7,4 @@ public class AppService { public static AppService context; - - } diff --git a/src/main/java/xy/FileSystem/Service/FastdfsServcice.java b/src/main/java/xy/FileSystem/Service/FastdfsServcice.java new file mode 100644 index 0000000..e4a2719 --- /dev/null +++ b/src/main/java/xy/FileSystem/Service/FastdfsServcice.java @@ -0,0 +1,5 @@ +package xy.FileSystem.Service; + +public class FastdfsServcice { + +} diff --git a/src/main/java/xy/FileSystem/Service/FileSystemStorageService.java b/src/main/java/xy/FileSystem/Service/FileSystemStorageService.java index 1c3447e..36bbc50 100644 --- a/src/main/java/xy/FileSystem/Service/FileSystemStorageService.java +++ b/src/main/java/xy/FileSystem/Service/FileSystemStorageService.java @@ -25,6 +25,8 @@ import xy.FileSystem.Propert.StorageProperties; public class FileSystemStorageService implements StorageService { private final Path rootLocation; + @Autowired + private StorageProperties prop; @Autowired public FileSystemStorageService(StorageProperties properties) { @@ -32,8 +34,13 @@ public class FileSystemStorageService implements StorageService { } @Override - public void store(MultipartFile file) { - String filename = StringUtils.cleanPath(file.getOriginalFilename()); + public void store(MultipartFile file,String fileName) { + String filename = StringUtils.cleanPath(file.getOriginalFilename()); + + if (prop.isRename()){ + filename = fileName; + } + try { if (file.isEmpty()) { throw new StorageException("Failed to store empty file " + filename); @@ -105,4 +112,10 @@ public class FileSystemStorageService implements StorageService { throw new StorageException("Could not initialize storage", e); } } + + @Override + public void store(MultipartFile file) { + // TODO Auto-generated method stub + + } } diff --git a/src/main/java/xy/FileSystem/Service/MongoService.java b/src/main/java/xy/FileSystem/Service/MongoService.java new file mode 100644 index 0000000..003395b --- /dev/null +++ b/src/main/java/xy/FileSystem/Service/MongoService.java @@ -0,0 +1,237 @@ +package xy.FileSystem.Service; + +import java.io.File; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.mongodb.BasicDBObject; +import com.mongodb.DB; +import com.mongodb.DBObject; +import com.mongodb.Mongo; +import com.mongodb.MongoClient; +import com.mongodb.ServerAddress; +import com.mongodb.client.MongoDatabase; +import com.mongodb.gridfs.GridFS; +import com.mongodb.gridfs.GridFSDBFile; +import com.mongodb.gridfs.GridFSFile; + +import xy.FileSystem.Propert.StorageProperties; + +@Service +public class MongoService { + @Autowired + private StorageProperties prop; + + + /** + * @MethodName : getMongo + * @Description : 获取数据连接 + * @return 返回mongon + */ + private MongoClient getMongo(){ + MongoClient mongo=null; + try { + mongo = new MongoClient(new ServerAddress(prop.getGridfshost(), prop.getGridfsport())); + + } catch (Exception e) { + e.printStackTrace(); + } + return mongo; + } + + /** + * @MethodName : uploadFile + * @Description : 上传文件 + * @param file :文件,File类型 + * @param id :唯一标示文件,可根据id查询到文件.必须设置 + * @param dbName :库名,每个系统使用一个库 + * @param collectionName:集合名,如果传入的集合名库中没有,则会自动新建并保存 + * @param map:放入你想要保存的属性,例如文件类型(“congtentType”".jpg"),字符串类型,区分大小写,如果属性没有的话会自动创建并保存 + */ + public void uploadFile(File file,String id,String dbName,String collectionName,LinkedHashMap map){ + //把mongoDB的数据库地址配置在外部。 + try { + MongoClient mongo =getMongo(); + //每个系统用一个库 + + DB db = mongo.getDB(dbName); + System.out.println(db.toString()); + //每个库中可以分子集 + GridFS gridFS= new GridFS(db,collectionName); + + // 创建gridfsfile文件 + GridFSFile gridFSFile = gridFS.createFile(file); + //判断是否已经存在文件,如果存在则先删除 + GridFSDBFile gridFSDBFile=getFileById(id, dbName, collectionName); + if(gridFSDBFile!=null){ + deleteFile(id, dbName, collectionName); + } + //将文件属性设置到 + gridFSFile.put("_id", id); + //循环设置的参数 + if (map != null && map.size() > 0) { + for (String key : map.keySet()) { + gridFSFile.put(key, map.get(key)); + } + } + //保存上传 + gridFSFile.save(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * @MethodName : deleteFile + * @Description : 删除文件 + * @param id:文件对应的id + * @param dbName:文件所在的库 + * @param collectionName:文件所在的集合 + */ + public void deleteFile(String id,String dbName,String collectionName){ + + try { + //获得mongoDB数据库连接。 + MongoClient mongo =getMongo(); + //获得库 + DB db= mongo.getDB(dbName); + //获得子集 + GridFS gridFS= new GridFS(db,collectionName); + //删除文件 + DBObject query=new BasicDBObject("_id", id); + gridFS.remove(query); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * 批量删除文件 + * @MethodName : deleteFileByIds + * @Description : TODO + * @param ids + * @param dbName + * @param collectionName + * + */ + public void deleteFileByIds(String[] ids,String dbName,String collectionName){ + try { + //获得mongoDB数据库连接。 + MongoClient mongo =getMongo(); + //获得库 + DB db= mongo.getDB(dbName); + //获得子集 + GridFS gridFS= new GridFS(db,collectionName); + Map map = new HashMap(); + for(int i=0;i getAllFile(String dbName,String collectionName){ + List gridFSDBFileList=null; + try { + //获得mongoDB数据库连接。 + Mongo mongo =getMongo(); + //获得库 + DB db= mongo.getDB(dbName); + //获得子集 + GridFS gridFS= new GridFS(db,collectionName); + //获得文件 + DBObject query=new BasicDBObject();//空的构造 + gridFSDBFileList = gridFS.find(query); + } catch (Exception e) { + e.printStackTrace(); + } + //返回数据 + return gridFSDBFileList; + } + + + + /** + * 据文件名返回文件,只返回第一个 + * @param fileName + * @return + */ + public GridFSDBFile getByFileName(String fileName,String dbName,String collectionName){ + DBObject query = new BasicDBObject("filename", fileName); + DB db= getMongo().getDB(dbName); + GridFS gridFS= new GridFS(db,collectionName); + GridFSDBFile gridFSDBFile = gridFS.findOne(query); + return gridFSDBFile; + } + + private void downloadFile(GridFSDBFile gridFSDBFile,HttpServletResponse res,String filename) + { + try + { + if (gridFSDBFile != null) + { + + OutputStream sos = res.getOutputStream(); + + res.setCharacterEncoding("UTF-8"); + res.setHeader("Access-Control-Allow-Origin", "*"); + res.setContentType("application/octet-stream"); + res.addHeader("Content-Disposition", "attachment; filename=\"" + filename + "\""); + gridFSDBFile.writeTo(sos); + sos.flush(); + sos.close(); + } + } + catch (Exception e) + { + System.out.println("下载文件异常 ..."); + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/xy/FileSystem/Service/QiniuService.java b/src/main/java/xy/FileSystem/Service/QiniuService.java new file mode 100644 index 0000000..00337ef --- /dev/null +++ b/src/main/java/xy/FileSystem/Service/QiniuService.java @@ -0,0 +1,95 @@ +package xy.FileSystem.Service; + +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.google.gson.Gson; +import com.qiniu.common.QiniuException; +import com.qiniu.common.Zone; +import com.qiniu.http.Response; +import com.qiniu.storage.Configuration; +import com.qiniu.storage.UploadManager; +import com.qiniu.storage.model.DefaultPutRet; +import com.qiniu.util.Auth; + +import xy.FileSystem.Propert.StorageProperties; + +@Service +public class QiniuService { + + @Autowired + private StorageProperties prop; + + public void store(String filePath, String fileName){ + + //构造一个带指定Zone对象的配置类 + Configuration cfg = new Configuration(Zone.huadong());//俺家是华东区的 + //...其他参数参考类注释 + UploadManager uploadManager = new UploadManager(cfg); + //生成上传凭证,然后准备上传 + + String bucket = prop.getQiniubucket(); + String accessKey = prop.getQiniuak(); + String secretKey = prop.getQiniusk(); + //如果是Windows情况下,格式是 D:\\qiniu\\test.png + //如果是linux,格式是/home/qiniu/test.png + String localFilePath = filePath; + //默认不指定key的情况下,以文件内容的hash值作为文件名 + String key = fileName; + Auth auth = Auth.create(accessKey, secretKey); + String upToken = auth.uploadToken(bucket); + try { + Response response = uploadManager.put(localFilePath, key, upToken); + //解析上传成功的结果 + DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); + System.out.println(putRet.key); + System.out.println(putRet.hash); + } catch (QiniuException ex) { + Response r = ex.response; + System.err.println(r.toString()); + try { + System.err.println(r.bodyString()); + } catch (QiniuException ex2) { + //ignore + } + } + + } + + public void store(byte[] bytes, String fileName) { + //构造一个带指定Zone对象的配置类 + Configuration cfg = new Configuration(Zone.zone0()); + //...其他参数参考类注释 + UploadManager uploadManager = new UploadManager(cfg); + //生成上传凭证,然后准备上传 + String bucket = prop.getQiniubucket(); + String accessKey = prop.getQiniuak(); + String secretKey = prop.getQiniusk(); + //默认不指定key的情况下,以文件内容的hash值作为文件名 + String key = fileName; + byte[] uploadBytes = bytes;//"hello qiniu cloud".getBytes("utf-8"); + //ByteArrayInputStream byteInputStream=new ByteArrayInputStream(uploadBytes); + Auth auth = Auth.create(accessKey, secretKey); + String upToken = auth.uploadToken(bucket); + try { + Response response = uploadManager.put(uploadBytes, key, upToken); + //解析上传成功的结果 + DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class); + System.out.println(putRet.key); + System.out.println(putRet.hash); + } catch (QiniuException ex) { + Response r = ex.response; + System.err.println(r.toString()); + try { + System.err.println(r.bodyString()); + } catch (QiniuException ex2) { + //ignore + } + } + + } + +} diff --git a/src/main/java/xy/FileSystem/Service/SeafileService.java b/src/main/java/xy/FileSystem/Service/SeafileService.java new file mode 100644 index 0000000..0ed56f8 --- /dev/null +++ b/src/main/java/xy/FileSystem/Service/SeafileService.java @@ -0,0 +1,5 @@ +package xy.FileSystem.Service; + +public class SeafileService { + +} diff --git a/src/main/java/xy/FileSystem/Service/SeaweedfsService.java b/src/main/java/xy/FileSystem/Service/SeaweedfsService.java new file mode 100644 index 0000000..41e6ee3 --- /dev/null +++ b/src/main/java/xy/FileSystem/Service/SeaweedfsService.java @@ -0,0 +1,5 @@ +package xy.FileSystem.Service; + +public class SeaweedfsService { + +} diff --git a/src/main/java/xy/FileSystem/Service/SfsService.java b/src/main/java/xy/FileSystem/Service/SfsService.java new file mode 100644 index 0000000..8855aa9 --- /dev/null +++ b/src/main/java/xy/FileSystem/Service/SfsService.java @@ -0,0 +1,5 @@ +package xy.FileSystem.Service; + +public class SfsService { + +} diff --git a/src/main/java/xy/FileSystem/Service/StorageService.java b/src/main/java/xy/FileSystem/Service/StorageService.java index be71987..2ad86ce 100644 --- a/src/main/java/xy/FileSystem/Service/StorageService.java +++ b/src/main/java/xy/FileSystem/Service/StorageService.java @@ -20,4 +20,6 @@ public interface StorageService { void deleteAll(); + void store(MultipartFile file, String fileName); + } diff --git a/src/main/java/xy/FileSystem/Utils/HttpHelper.java b/src/main/java/xy/FileSystem/Utils/HttpHelper.java new file mode 100644 index 0000000..ff3af01 --- /dev/null +++ b/src/main/java/xy/FileSystem/Utils/HttpHelper.java @@ -0,0 +1,714 @@ +package xy.FileSystem.Utils; + +import org.apache.http.*; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpRequestRetryHandler; +import org.apache.http.client.config.AuthSchemes; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.config.RequestConfig.Builder; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.ConnectTimeoutException; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.HttpMultipartMode; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.CharsetUtils; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import xy.FileSystem.File.HttpResult; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.*; +import java.net.UnknownHostException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + + +public class HttpHelper { + private static Logger logger = LoggerFactory.getLogger(HttpHelper.class); + private static final String DEFAULT_CHARSET = "UTF-8";// 默认请求编码 + private static final int DEFAULT_SOCKET_TIMEOUT = 5000;// 默认等待响应时间(毫秒) + private static final int DEFAULT_RETRY_TIMES = 0;// 默认执行重试的次数 + + /** + * 创建一个默认的可关闭的HttpClient + * + * @return + */ + public static CloseableHttpClient createHttpClient() { + return createHttpClient(DEFAULT_RETRY_TIMES, DEFAULT_SOCKET_TIMEOUT); + } + + /** + * 创建一个可关闭的HttpClient + * + * @param socketTimeout 请求获取数据的超时时间 + * @return + */ + public static CloseableHttpClient createHttpClient(int socketTimeout) { + return createHttpClient(DEFAULT_RETRY_TIMES, socketTimeout); + } + + /** + * 创建一个可关闭的HttpClient + * + * @param socketTimeout 请求获取数据的超时时间 + * @param retryTimes 重试次数,小于等于0表示不重试 + * @return + */ + public static CloseableHttpClient createHttpClient(int retryTimes, int socketTimeout) { + Builder builder = RequestConfig.custom(); + builder.setConnectTimeout(5000);// 设置连接超时时间,单位毫秒 + builder.setConnectionRequestTimeout(1000);// 设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。 + if (socketTimeout >= 0) { + builder.setSocketTimeout(socketTimeout);// 请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。 + } + RequestConfig defaultRequestConfig = builder.setCookieSpec(CookieSpecs.STANDARD_STRICT).setExpectContinueEnabled(true).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST)).setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build(); + // 开启HTTPS支持 + enableSSL(); + // 创建可用Scheme + Registry socketFactoryRegistry = RegistryBuilder.create().register("http", PlainConnectionSocketFactory.INSTANCE).register("https", socketFactory).build(); + // 创建ConnectionManager,添加Connection配置信息 + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + HttpClientBuilder httpClientBuilder = HttpClients.custom(); + if (retryTimes > 0) { + setRetryHandler(httpClientBuilder, retryTimes); + } + CloseableHttpClient httpClient = httpClientBuilder.setConnectionManager(connectionManager).setDefaultRequestConfig(defaultRequestConfig).build(); + return httpClient; + } + + /** + * 执行GET请求 + * + * @param url 远程URL地址 + * @param charset 请求的编码,默认UTF-8 + * @param socketTimeout 超时时间(毫秒) + * @return HttpResult + * @throws IOException + */ + public static HttpResult executeGet(String url, String charset, int socketTimeout) throws IOException { + CloseableHttpClient httpClient = createHttpClient(socketTimeout); + return executeGet(httpClient, url, null, null, charset, true); + } + + /** + * 执行GET请求 + * + * @param url 远程URL地址 + * @param charset 请求的编码,默认UTF-8 + * @param socketTimeout 超时时间(毫秒) + * @return String + * @throws IOException + */ + public static String executeGetString(String url, String charset, int socketTimeout) throws IOException { + CloseableHttpClient httpClient = createHttpClient(socketTimeout); + return executeGetString(httpClient, url, null, null, charset, true); + } + + /** + * 执行HttpGet请求 + * + * @param httpClient HttpClient客户端实例,传入null会自动创建一个 + * @param url 请求的远程地址 + * @param referer referer信息,可传null + * @param cookie cookies信息,可传null + * @param charset 请求编码,默认UTF8 + * @param closeHttpClient 执行请求结束后是否关闭HttpClient客户端实例 + * @return HttpResult + * @throws ClientProtocolException + * @throws IOException + */ + public static HttpResult executeGet(CloseableHttpClient httpClient, String url, String referer, String cookie, String charset, boolean closeHttpClient) throws IOException { + CloseableHttpResponse httpResponse = null; + try { + charset = getCharset(charset); + httpResponse = executeGetResponse(httpClient, url, referer, cookie); + //Http请求状态码 + Integer statusCode = httpResponse.getStatusLine().getStatusCode(); + String content = getResult(httpResponse, charset); + return new HttpResult(statusCode, content); + } finally { + if (httpResponse != null) { + try { + httpResponse.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (closeHttpClient && httpClient != null) { + try { + httpClient.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + /** + * @param httpClient httpclient对象 + * @param url 执行GET的URL地址 + * @param referer referer地址 + * @param cookie cookie信息 + * @return CloseableHttpResponse + * @throws IOException + */ + public static CloseableHttpResponse executeGetResponse(CloseableHttpClient httpClient, String url, String referer, String cookie) throws IOException { + if (httpClient == null) { + httpClient = createHttpClient(); + } + HttpGet get = new HttpGet(url); + if (cookie != null && !"".equals(cookie)) { + get.setHeader("Cookie", cookie); + } + if (referer != null && !"".equals(referer)) { + get.setHeader("referer", referer); + } + return httpClient.execute(get); + } + + /** + * 执行HttpGet请求 + * + * @param httpClient HttpClient客户端实例,传入null会自动创建一个 + * @param url 请求的远程地址 + * @param referer referer信息,可传null + * @param cookie cookies信息,可传null + * @param charset 请求编码,默认UTF8 + * @param closeHttpClient 执行请求结束后是否关闭HttpClient客户端实例 + * @return String + * @throws ClientProtocolException + * @throws IOException + */ + public static String executeGetString(CloseableHttpClient httpClient, String url, String referer, String cookie, String charset, boolean closeHttpClient) throws IOException { + CloseableHttpResponse httpResponse = null; + try { + charset = getCharset(charset); + httpResponse = executeGetResponse(httpClient, url, referer, cookie); + return getResult(httpResponse, charset); + } finally { + if (httpResponse != null) { + try { + httpResponse.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (closeHttpClient && httpClient != null) { + try { + httpClient.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + + /** + * 简单方式执行POST请求 + * + * @param url 远程URL地址 + * @param paramsObj post的参数,支持map,JSON,XML + * @param charset 请求的编码,默认UTF-8 + * @param socketTimeout 超时时间(毫秒) + * @return HttpResult + * @throws IOException + */ + public static HttpResult executePost(String url, Object paramsObj, String charset, int socketTimeout) throws IOException { + CloseableHttpClient httpClient = createHttpClient(socketTimeout); + return executePost(httpClient, url, paramsObj, null, null, charset, true); + } + + /** + * 简单方式执行POST请求 + * + * @param url 远程URL地址 + * @param paramsObj post的参数,支持map,JSON,XML + * @param charset 请求的编码,默认UTF-8 + * @param socketTimeout 超时时间(毫秒) + * @return HttpResult + * @throws IOException + */ + public static String executePostString(String url, Object paramsObj, String charset, int socketTimeout) throws IOException { + CloseableHttpClient httpClient = createHttpClient(socketTimeout); + return executePostString(httpClient, url, paramsObj, null, null, charset, true); + } + + /** + * 执行HttpPost请求 + * + * @param httpClient HttpClient客户端实例,传入null会自动创建一个 + * @param url 请求的远程地址 + * @param paramsObj 提交的参数信息,目前支持Map,和String(JSON\xml) + * @param referer referer信息,可传null + * @param cookie cookies信息,可传null + * @param charset 请求编码,默认UTF8 + * @param closeHttpClient 执行请求结束后是否关闭HttpClient客户端实例 + * @return + * @throws IOException + * @throws ClientProtocolException + */ + public static HttpResult executePost(CloseableHttpClient httpClient, String url, Object paramsObj, String referer, String cookie, String charset, boolean closeHttpClient) throws IOException { + CloseableHttpResponse httpResponse = null; + try { + charset = getCharset(charset); + httpResponse = executePostResponse(httpClient, url, paramsObj, referer, cookie, charset); + //Http请求状态码 + Integer statusCode = httpResponse.getStatusLine().getStatusCode(); + String content = getResult(httpResponse, charset); + return new HttpResult(statusCode, content); + } finally { + if (httpResponse != null) { + try { + httpResponse.close(); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + if (closeHttpClient && httpClient != null) { + try { + httpClient.close(); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + } + } + + /** + * 执行HttpPost请求 + * + * @param httpClient HttpClient客户端实例,传入null会自动创建一个 + * @param url 请求的远程地址 + * @param paramsObj 提交的参数信息,目前支持Map,和String(JSON\xml) + * @param referer referer信息,可传null + * @param cookie cookies信息,可传null + * @param charset 请求编码,默认UTF8 + * @param closeHttpClient 执行请求结束后是否关闭HttpClient客户端实例 + * @return String + * @throws IOException + * @throws ClientProtocolException + */ + public static String executePostString(CloseableHttpClient httpClient, String url, Object paramsObj, String referer, String cookie, String charset, boolean closeHttpClient) throws IOException { + CloseableHttpResponse httpResponse = null; + try { + charset = getCharset(charset); + httpResponse = executePostResponse(httpClient, url, paramsObj, referer, cookie, charset); + return getResult(httpResponse, charset); + } finally { + if (httpResponse != null) { + try { + httpResponse.close(); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + if (closeHttpClient && httpClient != null) { + try { + httpClient.close(); + } catch (Exception e2) { + e2.printStackTrace(); + } + } + } + } + + /** + * @param httpClient HttpClient对象 + * @param url 请求的网络地址 + * @param paramsObj 参数信息 + * @param referer 来源地址 + * @param cookie cookie信息 + * @param charset 通信编码 + * @return CloseableHttpResponse + * @throws IOException + */ + private static CloseableHttpResponse executePostResponse(CloseableHttpClient httpClient, String url, Object paramsObj, String referer, String cookie, String charset) throws IOException { + if (httpClient == null) { + httpClient = createHttpClient(); + } + HttpPost post = new HttpPost(url); + if (cookie != null && !"".equals(cookie)) { + post.setHeader("Cookie", cookie); + } + if (referer != null && !"".equals(referer)) { + post.setHeader("referer", referer); + } + // 设置参数 + HttpEntity httpEntity = getEntity(paramsObj, charset); + if (httpEntity != null) { + post.setEntity(httpEntity); + } + return httpClient.execute(post); + } + + /** + * 执行文件上传 + * + * @param httpClient HttpClient客户端实例,传入null会自动创建一个 + * @param remoteFileUrl 远程接收文件的地址 + * @param localFilePath 本地文件地址 + * @param charset 请求编码,默认UTF-8 + * @param closeHttpClient 执行请求结束后是否关闭HttpClient客户端实例 + * @return + * @throws ClientProtocolException + * @throws IOException + */ + public static HttpResult executeUploadFile(CloseableHttpClient httpClient, String remoteFileUrl, String localFilePath, String charset, boolean closeHttpClient) throws IOException { + CloseableHttpResponse httpResponse = null; + try { + if (httpClient == null) { + httpClient = createHttpClient(); + } + // 把文件转换成流对象FileBody + File localFile = new File(localFilePath); + FileBody fileBody = new FileBody(localFile); + // 以浏览器兼容模式运行,防止文件名乱码。 + HttpEntity reqEntity = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE).addPart("uploadFile", fileBody).setCharset(CharsetUtils.get("UTF-8")).build(); + // uploadFile对应服务端类的同名属性 + // .addPart("uploadFileName", uploadFileName) + // uploadFileName对应服务端类的同名属性 + HttpPost httpPost = new HttpPost(remoteFileUrl); + httpPost.setEntity(reqEntity); + httpResponse = httpClient.execute(httpPost); + Integer statusCode = httpResponse.getStatusLine().getStatusCode(); + String content = getResult(httpResponse, charset); + return new HttpResult(statusCode, content); + } finally { + if (httpResponse != null) { + try { + httpResponse.close(); + } catch (Exception e) { + } + } + if (closeHttpClient && httpClient != null) { + try { + httpClient.close(); + } catch (Exception e) { + } + } + } + } + + /** + * 执行文件上传(以二进制流方式) + * + * @param httpClient HttpClient客户端实例,传入null会自动创建一个 + * @param remoteFileUrl 远程接收文件的地址 + * @param localFilePath 本地文件地址 + * @param charset 请求编码,默认UTF-8 + * @param closeHttpClient 执行请求结束后是否关闭HttpClient客户端实例 + * @return + * @throws ClientProtocolException + * @throws IOException + */ + public static HttpResult executeUploadFileStream(CloseableHttpClient httpClient, String remoteFileUrl, String localFilePath, String charset, boolean closeHttpClient) throws ClientProtocolException, IOException { + CloseableHttpResponse httpResponse = null; + FileInputStream fis = null; + ByteArrayOutputStream baos = null; + try { + if (httpClient == null) { + httpClient = createHttpClient(); + } + // 把文件转换成流对象FileBody + File localFile = new File(localFilePath); + fis = new FileInputStream(localFile); + byte[] tmpBytes = new byte[1024]; + byte[] resultBytes = null; + baos = new ByteArrayOutputStream(); + int len; + while ((len = fis.read(tmpBytes, 0, 1024)) != -1) { + baos.write(tmpBytes, 0, len); + } + resultBytes = baos.toByteArray(); + ByteArrayEntity byteArrayEntity = new ByteArrayEntity(resultBytes, ContentType.APPLICATION_OCTET_STREAM); + HttpPost httpPost = new HttpPost(remoteFileUrl); + httpPost.setEntity(byteArrayEntity); + httpResponse = httpClient.execute(httpPost); + Integer statusCode = httpResponse.getStatusLine().getStatusCode(); + String content = getResult(httpResponse, charset); + return new HttpResult(statusCode, content); + } finally { + if (baos != null) { + try { + baos.close(); + } catch (Exception e) { + } + } + if (fis != null) { + try { + fis.close(); + } catch (Exception e) { + } + } + if (httpResponse != null) { + try { + httpResponse.close(); + } catch (Exception e) { + } + } + if (closeHttpClient && httpClient != null) { + try { + httpClient.close(); + } catch (Exception e) { + } + } + } + } + + /** + * 执行文件下载 + * + * @param httpClient HttpClient客户端实例,传入null会自动创建一个 + * @param remoteFileUrl 远程下载文件地址 + * @param localFilePath 本地存储文件地址 + * @param charset 请求编码,默认UTF-8 + * @param closeHttpClient 执行请求结束后是否关闭HttpClient客户端实例 + * @return + * @throws ClientProtocolException + * @throws IOException + */ + public static boolean executeDownloadFile(CloseableHttpClient httpClient, String remoteFileUrl, String localFilePath, String charset, boolean closeHttpClient) throws ClientProtocolException, IOException { + CloseableHttpResponse response = null; + InputStream in = null; + FileOutputStream fout = null; + try { + HttpGet httpget = new HttpGet(remoteFileUrl); + response = httpClient.execute(httpget); + HttpEntity entity = response.getEntity(); + if (entity == null) { + return false; + } + in = entity.getContent(); + File file = new File(localFilePath); + fout = new FileOutputStream(file); + int l; + byte[] tmp = new byte[1024]; + while ((l = in.read(tmp)) != -1) { + fout.write(tmp, 0, l); + // 注意这里如果用OutputStream.write(buff)的话,图片会失真 + } + // 将文件输出到本地 + fout.flush(); + EntityUtils.consume(entity); + return true; + } finally { + // 关闭低层流。 + if (fout != null) { + try { + fout.close(); + } catch (Exception e) { + } + } + if (response != null) { + try { + response.close(); + } catch (Exception e) { + } + } + if (closeHttpClient && httpClient != null) { + try { + httpClient.close(); + } catch (Exception e) { + } + } + } + } + + /** + * 根据参数获取请求的Entity + * + * @param paramsObj + * @param charset + * @return + * @throws UnsupportedEncodingException + */ + private static HttpEntity getEntity(Object paramsObj, String charset) throws UnsupportedEncodingException { + if (paramsObj == null) { + logger.info("当前未传入参数信息,无法生成HttpEntity"); + return null; + } + if (Map.class.isInstance(paramsObj)) {// 当前是map数据 + @SuppressWarnings("unchecked") + Map paramsMap = (Map) paramsObj; + List list = getNameValuePairs(paramsMap); + UrlEncodedFormEntity httpEntity = new UrlEncodedFormEntity(list, charset); + httpEntity.setContentType(ContentType.APPLICATION_FORM_URLENCODED.getMimeType()); + return httpEntity; + } else if (String.class.isInstance(paramsObj)) {// 当前是string对象,可能是 + String paramsStr = (String) paramsObj; + StringEntity httpEntity = new StringEntity(paramsStr, charset); + if (paramsStr.startsWith("{")) { + httpEntity.setContentType(ContentType.APPLICATION_JSON.getMimeType()); + } else if (paramsStr.startsWith("<")) { + httpEntity.setContentType(ContentType.APPLICATION_XML.getMimeType()); + } else { + httpEntity.setContentType(ContentType.APPLICATION_FORM_URLENCODED.getMimeType()); + } + return httpEntity; + } else { + logger.info("当前传入参数不能识别类型,无法生成HttpEntity"); + } + return null; + } + + /** + * 从结果中获取出String数据 + * + * @param httpResponse http结果对象 + * @param charset 编码信息 + * @return String + * @throws ParseException + * @throws IOException + */ + private static String getResult(CloseableHttpResponse httpResponse, String charset) throws ParseException, IOException { + String result = null; + if (httpResponse == null) { + return result; + } + HttpEntity entity = httpResponse.getEntity(); + if (entity == null) { + return result; + } + result = EntityUtils.toString(entity, charset); + EntityUtils.consume(entity);// 关闭应该关闭的资源,适当的释放资源 ;也可以把底层的流给关闭了 + return result; + } + + /** + * 转化请求编码 + * + * @param charset 编码信息 + * @return String + */ + private static String getCharset(String charset) { + return charset == null ? DEFAULT_CHARSET : charset; + } + + /** + * 将map类型参数转化为NameValuePair集合方式 + * + * @param paramsMap + * @return + */ + private static List getNameValuePairs(Map paramsMap) { + List list = new ArrayList<>(); + if (paramsMap == null || paramsMap.isEmpty()) { + return list; + } + for (Entry entry : paramsMap.entrySet()) { + list.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); + } + return list; + } + + /** + * 开启SSL支持 + */ + private static void enableSSL() { + try { + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, new TrustManager[]{manager}, null); + socketFactory = new SSLConnectionSocketFactory(context, NoopHostnameVerifier.INSTANCE); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static SSLConnectionSocketFactory socketFactory; + + // HTTPS网站一般情况下使用了安全系数较低的SHA-1签名,因此首先我们在调用SSL之前需要重写验证方法,取消检测SSL。 + private static TrustManager manager = new X509TrustManager() { + + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + // + + } + + @Override + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + // + + } + }; + + /** + * 为httpclient设置重试信息 + * + * @param httpClientBuilder + * @param retryTimes + */ + private static void setRetryHandler(HttpClientBuilder httpClientBuilder, final int retryTimes) { + HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() { + public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { + if (executionCount >= retryTimes) { + // Do not retry if over max retry count + return false; + } + if (exception instanceof InterruptedIOException) { + // Timeout + return false; + } + if (exception instanceof UnknownHostException) { + // Unknown host + return false; + } + if (exception instanceof ConnectTimeoutException) { + // Connection refused + return false; + } + if (exception instanceof SSLException) { + // SSL handshake exception + return false; + } + HttpClientContext clientContext = HttpClientContext.adapt(context); + HttpRequest request = clientContext.getRequest(); + boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); + if (idempotent) { + // 如果请求被认为是幂等的,那么就重试 + // Retry if the request is considered idempotent + return true; + } + return false; + } + }; + httpClientBuilder.setRetryHandler(myRetryHandler); + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e934221..6fdcfe7 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,26 +1,73 @@ # tomcat\u670d\u52a1\u7aef\u53e3 # server.port=9091 +#\u542f\u7528shutdown +endpoints.sensitive=false -# \u5b58\u50a8\u6e90\uff0c\u7c7b\u578b\u6709\uff1axyfs\\Seafile\\FastDFS\\MongoDB\\BFS\\PaxosStore\\aliOSS\\qiniu\\CFS # -storage.source = xyfs # \u5b58\u50a8\u7684\u76f8\u5bf9\u8def\u5f84\uff0c\u5982\u679c storage.source = xyfs \u9700\u8981\u914d\u7f6e # storage.location = uploadfiledir +# \u662f\u5426\u91cd\u65b0\u547d\u540d\u6587\u4ef6\u540d\uff0c\u5982\u679c\u662f\u4e2a\u4eba\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1ausername_ + \u539f\u6587\u4ef6\u540d\uff1b\u5982\u679c\u662f\u7fa4\u7ec4\u6587\u4ef6\u5219\u91cd\u547d\u540d\u4e3a\uff1agroupid_ + \u539f\u6587\u4ef6\u540d # +storage.rename = true + +# \u5b58\u50a8\u6e90\uff0c\u7c7b\u578b\u6709\uff1axyfs\\Seafile\\FastDFS\\SeaweedFS\\MongoDB\\aliOSS\\qiniu\\CFS # +storage.todisk = true +storage.toqiniu = true +storage.tofastdfs = false +storage.tomongodb = false +storage.toseaweedfs = false +storage.toalioss = false +storage.tocfs = false + +storage.diskprefix = http://localhost:9091/files/ + +# \u4e03\u725b\u5b58\u50a8\u914d\u7f6e # +storage.qiniuprefix = http://pbby0yzdu.bkt.clouddn.com/ +storage.qiniuak = _IAafy8aX5x7h-4FBEvH2DqCtTq2c7sESPSlfGgI +storage.qiniusk = _8hy2LE6kfTKr3wDUWJONgFRxPKX4cDQhi79Bj3Y +storage.qiniubucket = xytalk + +# mongodb.gridfs\u914d\u7f6e # +storage.gridfshost = 127.0.0.1 +storage.gridfsdbname = xyfs +storage.gridfsport = 27017 +storage.gridfscollectionname = fs + +# fastDFS \u914d\u7f6e # +storage.fastdfsconnecttimeout = 5 +storage.fastdfsnetwork_timeout = 10 +storage.fastdfscharset = UTF-8 +storage.fastdfstrackerhttpport = 80 +storage.fastdfsantistealtoken = no +storage.fastdfssecret_key = 1234567890 +storage.fastdfstrackerserver = 192.168.17.112:22122 + +# SeaweedFS \u914d\u7f6e # +storage.seaweedfshost = localhost +storage.seaweedfsport = 9333 +storage.seaweedfstimeout = 5000 + # \u7b2c\u4e00\u6b21\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u81ea\u52a8\u521b\u5efa\u6570\u636e\u5e93\u8868\uff0c\u5982\u679c\u662f\u8fd0\u884cSQL\u811a\u672c\u5219\u65e0\u9700\u4f7f\u7528\u6b64\u914d\u7f6e # # spring.jpa.hibernate.ddl-auto = create - # \u7b2c\u4e8c\u6b21\u5f00\u59cb\u4f7f\u7528\u7684\u914d\u7f6e\uff1a\u636e\u5e93\u8868\u4f1a\u6839\u636eEntity\u7684\u53d8\u52a8\u800c\u66f4\u65b0 # -spring.jpa.hibernate.ddl-auto = update -spring.datasource.url=jdbc:mysql://localhost:3306/xyfs -spring.datasource.username=root -spring.datasource.password=mysql + spring.jpa.hibernate.ddl-auto = update + +# Sqlite\u6570\u636e\u6e90 # +spring.datasource.driver-class-name=org.sqlite.JDBC +spring.datasource.url=jdbc:sqlite:DbSqlite/xyfs.db +spring.datasource.platform=sqlite +spring.jpa.database-platform= xy.FileSystem.Dialect.SQLiteDialect + +# mysql\u6570\u636e\u6e90 # +#spring.datasource.url=jdbc:mysql://localhost:3306/xyfs +#spring.datasource.username=root +#spring.datasource.password=mysql # dbcp2\u8fde\u63a5\u6c60\u914d\u7f6e # spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource spring.datasource.dbcp2.max-wait-millis=10000 spring.datasource.dbcp2.min-idle=5 spring.datasource.dbcp2.initial-size=5 -spring.datasource.dbcp2.validation-query=SELECT 1 FROM App +spring.datasource.dbcp2.validation-query=SELECT 1 FROM app spring.datasource.dbcp2.connection-properties=characterEncoding=utf8 # druid\u8fde\u63a5\u6c60\u7684\u914d\u7f6e\u4fe1\u606f # diff --git a/src/main/resources/templates/uploadForm.html b/src/main/resources/templates/uploadForm.html index a8c935a..8ca42ce 100644 --- a/src/main/resources/templates/uploadForm.html +++ b/src/main/resources/templates/uploadForm.html @@ -8,7 +8,10 @@
- + + + +
File to upload:
upload: