spring mvc为我们封装了十分简单的上传附件的方法,以下通过一个例子学习。
1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <!DOCTYPE> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>附件管理</title> <!-- css文件 --> <link rel="stylesheet" href="./static/bootstrap/css/bootstrap.min.css" /> <link rel="stylesheet" href="./static/bootstrap/css/bootstrap-theme.min.css"> <link rel="stylesheet" href="./static/css/OtherCss/upload.css"> <!-- js文件 --> <script type="text/javascript" src="./static/js/jquery-1.11.0.js"></script> <script type="text/javascript" src="./static/bootstrap/js/bootstrap.min.js"></script> <script type="text/javascript" src="./static/js/OtherJs/upload.js"></script> <!-- ajax form --> <script type="text/javascript" src="./static/js/jquery.form.js"></script> <script type="text/javascript" src="./static/js/ajaxfileupload.js"></script> <script type="text/javascript" src="./static/js/jquery-migrate-1.2.1.min.js"></script> <script type="text/javascript"> var dialog = frameElement.dialog; $(function() { $("#submit1").click(function() { if ($("#categoryName").val() == "") { alert("请填写类别名称"); return false; } var ajax_option = { url : "categoryAttSave", type : "post", dataType : "html", success : function(data) { if (data == 1) { alert("成功"); } else { alert("失败") } dialogClose(); } } $("#thisForm").ajaxSubmit(ajax_option); }); }); //返回 function dialogClose() { parent.g.loadData(parent.g.parms); dialog.close();//关闭dialog } </script> </head> <body> <form id="thisForm" method="post" action="categoryAttSave" enctype="multipart/form-data"> <input type="hidden" name="categoryId" value="${category.categoryId}" /> <div class="container-fluid "> <div class="col-xs-12"> <div class="panel-body "> <div class="row"> <div class="col-xs-8 col-xs-offset-1 tipinfo" style="padding-bottom: 10px"> <div class="input-group"> <h3>${category.categoryName}</h3> </div> </div> </div> <div class="row"> <div class="col-xs-8 col-xs-offset-1 tipinfo" style="padding-bottom: 10px"> <div class="info_center" id="userface_x"> <div class="upload_face"> <div class="upload_btn"> <a type="button" class="upload_vl" id="upface_tt">选择您要上传的图片</a> <p id="img_rq">仅支持JPG、GIF、PNG、JPEG、BMP格式,文件小于4M</p> </div> <div class="upface_img"> <c:choose> <c:when test="${not empty category.categoryPic}"> <img id="preview" src="./${category.categoryPic}" /> </c:when> <c:otherwise><img id="preview" src="./static/img/nopic.png" /></c:otherwise> </c:choose> </div> <div class="changeimg" style="display: none"> <input id="fileimg" type="file" name="upload" /> </div> </div> </div> </div> </div> <div class="row"> <div class="col-xs-5 col-xs-offset-5"> <button type="button" class="btn btn-default " onClick="dialogClose();">关闭</button> <button type="button" class="btn btn-primary " id="submit1"> 提交</button> </div> </div> </div> </div> </div> </form> </body> </html>
主要要注意的是form的地方必须加 enctype="multipart/form-data"这句话,还有就是<input id="fileimg" type="file" name="upload" />这句话。本实例用了一个js的上传插件。只是优化了上传的体验,不涉及到原理,所以此处不介绍相关内容。主要还是介绍如何实现上传。
2.后台代码
controller
@ResponseBody @RequestMapping("categoryAttSave") public String categoryAttSave(HttpServletRequest req, MultipartFile upload, int categoryId) { Integer result = categoryService.categoryAttSave(req, upload, categoryId, uploadFile); return result.toString(); }
Service
/** * 附件上传并修改数据库 * * @param req * @param upload * @param categoryId * @param uploadFile * @return */ public int categoryAttSave(HttpServletRequest req, MultipartFile upload, int categoryId, String uploadFile) { int result = 0; String originalFileName = upload.getOriginalFilename(); String suffix = IOUtil.getFileSuffix(originalFileName); String fileName = RandomUtil.getTimeStampPlusRand() + "." + suffix; String realPath = req.getServletContext().getRealPath(uploadFile); try { upload.transferTo(new File(realPath + "/" + fileName)); // 数据库操作 TCategory category = baseDao.getT( "TCategoryMapper.selectByPrimaryKey", categoryId); String oldCategoryPic = category.getCategoryPic(); category.setCategoryPic(uploadFile + "/" + fileName); baseDao.updateT("TCategoryMapper.updateCategoryPic", category); // 删除原来的图片 IOUtil.deleteFile(req, oldCategoryPic); result = 1; } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return result; }
其实主要是注意到传递过来的MultipartFile 名称,要与jsp里面的file名对应。还有就是我们需要用到request来获取附件最终存储的位置,所以传递了一个HttpServletRequest。上传就是这句话upload.transferTo(new File(realPath + "/" + fileName));很简单吧,如果我们自己写的话,就要通过输入流写入到file里了。而spring mvc只要一句简单的代码就实现了。
PS:上述代码还是有弊端的,当我们没有选定需要上传的图片而点击了上传的时候,它会报如下错误。
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
大概意思就是,你这个请求并不是关于文件上传的请求。这是spring 替你检查了并直接报运行错误。
我们可以通过修改controller代码,替代spring 的检查,就可以规避这个错误了。
@ResponseBody @RequestMapping("categoryAttSave") public String categoryAttSave(HttpServletRequest req, int categoryId) { MultipartFile upload = null; if (req instanceof MultipartHttpServletRequest) { upload = ((MultipartHttpServletRequest) req).getFile("upload"); } Integer result = categoryService.categoryAttSave(req, upload, categoryId, uploadFile); return result.toString(); }
上述代码我们自己检查是不是关于文件上传的请求,就不会报错了。
时间: 2024-11-13 21:18:51