增加七牛文件支持

This commit is contained in:
昕有灵犀
2018-07-05 17:04:28 +08:00
parent e8725dd72e
commit 982c5831ec
34 changed files with 1871 additions and 66 deletions

View File

@@ -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
)

BIN
DbSqlite/xyfs.db Normal file

Binary file not shown.

View File

@@ -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

2
bin/main/.gitignore vendored
View File

@@ -1,2 +0,0 @@
/xy/
/templates/

View File

@@ -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 #

View File

@@ -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")

View File

@@ -0,0 +1,9 @@
package xy.FileSystem.Cache;
public class UsesCache {
public static double usedspace;
public static int files;
public static int groups;
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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<String> 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<String> 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();

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 + '\'' +
'}';
}
}

View File

@@ -0,0 +1,9 @@
package xy.FileSystem.File;
public class UploadedFile {
public int length;
public byte[] bytes;
public String name;
public String type;
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,5 @@
package xy.FileSystem.Service;
public class AliService {
}

View File

@@ -7,6 +7,4 @@ public class AppService {
public static AppService context;
}

View File

@@ -0,0 +1,5 @@
package xy.FileSystem.Service;
public class FastdfsServcice {
}

View File

@@ -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
}
}

View File

@@ -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<String, Object> 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<String,String> map = new HashMap<String,String>();
for(int i=0;i<ids.length;i++){
//删除文件
DBObject query=new BasicDBObject("_id", ids[i]);
gridFS.remove(query);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @MethodName : getFileById
* @Description : 根据Id获得文件
* @param id 文件Id
* @param dbName: 数据库名
* @param collectionName集合名
* @return GridFSDBFile
*/
public GridFSDBFile getFileById(String id,String dbName,String collectionName){
GridFSDBFile gridFSDBFile=null;
try {
//获得mongoDB数据库连接。
Mongo mongo =getMongo();
//获得库
DB db= mongo.getDB(dbName);
//获得子集
GridFS gridFS= new GridFS(db,collectionName);
//获得文件
DBObject query=new BasicDBObject("_id", id);
gridFSDBFile=gridFS.findOne(query);
} catch (Exception e) {
e.printStackTrace();
}
//返回数据
return gridFSDBFile;
}
/**查询集合中所有文件
* @MethodName : getAllFile
* @Description : TODO
* @param dbName
* @param collectionName *
* @return
*/
public List<GridFSDBFile> getAllFile(String dbName,String collectionName){
List<GridFSDBFile> 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();
}
}
}

View File

@@ -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
}
}
}
}

View File

@@ -0,0 +1,5 @@
package xy.FileSystem.Service;
public class SeafileService {
}

View File

@@ -0,0 +1,5 @@
package xy.FileSystem.Service;
public class SeaweedfsService {
}

View File

@@ -0,0 +1,5 @@
package xy.FileSystem.Service;
public class SfsService {
}

View File

@@ -20,4 +20,6 @@ public interface StorageService {
void deleteAll();
void store(MultipartFile file, String fileName);
}

View File

@@ -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<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>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<String,String>,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<String,String>,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对应服务端类的同名属性<File类型>
// .addPart("uploadFileName", uploadFileName)
// uploadFileName对应服务端类的同名属性<String类型>
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<String, String> paramsMap = (Map<String, String>) paramsObj;
List<NameValuePair> 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<NameValuePair> getNameValuePairs(Map<String, String> paramsMap) {
List<NameValuePair> list = new ArrayList<>();
if (paramsMap == null || paramsMap.isEmpty()) {
return list;
}
for (Entry<String, String> 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);
}
}

View File

@@ -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 #

View File

@@ -8,7 +8,10 @@
<div>
<form method="POST" enctype="multipart/form-data" action="/">
<table>
<tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
<input type="hidden" name="appid" value="100" />
<input type="hidden" name="username" value="wangxin" />
<input type="hidden" name="groupid" value="" />
<tr><td>upload:</td><td><input type="file" name="file" /></td></tr>
<tr><td></td><td><input type="submit" value="Upload" /></td></tr>
</table>
</form>