Java+Springboot搭建一个在线网盘文件分享系统

网友投稿 406 2022-09-12


Java+Springboot搭建一个在线网盘文件分享系统

目录前言效果图主要代码管理员控制器:文件仓库控制器:登录控制器:FTP工具类:

前言

springboot+freemark+jpa+mysql实现的在线网盘文件分享系统,其功能跟百度网盘非常类似,普通用户可以注册登录,注册后默认分配1G的空间大小,登录进去后可以新建文件夹、上传各种类型的文件、文件移动、复制、下载、删除、分享,分享分为私密分享和公开分享,还可以设置分享过期时间,打开分享链接后可以对文件进行查看、下载、保存到自己网盘等。超级管理员登录后可以设置普通用户的空间大小、角色类型、权限等。

本系统主要涉及的特色功能有:

1:系统在上传文件时自动计算文件的md5值,并且检查该值是否存在,若存在则文件不再上传到服务器,直接进行引用原有的文件。

2:定时器定时检查限时分享的文件是否过期。

3:网盘目录结构可无限制层级创建,保存移动复制文件时递归所选文件夹层级等等。

使用技术:java+springboot+freemark+jpa+MySQL+maven

效果图

主要代码

管理员控制器:

/**

* @ClassName: AdminController

* @Description: 管理员控制器

**/

@Controller

public class AdminController extends BaseController {

private Logger logger = LogUtils.getInstance(AdminController.class);

/**

* @Description 前往用户管理页面

**/

@GetMapping("/manages-users")

public String manageUsers(Map map,Integer cur){

if (loginUser.getRole() == 1){

//用于无访问权限

logger.error("当前登录用户:"+loginUser.getUserName()+"无管理员权限!");

return "redirect:/error401Page";

}

//获取全部的用户

Integer usersCount = userService.getUsersCount();

//获取当前查询的页数,如果为空,默认为0

cur = (cur == null || cur<0)?0:cur;

//获得统计信息

FileStoreStatistics statistics = myFileService.getCountStatistics(loginUser.getFileStoreId());

//分页获得20个用户信息

Page page = PageHelper.startPage(cur, 20);

List users = userService.getUsers();

map.put("statistics", statistics);

map.put("users", users);

map.put("page", page);

map.put("usersCount", usersCount);

logger.info("用户管理域的内容:"+map);

return "admin/manage-users";

}

/**

* @Description 修改用户的权限和最大容量

**/

@GetMapping("/updateStoreInfo")

@ResponseBody

public String updateStoreInfo(Integer uId,Integer pre,Integer size){

Integer integer = fileStoreService.updatePermission(uId, pre, size*1024);

if (integer == 1) {

//更新成功,返回200状态码

logger.info("修改用户"+userService.queryById(uId).getUserName()+":的权限和仓库大小成功!");

return "200";

}else {

//更新失败,返回500状态码

logger.error("修改用户"+userService.queryById(uId).getUserName()+":的权限和仓库大小失败!");

return "500";

}

}

/**

* @Description 删除用户

**/

@GetMapping("/deleteUser")

public String deleteUser(Integer uId,Integer cur){

cur = (cur == null || cur < 0)?1:cur;

User user = userService.queryById(uId);

FileStore fileStore = fileStoreService.getFileStoreByUserId(uId);

List folders = fileFolderService.getRootFoldersByFileStoreId(fileStore.getFileStoreId());

//迭代删除文件夹

for (FileFolder f:folders) {

deleteFolderF(f);

}

List files = myFileService.getRootFilesByFileStoreId(fileStore.getFileStoreId());

//删除该用户仓库根目录下的所有文件

for (MyFile f:files) {

String remotePath = f.getMyFilePath();

String fileName = f.getMyFileName()+f.getPostfix();

//从FTP文件服务器上删除文件

boolean b = FtpUtil.deleteFile("/"+remotePath, fileName);

if (b){

//删除成功,返回空间

fileStoreService.subSizhttp://e(f.getFileStoreId(),Integer.valueOf(f.getSize()));

//删除文件表对应的数据

myFileService.deleteByFileId(f.getMyFileId());

}

logger.info("删除文件成功!"+f);

}

if (FtpUtil.deleteFolder("/" + uId)){

logger.info("清空FTP上该用户的文件成功");

}else {

logger.error("清空FTP上该用户的文件失败");

}

userService.deleteById(uId);

fileStoreService.deleteById(fileStore.getFileStoreId());

return "redirect:/manages-users?cur="+cur;

}

/**

* @Description 迭代删除文件夹里面的所有文件和子文件夹

**/

public void deleteFolderF(FileFolder folder){

//获得当前文件夹下的所有子文件夹

List folders = fileFolderService.getFileFolderByParentFolderId(folder.getFileFolderId());

//删除当前文件夹的所有的文件

List files = myFileService.getFilesByParentFolderId(folder.getFileFolderId());

if (files.size()!=0){

for (int i = 0; i < files.size(); i++) {

Integer fileId = files.get(i).getMyFileId();

boolean b = FtpUtil.deleteFile("/"+files.get(i).getMyFilePath(), files.get(i).getMyFileName() + files.get(i).getPostfix());

if (b){

myFileService.deleteByFileId(fileId);

fileStoreService.subSize(folder.getFileStoreId(),Integer.valueOf(files.get(i).getSize()));

}

}

}

if (folders.size()!=0){

for (int i = 0; i < folders.size(); i++) {

deleteFolderF(folders.get(i));

}

}

fileFolderService.deleteFileFolderById(folder.getFileFolderId());

}

}

