项目系统随着使用时长的增加,存储的文件数量也会逐渐增长,为了方便更好地对文件(附件)进行统一的管理,需要将文件保存路径存放到一张附件表中,获取有附件的主表数据是调用查询附加表获取到文件信息
另外,有的主表数据可能有不只一个附件,都放在数据字段中可能影响性能和后续维护成本
从配置表中读取到根目录信息,不同业务文件分别保存在不同文件;
文件主要信息有:文件路径、文件名、文件大小、文件类型、上传时间、调用文件的主表id等
界面选择文件进行上传——>由配置表、当前业务、当前日期时间等统一命名目录名、文件名等~~(可能后续会更改)~~
——>保存文件——>保存文件信息到s308表——>返回执行结果
个人感觉的话若依框架中已经编写好的文件上传功能已经很完善了,对于根目录的配置方式也很方便(几遍打成jar包yml文件也不会被编译,可以直接修改或覆盖),但是毕竟需求有出入,也只能进行修改,当然目前修改的情况只能说可用,还算不上完善,根据后续功能的开发也将逐渐完善本文所言的文件上传功能
@Autowired
private SysConfigMapper configMapper;@Autowired
private Sys308Service sys308Service;@PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
{// 判断头像文件不为空if (!file.isEmpty()){// 通过Security获取到登录用户信息LoginUser loginUser = getLoginUser();// 拼接根路径// 从配置表获取到根目录信息SysConfig sysConfig = configMapper.checkConfigKeyUnique("sys.file.basePath");// 进入到头像文件夹String basePath = ConfigValue() + "/avatar/";String absPath = sys308Service.fileUpload(basePath, file, UserId());if (absPath == null) {("上传图片异常,请联系管理员");}// 保存到数据库——>通过用户名查找到对应用户修改头像地址信息if (userService.Username(), absPath)){AjaxResult ajax = AjaxResult.success();// 返回值中增加头像地址(为空时默认使用若依头像)ajax.put("imgUrl", absPath);// 更新缓存用户头像User().setAvatar(absPath);// 更新tokentokenService.setLoginUser(loginUser);// 返回前端return ajax;}}("上传图片异常,请联系管理员");
}
@Autowired
private Sys308Mapper sys308Mapper;public String fileUpload(String basePath, MultipartFile file, String idMain) {try {// 头像转为输入流后续读出InputStream is = InputStream();// 创建filedirStr保存存储头像的文件夹层级——>当前还是包含文件的String filedirStr = basePath + extractFilename(file);// 创建absPath保存文件全路径String absPath = filedirStr;// 分隔全路径,用来截取出文件夹层级String[] split = filedirStr.split("/");int i = split[split.length - 1].indexOf(".");// 获取到文件名String fileName = split[split.length - 1].substring(0, i);// 通过获取文件名索引来截取到文件夹层级filedirStr = filedirStr.substring(0, filedirStr.indexOf(fileName));// 生成文件夹对象File filedir = new File(filedirStr);// 不存在就创建所有层级文件夹if (!ists()) {filedir.mkdirs();}// 文件对象File outFile = new File(absPath);// 文件对象转为输出流OutputStream os = new FileOutputStream(outFile);// 读出头像文件数据并写入到本地头像文件byte[] byteStr = new byte[1024];int len = 0;while ((len = is.read(byteStr)) > 0) {os.write(byteStr, 0, len);}// 关闭输入流is.close();// 输出文件数据os.flush();// 关闭输出流os.close();// 创建Sys308对象,设置信息Sys308 sys308 = new Sys308();// 地址sys308.setS308VarFilePath(absPath);// 文件名sys308.setS308VarFileName(fileName);// 大小sys308.setS308IntSize(Integer.Size() + ""));// 类型// 通过文件名长度截取文件类型sys308.setS308VarFileType(split[split.length - 1].substring(fileName.length()) + 1);// 原表sys308.setS308IdTable("sys_user");// 原表idsys308.setS308IdMain(idMain);// 保存到附件表s308sys308Mapper.saveS308(sys308);return absPath;} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();return null;}}
实现类方法:传入根目录、文件、
主表id返回保存后的全路径
思路:流转换
将传入文件转为输入流,将其中内容读取到将要生成的文件的输出流,
迭代方式读取完后flush出文件到对应位置
其实不管是什么功能的修改或编写,如果有过编写的经验实际开发难度也并不会太大,事实上这里的文件上传功能也并不涉及到什么比较绕或者复杂的业务逻辑(也可能跟目前对于整个项目的了解不全面有关);
虽然之前也有过文件上传相关的功能开发,但今天在进行文件上传改写的过程中也还是出现了不少的问题:
比如希望跟若依一样通过yml文件来配置根目录地址,这样也可能以根据不同的业务动态选择不同的根目录来保存文件,但不知道问题出在哪里我从yml文件读到的数据总是null,更没法进行调用什么得了……还是经验问题吧可能(手动捂脸);
又比如希望能够在若依原有的实现逻辑上进行修改,减少开发成本嘛,但是!一旦涉及到若依自带的实现流程,就很难保证保存到数据库中的地址是我所希望的那样——全路径了,若依自身是使用了别名(我的理解)的方式代替根路径,这样就导致结果并不是我所期望的
很明显出了不少问题,不过还好最终也都是解决了;
虽然但是,花费了不少时间最终还是将需求给实现了,目前只是调用了一个 extractFilename(file) 去生成年月日格式的文件夹层级和文件名,这也极大程度上减少了开发时的困扰——怎么处理将来可能存在的条件查询;
解决办法是一个个搜一个个试出来的,多多少少也算是增长了一些经验,也复习了一下文件流的使用
本文发布于:2024-02-02 18:10:03,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170686925145533.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |