在一个应用系统里,会有上传本地文件到系统服务器里或从系统服务器查看、下载有关文件到本地的需要。这里只对自己了解到的做一个总结

文件上传

这里是把本地文件上传到服务器文件目录,而不是放到项目目录里。

前端用的bootstrap和Jquery,上传文件界面显示在是模态框里

//文件上传
<input id="uploadFile" type="file" name="file" style="margin-left: 90px; margin-top: 10px">
<!-- 模态框 --><div class="modal fade" id="newImg"><div class="modal-dialog"><div class="modal-content"><div class="modal-header">上传新的流程图</div><!-- <form class="form-horizontal"> --><div class="modal-body"><div class="form-group"><label for="inputEmail" class="col-sm-2 control-label">添加描述</label><div class="col-sm-10"><input id="describle" type="text"class="form-control list-inline" /></div></div><div class="form-group"><label class="control-label" style="margin-left: 30px">待上传的文件</label><div style="margin-left: 20px"><label class="control-label">输入记录id</label> <input type="text" id="relId_ajax" name="relId_ajax"><input id="uploadFile" type="file" name="file" style="margin-left: 90px; margin-top: 10px"></div></div><div class="modal-footer"><button id="back_btn" class="btn btn-danger" data-dismiss="modal">取消</button><button class="btn btn-success" onclick="submit_btn()" data-dismiss="modal">上传</button></div></div><!-- </form> --></div></div></div>

点击上传之后。调用JS方法使用ajax方法进行上传。上传成功之后,接收到后端返回的信息,并再次调用ajax请求对这些信息进行处理。这些信息后面会提到

//上传新的流程图(单文件上传,ajax方式)function submit_btn(){var relId = $("#relId_ajax").val();var fileDescribe = $("#describle").val();var file = $("#uploadFile")[0].files[0];var formData = new FormData();formData.append("file", file);formData.append("relId", relId);formData.append("fileDescribe", fileDescribe);$.ajax({dataType : "JSON",contentType : "application/json;charset=UTF-8",type : "POST",data : formData,url : "/hzsh/eomc-front/file/multiUpload",processData : false, // 使数据不做处理contentType : false, // 不要设置Content-Type请求头success : function(result) {console.log(result)console.log(result.msg)var JsonData = JSON.parse(result.data) //将后端传回的json数组字符串转换为json对象 //[{"fileName":"compareWithAll.PNG","id":"4b267540-1d97-4703-85b8-6522ee26843f"}]var imgId = JsonData[0].id;console.log(imgId);   $.ajax({type:"post",url:"/hzsh/eomc-zzhj/nyglms/updateImg",data:{"imgId":imgId},success:function(result){console.log("进行流程图更新")if(result.code){alert("上传成功")}else{alert("上传失败")}}})},error : function() {console.log("上传出错");}})}

效果如图:(这里我上传的是图片)

点击上传之后,会先将文件保存到数据库的附件表里,这张表就是对上传的文件元数据做统一的管理,包括文件类型、文件原名、文件大小、上传时间、上传用户等等。因为考虑到文件安全问题,上传的文件经过后端处理,存到服务器端文件目录里的文件名是一串随机字符串序列。