文件仓库控制器:

登录控制器:

/**

* @Description 登录控制器

**/

@Controller

public class LoginController extends BaseController {

private Logger logger = LogUtils.getInstance(LoginController.class);

/**

* @Description 免登陆用户入口,用于本地开发测试,上线运营为了安全请删除此方法

* @Author xw

* @Date 15:17 2020/2/26

* @Param []

* @return java.lang.String

**/

@GetMapping("/admin")

public String adminLogin(){

User user = userService.getUserByOpenId("123456");

logger.info("使用免登陆方式登录成功!"+user);

session.setAttribute("loginUser", user);

return "redirect:/index";

}

/**

* 用于注册流程,用户名,密码,邮箱等校验工作由前端来完成

*/

@PostMapping("/register")

public String register(User user, String code, Map map) {

String uCode = (String) session.getAttribute(user.getEmail() + "_code");

if (!code.equals(uCode)) {

map.put("errorMsg", "验证码错误");

return "index";

}

// 用户名去空格

user.setUserName(user.getUserName().trim());

user.setImagePath("https://p.qpic.cn/qqconnect/0/app_101851241_1582451550/100?max-age=2592000&t=0");

user.setRegisterTime(new Date());

user.setRole(1);

if (userService.insert(user)) {

FileStore store = FileStore.builder().userId(user.getUserId()).currentSize(0).build();

fileStoreService.addFileStore(store);

user.setFileStoreId(store.getFileStoreId());

userService.update(user);

logger.info("注册用户成功!当前注册用户" + user);

logger.info("注册仓库成功!当前注册仓库" + store);

} else {

map.put("errorMsg", "服务器发生错误,注册失败");

return "index";

}

session.removeAttribute(user.getEmail() + "_code");

session.setAttribute("loginUser", user);

return "redirect:/index";

}

/**

* 用户登录

*/

@PostMapping("/login")

public String login(User user, Map map) {

User userByEmail = userService.getUserByEmail(user.getEmail());

if (userByEmail != null && userByEmail.getPassword().equals(user.getPassword())) {

session.setAttribute("loginUser", userByEmail);

logger.info("登录成功!"+userByEmail);

return "redirect:/index";

}else{

User user1 = userService.getUserByEmail(user.getEmail());

String errorMsg = user1 == null ? "该邮箱尚未注册" : "密码错误";

logger.info("登录失败!请确认邮箱和密码是否正确!");

//登录失败,将失败信息返回前端渲染

map.put("errorMsg", errorMsg);

return "index";

}

}

/**

* @return void

* @Description 向注册邮箱发送验证码, 并验证邮箱是否已使用

**/

@ResponseBody

@RequestMapping("/sendCode")

public String sendCode(String userName, String email, String password) {

User userByEmail = userService.getUserByEmail(email);

if (userByEmail != null) {

logger.error("发送验证码失败!邮箱已被注册!");

return "exitEmail";

}

logger.info("开始发送邮件.../n" + "获取的到邮件发送对象为:" + mailSender);

mailUtils = new MailUtils(mailSender);

String code = "123456";

session.setAttribute(email + "_code", code);

return "success";

}

/**

* @Description 请求QQ登录

**/

@GetMapping("/loginByQQ")

public void login() {

response.setContentType("text/html;charset=utf-8");

try {

response.sendRedirect(new Oauth().getAuthorizeURL(request));

logger.info("请求QQ登录,开始跳转...");

} catch (QQConnectException | IOException e) {

e.printStackTrace();

}

}

/**

* @Description QQ登录回调地址

**/

@GetMapping("/connection")

public String connection() {

try {

AccessToken accessTokenObj = (new Oauth()).getAccessTokenByRequest(request);

String accessToken = null, openID = null;

long tokenExpireIn = 0L;

if ("".equals(accessTokenObj.getAccessToken())) {

logger.error("登录失败:没有获取到响应参数");

return "accessTokenObj=>" + accessTokenObj + "; accessToken" + accessTokenObj.getAccessToken();

} else {

accessToken = accessTokenObj.getAccessToken();

tokenExpireIn = accessTokenObj.getExpireIn();

logger.error("accessToken" + accessToken);

request.getSession().setAttribute("demo_access_token", accessToken);

request.getSession().setAttribute("demo_token_expirein", String.valueOf(tokenExpireIn));

// 利用获取到的accessToken 去获取当前用的openid -------- start

OpenID openIDObj = new OpenID(accessToken);

openID = openIDObj.getUserOpenID();

UserInfo qzoneUserInfo = new UserInfo(accessToken, openID);

UserInfoBean userInfoBean = qzoneUserInfo.getUserInfo();

if (userInfoBean.getRet() == 0) {

logger.info("用户的OPEN_ID: " + openID);

logger.info("用户的昵称: " + removeNonBmpUnicode(userInfoBean.getNickname()));

logger.info("用户的头像URI: " + userInfoBean.getAvatar().getAvatarURL100());

//设置用户信息

User user = userService.getUserByOpenId(openID);

if (user == null){

user = User.builder()

.openId(openID).userName(removeNonBmpUnicode(userInfoBean.getNickname()))

.imagePath(userInfoBean.getAvatar().getAvatarURL100()).

registerTime(new Date()).build();

if (userService.insert(user)){

logger.info("注册用户成功!当前注册用户" + user);

FileStore store = FileStore.builder().userId(user.getUserId()).build();

if (fileStoreService.addFileStore(store) == 1){

user.setFileStoreId(store.getFileStoreId());

userService.update(user);

logger.info("注册仓库成功!当前注册仓库" + store);

}

} else {

logger.error("注册用户失败!");

}

}else {

user.setUserName(removeNonBmpUnicode(userInfoBean.getNickname()));

user.setImagePath(userInfoBean.getAvatar().getAvatarURL100());

userService.update(user);

}

logger.info("QQ用户登录成功!"+user);

session.setAttribute("loginUser", user);

return "redirect:/index";

} else {

logger.error("很抱歉,我们没能正确获取到您的信息,原因是: " + userInfoBean.getMsg());

}

}

} catch (QQConnectException e) {

} finally {

logger.error("登录成功!");

}

return "登录失败!请查看日志信息...";

}

/**

* @Description 处理掉QQ网名中的特殊表情

**/

public String removeNonBmpUnicode(String str) {

if (str == null) {

return null;

}

str = str.replaceAll("[^\\u0000-\\uFFFF]", "");

if ("".equals(str)) {

str = "($ _ $)";

}

return str;

}

/**

* @Description 退出登录,清空session

**/

@GetMapping("/logout")

public String logout() {

logger.info("用户退出登录!");

session.invalidate();

return "redirect:/";

}

}

