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<String,Object> 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<Object> page = PageHelper.startPage(cur, 20); List<UserToShow> 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<FileFolder> folders = fileFolderService.getRootFoldersByFileStoreId(fileStore.getFileStoreId()); //迭代删除文件夹 for (FileFolder f:folders) { deleteFolderF(f); } List<MyFile> 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.subSize(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<FileFolder> folders = fileFolderService.getFileFolderByParentFolderId(folder.getFileFolderId()); //删除当前文件夹的所有的文件 List<MyFile> 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()); } }
文件仓库控制器:
/** * @ClassName: FileStoreController * @Description: 文件仓库控制器 **/ @Controller public class FileStoreController extends BaseController { private Logger logger = LogUtils.getInstance(FileStoreController.class); /** * @Description 上传临时文件 **/ @PostMapping("/uploadTempFile") public String uploadTempFile(@RequestParam("file") MultipartFile file,String url) { session.setAttribute("imgPath","https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2654852821,3851565636&fm=26&gp=0.jpg"); String name = file.getOriginalFilename().replaceAll(" ",""); if (!checkTarget(name)){ logger.error("临时文件上传失败!文件名不符合规范..."); session.setAttribute("msg", "上传失败!文件名不符合规范"); return "redirect:/temp-file"; } SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); String dateStr = format.format(new Date()); String path = "temp/"+dateStr +"/"+UUID.randomUUID(); try { if (FtpUtil.uploadFile("/"+path, name, file.getInputStream())){ //上传成功 logger.info("临时文件上传成功!"+name); String size = String.valueOf(file.getSize()); TempFile tempFile = TempFile.builder().fileName(name).filePath(path).size(size).uploadTime(new Date()).build(); if (tempFileService.insert(tempFile)) { try { String id = UUID.randomUUID().toString(); String p = request.getSession().getServletContext().getRealPath("/user_img/"); Long t = tempFile.getUploadTime().getTime(); url = url+"/file/share?t="+ UUID.randomUUID().toString().substring(0,10) +"&f="+tempFile.getFileId()+"&p="+size+"&flag=2"; File targetFile = new File(p, ""); if (!targetFile.exists()) { targetFile.mkdirs(); } File f = new File(p, id + ".jpg"); if (!f.exists()){ //文件不存在,开始生成二维码并保存文件 OutputStream os = new FileOutputStream(f); QRCodeUtil.encode(url, "/static/img/logo.png", os, true); os.close(); } //异步删除临时文件 tempFileService.deleteById(tempFile.getFileId()); session.setAttribute("imgPath","user_img/"+id+".jpg"); session.setAttribute("url",url); session.setAttribute("msg","上传成功,扫码/访问链接 即可下载!"); return "redirect:/temp-file"; } catch (Exception e) { e.printStackTrace(); } }else { logger.info("临时文件数据库写入失败!"+name); session.setAttribute("url","error"); session.setAttribute("msg", "服务器出错了,临时文件上传失败!"); } }else{ //上传失败 logger.info("临时文件上传失败!"+name); session.setAttribute("url","error"); session.setAttribute("msg", "服务器出错了,上传失败!"); } } catch (IOException e) { e.printStackTrace(); } return "redirect:/temp-file"; } /** * @Description 网盘的文件上传 * @Author xw * @Date 23:10 2020/2/10 * @Param [files] * @return java.util.Map<java.lang.String,java.lang.Object> **/ @PostMapping("/uploadFile") @ResponseBody public Map<String, Object> uploadFile(@RequestParam("file") MultipartFile files) { Map<String, Object> map = new HashMap<>(); if (fileStoreService.getFileStoreByUserId(loginUser.getUserId()).getPermission() != 0){ logger.error("用户没有上传文件的权限!上传失败..."); map.put("code", 499); return map; } FileStore store = fileStoreService.getFileStoreByUserId(loginUser.getUserId()); Integer folderId = Integer.valueOf(request.getHeader("id")); String name = files.getOriginalFilename().replaceAll(" ",""); //获取当前目录下的所有文件,用来判断是否已经存在 List<MyFile> myFiles = null; if (folderId == 0){ //当前目录为根目录 myFiles = myFileService.getRootFilesByFileStoreId(loginUser.getFileStoreId()); }else { //当前目录为其他目录 myFiles = myFileService.getFilesByParentFolderId(folderId); } for (int i = 0; i < myFiles.size(); i++) { if ((myFiles.get(i).getMyFileName()+myFiles.get(i).getPostfix()).equals(name)){ logger.error("当前文件已存在!上传失败..."); map.put("code", 501); return map; } } SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); String dateStr = format.format(new Date()); String path = loginUser.getUserId()+"/"+dateStr +"/"+folderId; if (!checkTarget(name)){ logger.error("上传失败!文件名不符合规范..."); map.put("code", 502); return map; } Integer sizeInt = Math.toIntExact(files.getSize() / 1024); //是否仓库放不下该文件 if(store.getCurrentSize()+sizeInt > store.getMaxSize()){ logger.error("上传失败!仓库已满。"); map.put("code", 503); return map; } //处理文件大小 String size = String.valueOf(files.getSize()/1024.0); int indexDot = size.lastIndexOf("."); size = size.substring(0,indexDot); int index = name.lastIndexOf("."); String tempName = name; String postfix = ""; int type = 4; if (index!=-1){ tempName = name.substring(index); name = name.substring(0,index); //获得文件类型 type = getType(tempName.toLowerCase()); postfix = tempName.toLowerCase(); } try { //提交到FTP服务器 boolean b = FtpUtil.uploadFile("/"+path, name + postfix, files.getInputStream()); if (b){ //上传成功 logger.info("文件上传成功!"+files.getOriginalFilename()); //向数据库文件表写入数据 myFileService.addFileByFileStoreId( MyFile.builder() .myFileName(name).fileStoreId(loginUser.getFileStoreId()).myFilePath(path) .downloadTime(0).uploadTime(new Date()).parentFolderId(folderId). size(Integer.valueOf(size)).type(type).postfix(postfix).build()); //更新仓库表的当前大小 fileStoreService.addSize(store.getFileStoreId(),Integer.valueOf(size)); try { Thread.sleep(5000); map.put("code", 200); } catch (InterruptedException e) { e.printStackTrace(); } }else{ logger.error("文件上传失败!"+files.getOriginalFilename()); map.put("code", 504); } } catch (IOException e) { e.printStackTrace(); } return map; } /** * @Description 网盘的文件下载 **/ @GetMapping("/downloadFile") public String downloadFile(@RequestParam Integer fId){ if (fileStoreService.getFileStoreByUserId(loginUser.getUserId()).getPermission() == 2){ logger.error("用户没有下载文件的权限!下载失败..."); return "redirect:/error401Page"; } //获取文件信息 MyFile myFile = myFileService.getFileByFileId(fId); String remotePath = myFile.getMyFilePath(); String fileName = myFile.getMyFileName()+myFile.getPostfix(); try { //去FTP上拉取 OutputStream os = new BufferedOutputStream(response.getOutputStream()); response.setCharacterEncoding("utf-8"); // 设置返回类型 response.setContentType("multipart/form-data"); // 文件名转码一下,不然会出现中文乱码 response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8")); boolean flag = FtpUtil.downloadFile("/" + remotePath, fileName, os); if (flag) { myFileService.updateFile( MyFile.builder().myFileId(myFile.getMyFileId()).downloadTime(myFile.getDownloadTime() + 1).build()); os.flush(); os.close(); logger.info("文件下载成功!" + myFile); } } catch (Exception e) { e.printStackTrace(); } return "success"; } /** * @Description 删除文件 **/ @GetMapping("/deleteFile") public String deleteFile(@RequestParam Integer fId,Integer folder){ //获得文件信息 MyFile myFile = myFileService.getFileByFileId(fId); String remotePath = myFile.getMyFilePath(); String fileName = myFile.getMyFileName()+myFile.getPostfix(); //从FTP文件服务器上删除文件 boolean b = FtpUtil.deleteFile("/"+remotePath, fileName); if (b){ //删除成功,返回空间 fileStoreService.subSize(myFile.getFileStoreId(),Integer.valueOf(myFile.getSize())); //删除文件表对应的数据 myFileService.deleteByFileId(fId); } logger.info("删除文件成功!"+myFile); return "redirect:/files?fId="+folder; } /** * @Description 删除文件夹并清空文件 **/ @GetMapping("/deleteFolder") public String deleteFolder(@RequestParam Integer fId){ FileFolder folder = fileFolderService.getFileFolderByFileFolderId(fId); //强制删除 deleteFolderF(folder); return folder.getParentFolderId() == 0?"redirect:/files":"redirect:/files?fId="+folder.getParentFolderId(); } /** * @Description 迭代删除文件夹里面的所有文件和子文件夹 **/ public void deleteFolderF(FileFolder folder){ //获得当前文件夹下的所有子文件夹 List<FileFolder> folders = fileFolderService.getFileFolderByParentFolderId(folder.getFileFolderId()); //删除当前文件夹的所有的文件 List<MyFile> 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 添加文件夹 **/ @PostMapping("/addFolder") public String addFolder(FileFolder folder,Map<String, Object> map) { //设置文件夹信息 folder.setFileStoreId(loginUser.getFileStoreId()); folder.setTime(new Date()); //获得当前目录下的所有文件夹,检查当前文件夹是否已经存在 List<FileFolder> fileFolders = null; if (folder.getParentFolderId() == 0){ //向用户根目录添加文件夹 fileFolders = fileFolderService.getRootFoldersByFileStoreId(loginUser.getFileStoreId()); }else{ //向用户的其他目录添加文件夹 fileFolders = fileFolderService.getFileFolderByParentFolderId(folder.getParentFolderId()); } for (int i = 0; i < fileFolders.size(); i++) { FileFolder fileFolder = fileFolders.get(i); if (fileFolder.getFileFolderName().equals(folder.getFileFolderName())){ logger.info("添加文件夹失败!文件夹已存在..."); return "redirect:/files?error=1&fId="+folder.getParentFolderId(); } } //向数据库写入数据 Integer integer = fileFolderService.addFileFolder(folder); logger.info("添加文件夹成功!"+folder); return "redirect:/files?fId="+folder.getParentFolderId(); } /** * @Description 重命名文件夹 **/ @PostMapping("/updateFolder") public String updateFolder(FileFolder folder,Map<String, Object> map) { //获得文件夹的数据库信息 FileFolder fileFolder = fileFolderService.getFileFolderByFileFolderId(folder.getFileFolderId()); fileFolder.setFileFolderName(folder.getFileFolderName()); //获得当前目录下的所有文件夹,用于检查文件夹是否已经存在 List<FileFolder> fileFolders = fileFolderService.getFileFolderByParentFolderId(fileFolder.getParentFolderId()); for (int i = 0; i < fileFolders.size(); i++) { FileFolder folder1 = fileFolders.get(i); if (folder1.getFileFolderName().equals(folder.getFileFolderName()) && folder1.getFileFolderId() != folder.getFileFolderId()){ logger.info("重命名文件夹失败!文件夹已存在..."); return "redirect:/files?error=2&fId="+fileFolder.getParentFolderId(); } } //向数据库写入数据 Integer integer = fileFolderService.updateFileFolderById(fileFolder); logger.info("重命名文件夹成功!"+folder); return "redirect:/files?fId="+fileFolder.getParentFolderId(); } /** * @Description 重命名文件 **/ @PostMapping("/updateFileName") public String updateFileName(MyFile file,Map<String, Object> map) { MyFile myFile = myFileService.getFileByFileId(file.getMyFileId()); if (myFile != null){ String oldName = myFile.getMyFileName(); String newName = file.getMyFileName(); if (!oldName.equals(newName)){ boolean b = FtpUtil.reNameFile(myFile.getMyFilePath() + "/" + oldName+myFile.getPostfix(), myFile.getMyFilePath() + "/" + newName+myFile.getPostfix()); if (b){ Integer integer = myFileService.updateFile( MyFile.builder().myFileId(myFile.getMyFileId()).myFileName(newName).build()); if (integer == 1){ logger.info("修改文件名成功!原文件名:"+oldName+" 新文件名:"+newName); }else{ logger.error("修改文件名失败!原文件名:"+oldName+" 新文件名:"+newName); } } } } return "redirect:/files?fId="+myFile.getParentFolderId(); } /** * @Description 获得二维码 **/ @GetMapping("getQrCode") @ResponseBody public Map<String,Object> getQrCode(@RequestParam Integer id,@RequestParam String url){ Map<String,Object> map = new HashMap<>(); map.put("imgPath","https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=2654852821,3851565636&fm=26&gp=0.jpg"); if (id != null){ MyFile file = myFileService.getFileByFileId(id); if (file != null){ try { String path = request.getSession().getServletContext().getRealPath("/user_img/"); url = url+"/file/share?t="+ UUID.randomUUID().toString().substring(0,10) +"&f="+file.getMyFileId()+"&p="+file.getUploadTime().getTime()+""+file.getSize()+"&flag=1"; File targetFile = new File(path, ""); if (!targetFile.exists()) { targetFile.mkdirs(); } File f = new File(path, id + ".jpg"); if (!f.exists()){ //文件不存在,开始生成二维码并保存文件 OutputStream os = new FileOutputStream(f); QRCodeUtil.encode(url, "/static/img/logo.png", os, true); os.close(); } map.put("imgPath","user_img/"+id+".jpg"); map.put("url",url); } catch (Exception e) { e.printStackTrace(); } } } return map; } /** * @Description 分享文件 **/ @GetMapping("/file/share") public String shareFile(Integer f,String p,String t,Integer flag){ String fileNameTemp = ""; String remotePath = ""; String fileName = ""; Integer times = 0; if (flag == null || f == null || p == null || t == null){ logger.info("下载分享文件失败,参数错误"); return "redirect:/error400Page"; } if(flag == 1){ //获取文件信息 MyFile myFile = myFileService.getFileByFileId(f); if (myFile == null){ return "redirect:/error404Page"; } String pwd = myFile.getUploadTime().getTime()+""+myFile.getSize(); if (!pwd.equals(p)){ return "redirect:/error400Page"; } remotePath = myFile.getMyFilePath(); fileName = myFile.getMyFileName()+myFile.getPostfix(); }else if(flag == 2){ TempFile tempFile = tempFileService.queryById(f); if (tempFile == null){ return "redirect:/error404Page"; } Long test = tempFile.getUploadTime().getTime(); String pwd = tempFile.getSize(); if (!pwd.equals(p)){ return "redirect:/error400Page"; } remotePath = tempFile.getFilePath(); fileName = tempFile.getFileName(); }else { return "redirect:/error400Page"; } fileNameTemp = fileName; try { //解决下载文件时 中文文件名乱码问题 boolean isMSIE = isMSBrowser(request); if (isMSIE) { //IE浏览器的乱码问题解决 fileNameTemp = URLEncoder.encode(fileNameTemp, "UTF-8"); } else { //万能乱码问题解决 fileNameTemp = new String(fileNameTemp.getBytes("UTF-8"), "ISO-8859-1"); } //去FTP上拉取 OutputStream os = new BufferedOutputStream(response.getOutputStream()); response.setCharacterEncoding("utf-8"); // 设置返回类型 response.setContentType("multipart/form-data"); // 文件名转码一下,不然会出现中文乱码 response.setHeader("Content-Disposition", "attachment;fileName=" + fileNameTemp); if (FtpUtil.downloadFile("/" + remotePath, fileName, os)) { myFileService.updateFile( MyFile.builder().myFileId(f).downloadTime(times + 1).build()); os.flush(); os.close(); logger.info("文件下载成功!"); } } catch (Exception e) { e.printStackTrace(); } return "success"; } /** * @Description 根据文件的后缀名获得对应的类型 * @return int 1:文本类型 2:图像类型 3:视频类型 4:音乐类型 5:其他类型 **/ public int getType(String type){ if (".chm".equals(type)||".txt".equals(type)||".xmind".equals(type)||".xlsx".equals(type)||".md".equals(type) ||".doc".equals(type)||".docx".equals(type)||".pptx".equals(type) ||".wps".equals(type)||".word".equals(type)||".html".equals(type)||".pdf".equals(type)){ return 1; }else if (".bmp".equals(type)||".gif".equals(type)||".jpg".equals(type)||".ico".equals(type)||".vsd".equals(type) ||".pic".equals(type)||".png".equals(type)||".jepg".equals(type)||".jpeg".equals(type)||".webp".equals(type) ||".svg".equals(type)){ return 2; } else if (".avi".equals(type)||".mov".equals(type)||".qt".equals(type) ||".asf".equals(type)||".rm".equals(type)||".navi".equals(type)||".wav".equals(type) ||".mp4".equals(type)||".mkv".equals(type)||".webm".equals(type)){ return 3; } else if (".mp3".equals(type)||".wma".equals(type)){ return 4; } else { return 5; } } /** * @Description 正则验证文件名是否合法 [汉字,字符,数字,下划线,英文句号,横线] **/ public boolean checkTarget(String target) { final String format = "[^\\u4E00-\\u9FA5\\uF900-\\uFA2D\\w-_.]"; Pattern pattern = Pattern.compile(format); Matcher matcher = pattern.matcher(target); return !matcher.find(); } /** * @Description 判断当前浏览器是否为ie **/ public static boolean isMSBrowser(HttpServletRequest request) { String[] IEBrowserSignals = {"MSIE", "Trident", "Edge"}; String userAgent = request.getHeader("User-Agent"); for (String signal : IEBrowserSignals) { if (userAgent.contains(signal)){ return true; } } return false; } }
登录控制器:
/** * @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<String, Object> 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<String, Object> 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 的资料请关注我们其它相关文章!
赞 (0)