@RequestMapping("/file/multiUpload")public String multiUpload(HttpServletRequest request, HttpServletResponse response,HttpSession session) {try {String userName = (String) session.getAttribute("userName");String fileDescribe = request.getParameter("fileDescribe");String relId = request.getParameter("relId");String sort = request.getParameter("sort");log.info("文件描述" + fileDescribe);List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");boolean result = true;String retMsg = "";JSONArray retDataArray = new JSONArray();for (int i = 0; i < files.size(); i++) {MultipartFile file = files.get(i);if (file.isEmpty()) {retMsg += "第" + (i + 1) + "个文件为空";continue;}String fileName = file.getOriginalFilename();//定义附件表对象,用于将上传的文件元数据写入附件表CommAttachEntity commAttachEntity = new CommAttachEntity();commAttachEntity.setId(UUID.randomUUID().toString());commAttachEntity.setRealName(fileName);commAttachEntity.setEncName(commAttachEntity.getId());int extendIndex = fileName.indexOf(".");if(extendIndex < 0) {extendIndex = 0;}commAttachEntity.setExtendName(fileName.substring(extendIndex));if(CDataUtil.isPicture(fileName)) {commAttachEntity.setFileType("图片");}else if(CDataUtil.isDocument(fileName)) {commAttachEntity.setFileType("文档");}else {commAttachEntity.setFileType("未知");}commAttachEntity.setFlgDel("0");commAttachEntity.setFileSize(file.getSize() + "");commAttachEntity.setCreateUser(userName);commAttachEntity.setCreateDate(CDateTimeUtil.sysDateTime("yyyy-MM-dd HH:mm:ss"));commAttachEntity.setRemark(fileDescribe);commAttachEntity.setRelId(relId);if(sort == null || sort.trim().equals("")) {commAttachEntity.setSort(i + "");}else {commAttachEntity.setSort(sort);}//文件输出到本地File dest = new File(EnvConstant.attachPath + commAttachEntity.getEncName());try {file.transferTo(dest);log.info("第" + (i + 1) + "个文件上传成功(" + fileName + ")");} catch (Exception e) {log.error("第" + (i + 1) + "个文件上传失败(" + fileName + ")" + e.toString(), e);result = false;retMsg += fileName + ";";}//写入附件表commAttachMapper.insert(commAttachEntity);JSONObject retDataJson = new JSONObject();retDataJson.put("id", commAttachEntity.getId());retDataJson.put("fileName", fileName);retDataArray.add(retDataJson);}System.out.println(retDataArray+"KKKKKKKKKKKKKKKKKKK");if(result) {System.out.println("上传成功");return CIOUtil.buildRetMsg(true, "上传成功", retDataArray);}else {return CIOUtil.buildRetMsg(false, retMsg + " 文件上传失败", retDataArray);}}catch(Exception e) {return CIOUtil.buildRetMsg(false, "文件上传出错", e.getMessage());}}

上面这段代码就是对前端发送来的文件进行处理,生成一些文件元数据保存到数据库对应的附件表里。附件表主键就是在这里生成的随机序列:UUID.randomUUID()

该接口代码处理完文件信息后一方面将文件元数据传到数据库,

               //写入附件表commAttachMapper.insert(commAttachEntity);

一方面将文件保存到对应的文件目录里,其中 EnvConstant.attachPath 是之前在类中定义好的
文件保存路径

                //文件输出到本地File dest = new File(EnvConstant.attachPath + commAttachEntity.getEncName());file.transferTo(dest);

另一方面向前端返回一些信息

           if(result) {System.out.println("上传成功");return CIOUtil.buildRetMsg(true, "上传成功", retDataArray);}else {return CIOUtil.buildRetMsg(false, retMsg + " 文件上传失败", retDataArray);}

像前端返回的信息里包含了很重要的一项,就是随机生成的文件序列,也是文件上传后保存到服务器端目录里的文件加密名,这里的ajax请求是在点击“上传”后的JS方法里,是一个回调请求。

success : function(result) {console.log(result)console.log(result.msg)var JsonData = JSON.parse(result.data) //将后端传回的json数组字符串转换为json对象 //[{"fileName":"compareWithAll.PNG","id":"4b267540-1d97-4703-85b8-6522ee26843f"}]var imgId = JsonData[0].id;console.log(imgId);   $.ajax({type:"post",url:"/hzsh/eomc-zzhj/nyglms/updateImg",data:{"imgId":imgId},success:function(result){console.log("进行流程图更新")if(result.code){alert("上传成功")}else{alert("上传失败")}}})},

将随机生成的文件字符串序列保存到业务表里,作为外键和附件表进行关联。因为这里模拟的是特定业务的文件上传,业务里文件只有一个,所以上传文件属于更新操作。文件信息保存到业务表里始终只有一条记录。

@ResponseBody@RequestMapping("/nyglms/updateImg")public String updateNyglmsImg(HttpServletRequest request, HttpServletResponse response, HttpSession session) {// 获取CommAttachEntity对象流程图的Id信息String imgId = request.getParameter("imgId");// 将CommAttachEntity的流程图id信息写到nyglms表中String userName = (String) session.getAttribute("userName");DateFormat df = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");Calendar calendar = Calendar.getInstance();String create_img_time = df.format(calendar.getTime());EomcZzhjNyglmsEntity eomcZzhjNyglmsEntity = new EomcZzhjNyglmsEntity();eomcZzhjNyglmsEntity.setId(1);eomcZzhjNyglmsEntity.setCreateImgUser(userName);eomcZzhjNyglmsEntity.setCreateImgTime(create_img_time);eomcZzhjNyglmsEntity.setImgId(imgId);int result = eomcZzhjNyglmsService.updateNyglmsImg(eomcZzhjNyglmsEntity);if (result == 1) {return CIOUtil.buildRetMsg(true, "上传成功", null);} else {return CIOUtil.buildRetMsg(false,  "上传失败,请重新上传", null);}}

文件查看

此时,文件上传操作已经完成。当我们想在功能模块里查看已上传的文件时,只需发送请求到后端的业务表里获取唯一的文件随机字符串序列,并将字符串序列和文件保存路径进行拼接。这里使用IO流的方式将特定文件写出到前端页面。

@ResponseBody@RequestMapping("/nyglms/queryImg")public String queryNyglmsImage(HttpServletRequest request, HttpServletResponse response) {// 获取最新上传的流程图片信息(从业务表中)EomcZzhjNyglmsEntity eomcZzhjNyglmsEntity =  eomcZzhjNyglmsService.queryNyglmsImg();String imgId = eomcZzhjNyglmsEntity.getImgId();System.out.println("查询流程图************************:"+imgId);try {File file = new File(EnvConstant.attachPath +imgId);FileInputStream fis = new FileInputStream(file);OutputStream out = response.getOutputStream();long size = file.length();byte[] temp = new byte[(int) size];fis.read(temp, 0, (int) size);fis.close();byte[] data = temp;response.setContentType("image/PNG");// data = Base64.encodeBase64(data);out.write(data);out.flush();out.close();} catch (Exception e) {e.printStackTrace();}return CIOUtil.buildRetMsg(true, "显示流程图成功", null);}

前端代码:

      <div><img id="Img" alt="" src="/nyglms/queryImg" style="height: 400px; width: 600px;" /></div>

文件下载

可以从附件表获取文件随机字符串序列,也可以从业务表中获取。
这里从业务表中获取更容易一些(点击前端下载按钮,调用该后端接口)

/*** a根据附件名称,下载附件* @param fileName* @param request* @param response* @param model* @return*/@RequestMapping("/file/download")public String download( HttpServletRequest request, HttpServletResponse response ,Model model) {// 获取最新上传的流程图片信息(从业务表中)EomcZzhjNyglmsEntity eomcZzhjNyglmsEntity =    eomcZzhjNyglmsService.queryNyglmsImg();String imgId = eomcZzhjNyglmsEntity.getImgId();if(getImgId== null || getImgId.trim().equals("")) {log.info("imgId为空,无法下载附件");return CIOUtil.buildRetMsg(false, "imgId不能为空", null);}//设置为png格式的文件setHeader(request, response, imgId);byte[] buff = new byte[1024];//创建缓冲输入流BufferedInputStream bis = null;OutputStream outputStream = null;try {outputStream = response.getOutputStream();//这个路径为待下载文件的路径bis = new BufferedInputStream(new FileInputStream(new File(EnvConstant.attachPath + imgId)));int read = bis.read(buff);//通过while循环写入到指定了的文件夹中(这里指浏览器设置的目录文件夹)while (read != -1) {outputStream.write(buff, 0, buff.length);outputStream.flush();read = bis.read(buff);}} catch ( IOException e ) {e.printStackTrace();//出现异常返回给页面失败的信息model.addAttribute("result","下载失败");return "下载失败";} finally {if (bis != null) {try {bis.close();} catch (IOException e) {e.printStackTrace();}}if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}//成功后返回成功信息model.addAttribute("result","下载成功");return CIOUtil.buildRetMsg(true, "下载成功", null);}private boolean setHeader(HttpServletRequest request, HttpServletResponse response, String fileName) {try {response.setContentType("application/octet-stream");response.setHeader("content-type", "application/octet-stream");String browser = request.getHeader("User-Agent");if (-1 < browser.indexOf("MSIE 6.0") || -1 < browser.indexOf("MSIE 7.0")) {// IE6, IE7 浏览器response.addHeader("content-disposition", "attachment;filename="+ new String(fileName.getBytes(), "ISO8859-1"));} else if (-1 < browser.indexOf("MSIE 8.0")) {// IE8response.addHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8"));} else if (-1 < browser.indexOf("MSIE 9.0")) {// IE9response.addHeader("content-disposition", "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8"));} else if (-1 < browser.indexOf("Chrome")) {// 谷歌response.addHeader("content-disposition","attachment;filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));} else if (-1 < browser.indexOf("Safari")) {// 苹果response.addHeader("content-disposition", "attachment;filename="+ new String(fileName.getBytes(), "ISO8859-1"));} else {// 火狐或者其他的浏览器response.addHeader("content-disposition","attachment;filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));}return true;} catch (Exception e) {log.error(e.getMessage());return false;}}

java实现文件上传和文件查看、下载相关推荐

  1. java文件上传_Java文件上传细讲

    什么是文件上传? 文件上传就是把用户的信息保存起来. 为什么需要文件上传? 在用户注册的时候,可能需要用户提交照片.那么这张照片就应该要进行保存. 上传组件(工具) 为什么我们要使用上传工具? 为啥我 ...

  2. 渗透测试 ( 0 ) --- XSS、CSRF、文件上传、文件包含、反序列化漏洞

    漏洞数据库:https://www.exploit-db.com/google-hacking-database 1.渗透测试 实用 浏览器插件 chrome.edge 插件:搜索 cookie,安装 ...

  3. 文件上传时,文件太大会有几种被限制的情况

    文件上传时,文件太大会有几种被限制的情况 ​ 近期在维护一个项目时,商户有反馈,在新增用户时会直接卡住并报错,返回一个异常,应用层没有日志,最后排查出来是nginx限制了请求的最大值. ​ 那么整个链 ...

  4. 通达OA未授权任意文件上传及文件包含漏洞分析学习

    今年3月份通达OA爆出了文件上传和文件包含漏洞,网络上很多复现和分析的博客,今天我也来试着分析分析,据360灵腾安全实验室判断该漏洞等级为高,利用难度低,威胁程度高,所以可能比较适合代码审计的新手来练 ...

  5. 文件上传漏洞_通达OA前台任意文件上传漏洞+文件包含漏洞导致getshell

    点击蓝字|关注我们 通达OA前台任意文件上传漏洞 +文件包含漏洞导致getshell 一.漏洞介绍/Profile/ 通达OA介绍: 通达OA(Office Anywhere网络智能办公系统)是由北京 ...

  6. 文件上传、文件包含和目路遍历杂谈

    一.说明 文件上传.文件包含和目路遍历是<黑客防线>盛行的时代常谈的getshell手法,但到现在的安全书藉感觉就比较少提及或一笔带过.在谈的年代看不懂,在看得懂的年代又不谈了,概念感觉总 ...

  7. httpclient base64 文件上传_文件上传下载

    说道文件上传下载,这个业务需求并不是很复杂思想如下 1.将文件上传到 某台服务器上的指定的路径下也可以这样理解 文件上传就是将本地图片发送到别的地方,下载就是将别的地方的图片放在本地 2.将路径同文件 ...

  8. 踩坑 - click事件与blur事件冲突问题 input文件上传同名文件问题

    前言 上周写需求遇到了一点小坑涉及到一些小细节,今天赶上没啥事总结一下分享出来. click事件与blur事件冲突问题 click事件与blur事件 blur事件: 表单事件,元素失去焦点时候触发,不 ...

  9. 代码审计:YCCMS 代码执行 文件上传 任意文件删除

    代码审计:YCCMS 代码执行 文件上传 任意文件删除 YCCMS 审计准备 代码审计 代码执行漏洞 文件上传漏洞 任意文件删除漏洞 YCCMS YCCMS是一款PHP版轻量级CMS建站系统,程序页面 ...

  10. Dropzone单文件上传、多文件上传、文件夹上传,springmvc接收,上传至Minio的一系列问题

    0 前言 1.项目需要上传文件和大量的文件夹,页面只有一个input file标签会很丑,偶然间得知dropzone类库, 决定使用. 2. 项目后端采用springmvc接收,调用minio代码上传 ...

最新文章

  1. 力扣(LeetCode)刷题,简单题(第12期)
  2. 极客新闻——17、给决定长久做程序员的你三个建议
  3. 推荐10个能带来快感的实用windows软件,好评如潮!
  4. CF 529B Group Photo 2 (online mirror version)
  5. nginx linux脚本,shell脚本之nginx自动化脚本
  6. css 带轮廓的圆,CSS3 圆球轮廓动画
  7. leetcode 449. Serialize and Deserialize BST | 449. 序列化和反序列化二叉搜索树(BST后序遍历性质)
  8. 计算机文档用什么翻译,Word文档翻译在哪里(适于Word2010-Word2016)?
  9. Linux基础(1)--Vim编辑器的常用命令
  10. ubuntu18.04,Linux使用远程连接工具连接失败解决
  11. 学习C++项目——一个基于C++11简单易用的轻量级网络编程框架 1
  12. delphi控件属性大全-详解-简介
  13. 开放源代码是如何吞噬软件的
  14. 数据可视化大屏的应用与落地实践
  15. 软链接解决存储空间不足
  16. 魔兽世界正式服哪个服务器稳定,魔兽世界正式服什么职业厉害2021
  17. Node.js 和npm的安装(插件的安装)
  18. base64图片压缩到指定大小
  19. 解决windows下C32ASM反汇编无法打开的问题
  20. JAVASE温故知新

热门文章

  1. HDU 1281 棋盘游戏 【二分图最大匹配】
  2. centos7.2 使用rpm安装jdk8
  3. 扭曲效果 效率优化 GrapPass,CommandBuffer对比
  4. python 打印输出xml数据问题
  5. Linux学习之CentOS6下Mysql数据库的安装与配置
  6. JSon_零基础_005_将po(bean)对象转换为JSon格式的对象字符串,返回给界面
  7. Excel的python读写
  8. java怎么进行浮点数运算_【考试经验】Java中实现浮点数的精确运算
  9. ORA-01810格式代码出现两次 的解决方案
  10. Linux常用命令——关机重启命令