FTP工具类:

/**

* @ClassName: FtpUtil

* @Description: FTP工具类

**/

public class FtpUtil {

/**

* FTP服务器hostname

*/

private static String HOST = "192.168.1.106";

/**

* FTP服务器端口

*/

private static int PORT = 21;

/**

* FTP登录账号

*/

private static String USERNAME = "chen";

/**

* FTP登录密码

*/

private static String PASSWORD = "chenfuning";

/**

* FTP服务器基础目录

*/

private static String BASEPATH = "";

/**

* FTP客户端

*/

private static FTPClient ftp;

/**

* @Description 初始化FTP客户端

**/

public static boolean initFtpClient(){

ftp = new FTPClient();

int reply;

try {

// 连接FTP服务器

ftp.connect(HOST, PORT);

//登录, 如果采用默认端口,可以使用ftp.connect(host)的方式直接连接FTP服务器

ftp.login(USERNAME, PASSWORD);

ftp.setBufferSize(10240);

//设置传输超时时间为60秒

ftp.setDataTimeout(600000);

//连接超时为60秒

ftp.setConnectTimeout(600000);

//FTP以二进制形式传输

ftp.setFileType(FTP.BINARY_FILE_TYPE);

reply = ftp.getReplyCode();

if (!FTPReply.isPositiveCompletion(reply)) {

ftp.disconnect();

return false;

}

} catch (IOException e) {

e.printStackTrace();

}

return true;

}

/**

* Description: 向FTP服务器上传文件

* @param filePath FTP服务器文件存放路径。例如分日期存放:/2015/01/01。文件的路径为basePath+filePath

* @param filename 上传到FTP服务器上的文件名

* @param input 本地要上传的文件的 输入流

* @return 成功返回true,否则返回false

*/

public static boolean uploadFile(String filePath, String filename, InputStream input) {

boolean result = false;

try {

filePath = new String(filePath.getBytes("GBK"),"iso-8859-1");

filename = new String(filename.getBytes("GBK"),"iso-8859-1");

if (!initFtpClient()){

return result;

};

//切换到上传目录

ftp.enterLocalPassiveMode();

if (!ftp.changeWorkingDirectory(BASEPATH+filePath)) {

//如果目录不存在创建目录

String[] dirs = filePath.split("/");

String tempPath = BASEPATH;

for (String dir : dirs) {

if (null == dir || "".equals(dir)){

continue;

}

tempPath += "/" + dir;

if (!ftp.changeWorkingDirectory(tempPath)) {

if (!ftp.makeDirectory(tempPath)) {

return result;

} else {

ftp.changeWorkingDirectory(tempPath);

}

}

}

}

//设置上传文件的类型为二进制类型

ftp.setFileType(FTP.BINARY_FILE_TYPE);

//上传文件

ftp.enterLocalPassiveMode();

if (!ftp.storeFile(filename, input)) {

return result;

}

input.close();

ftp.logout();

result = true;

}

catch (IOException e) {

e.printStackTrace();

} finally {

if (ftp.isConnected()) {

try {

ftp.disconnect();

} catch (IOException ioe) {

}

}

}

return result;

}

/**

* Description: 从FTP服务器下载文件

* @param remotePath FTP服务器上的相对路径

* @param fileName 要下载的文件名

* @return

*/

public static boolean downloadFile( String remotePath,String fileName,String localPath) {

boolean result = false;

try {

remotePath = new String(remotePath.getBytes("GBK"),"iso-8859-1");

fileName = new String(fileName.getBytes("GBK"),"iso-8859-1");

if (!initFtpClient()){

return result;

};

// 转移到FTP服务器目录

ftp.changeWorkingDirectory(remotePath);

ftp.enterLocalPassiveMode();

FTPFile[] fs = ftp.listFiles();

for (FTPFile ff : fs) {

if (ff.getName().equals(fileName)) {

ftp.enterLocalPassiveMode();

FileOutputStream outputStream = new FileOutputStream(new File(localPath));

ftp.retrieveFile(remotePath+"/"+fileName,outputStream);

result = true;

outputStream.close();

}

}

ftp.logout();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (ftp.isConnected()) {

try {

ftp.disconnect();

} catch (IOException ioe) {

}

}

}

return result;

}

/**

* @Description 从ftp服务器下载文件到指定输出流

* @Param [remotePath, fileName, outputStream]

* @return boolean

**/

public static boolean downloadFile(String remotePath, String fileName, OutputStream outputStream) {

boolean result = false;

try {

remotePath = new String(remotePath.getBytes("GBK"),"iso-8859-1");

fileName = new String(fileName.getBytes("GBK"),"iso-8859-1");

if (!initFtpClient()){

return result;

};

// 转移到FTP服务器目录

ftp.changeWorkingDirectory(remotePath);

ftp.enterLocalPassiveMode();

FTPFile[] fs = ftp.listFiles();

for (FTPFile ff : fs) {

if (ff.getName().equals(fileName)) {

ftp.enterLocalPassiveMode();

ftp.retrieveFile(remotePath+"/"+fileName,outputStream);

result = true;

}

}

ftp.logout();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (ftp.isConnected()) {

try {

ftp.disconnect();

} catch (IOException ioe) {

}

}

}

return result;

}

/**

* @Description 删除文件

* @Param [remotePath, fileName]

* @return void

**/

public static boolean deleteFile( String remotePath,String fileName){

boolean flag = false;

try {

remotePath = new String(remotePath.getBytes("GBK"),"iso-8859-1");

fileName = new String(fileName.getBytes("GBK"),"iso-8859-1");

if (!initFtpClient()){

return flag;

};

// 转移到FTP服务器目录

ftp.changeWorkingDirectory(remotePath);

ftp.enterLocalPassiveMode();

FTPFile[] fs = ftp.listFiles();

for (FTPFile ff : fs) {

if ("".equals(fileName)){

return flag;

}

if (ff.getName().equals(fileName)){

String filePath = remotePath + "/" +fileName;

ftp.deleteFile(filePath);

flag = true;

}

}

ftp.logout();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (ftp.isConnected()) {

try {

ftp.disconnect();

} catch (IOException ioe) {

}

}

}

return flag;

}

/**

* @Description 删除文件夹

* @Param [remotePath, fileName]

* @return void

**/

public static boolean deleteFolder( String remotePath){

boolean flag = false;

try {

remotePath = new String(remotePath.getBytes("GBK"),"iso-8859-1");

if (!initFtpClient()){

return flag;

};

// 转移到FTP服务器目录

ftp.changeWorkingDirectory(remotePath);

ftp.enterLocalPassiveMode();

FTPFile[] fs = ftp.listFiles();

if (fs.length==0){

ftp.removeDirectory(remotePath);

flag = true;

}

ftp.logout();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (ftp.isConnected()) {

try {

ftp.disconnect();

} catch (IOException ioe) {

}

}

}

return flag;

}

/**

* @Description 修改文件名称或者文件夹名

* @Param [oldAllName, newAllName]

* @return boolean

**/

public static boolean reNameFile( String oldAllName,String newAllName){

boolean flag = false;

try {

oldAllName = new String(oldAllName.getBytes("GBK"),"iso-8859-1");

newAllName = new String(newAllName.getBytes("GBK"),"iso-8859-1");

if (!initFtpClient()){

return flag;

};

ftp.enterLocalPassiveMode();

ftp.rename(oldAllName,newAllName);

flag = true;

ftp.logout();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (ftp.isConnected()) {

try {

ftp.disconnect();

} catch (IOException ioe) {

}

}

}

return flag;

}

}

以上就是Java+Springboot搭建一个在线网盘文件分享系统的详细内容,更多关于Java Springboot 的资料请关注我们其它相关文章!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Apache构建虚拟主机
下一篇:企业项目拓扑1(小型企业拓扑图)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~