写在前面
本篇我们来介绍后台文件上传和后台富文本图片上传的开发,这里面涉及到的内容比较多,而且还是具有一定的难度,建议大家没事多看几遍,多敲代码。
后台文件上传
首先打开ProductManageController. java 文件,在里面新增以下代码:
/*** * * 后台管理员--上传文件到服务器(spring mvc) * */ @RequestMapping("upload. do ") @ResponseBody public ServerResponse upload(HttpSession session, @RequestParam(value = "upload_file",required = false) MultipartFile file , HttpServletRequest request){ //判断一下登录情况 User user = (User)session.getAttribute(Const.CURRENT_USER); if(user == null){ return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(),"用户未登录,请登录管理员"); } //判断一下是不是管理员身份 if(iUser service .checkAdminRole(user).isSuccess()){ //如果是管理员就进行后台上传文件的逻辑 String path = request.getSession().getServletContext().getRealPath("upload"); String targetFileName = iFileService.upload(file,path); String url = PropertiesUtil.getProperty("ftp.server.http.prefix")+targetFileName; //进行url的拼接以供前端使用 Map fileMap = Maps.newHashMap(); fileMap.put("uri",targetFileName); fileMap.put("url",url); return ServerResponse.createBySuccess(fileMap); }else{ return ServerResponse.createByErrorMessage("无权限操作,需要管理员权限"); } }
关于这段代码,我需要说明几点:
1、参数问题,这里不仅仅需要登录,而且还需要一个文件参数(非必须)和请求参数(必须因为文件上传路径需要从它里面进行获取)。
2、String targetFileName = iFileService.upload( File ,path);看到这里就说明你需要完成几个事情:首先新建iFileService这个接口,然后再创建一个该接口的实现类。
打开service这个包,在里面新建一个IFileService.java的接口,里面的代码如下:(按照我们之前的说明应该是最后进行的,这里考虑到介绍的顺序问题,就这里写吧)
package top.store.service;
import org.springframework.web.multipart.MultipartFile;
public interface IFile Service {
String upload(MultipartFile file, String path); //上传文件到ftp服务器上面
}
然后打开impl文件,在里面新建FileServiceImpl.java文件来实现我们IFileService这个接口,里面的代码如下:
package top.store.service.impl; import com.google.common.collect.Lists; import org. slf4j .Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import top.store.service.IFileService; import top.store.util.FTPUtil; import java. io .File; import java.io.IOException; import java.util.UUID; @Service("iFileService") public class FileServiceImpl implements IFileService { //添加一个用于目录列表为空的日志 private Logger logger = LoggerFactory.getLogger(FileServiceImpl.class); public String upload(MultipartFile file,String path){ //上传文件的名称 String fileName =file.getOriginalFilename(); //扩展名test.jpg,我们要获取jpg String fileExtensionName =fileName.substring(fileName.lastIndexOf(".")+1); //文件上传的名称 String uploadFileName = UUID.randomUUID().toString()+"."+fileExtensionName; logger.info("开始上传文件,上传文件的文件名:{},上传的路径:{},新文件名:{}",fileName,path,uploadFileName); File fileDir = new File(path); if(!fileDir.exists()){ //文件可以设置权限 fileDir.setWritable(true); //创建多个文件 fileDir.mkdirs(); } File targetFile = new File(path,uploadFileName); try { file.transferTo(targetFile); //文件已经上传成功了 FTPUtil.uploadFile(Lists.newArrayList(targetFile)); //已经上传到ftp服务器上 targetFile.delete(); //删除upload下面的文件 } catch (IOException e) { logger.error("上传文件异常",e); return null; } //1:test.jpg 这里就是说明我们前面使用UUID的必要性,否则就很容易造成重复 //2:test.jpg return targetFile.getName(); } }
上面这个实现文件上传的类不仅仅用在文件上传,而且后台富文本图片上传也是需要依靠它的。同样这里的FTPUtil.uploadFile(Lists.newArrayList(targetFile));也是需要你注意的,打开util包,在里面新建一个FTPUtil.java的工具类,我们在里面新增以下代码:
package top.store.util; import org.apache.commons.net.ftp.FTPClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.List; public class FTPUtil { //添加一个用于目录列表为空的日志 private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class); //使用我们之前定义的PropertiesUtil这个工具类来获取服务器属性 private static String ftpIp =PropertiesUtil.getProperty("ftp.server.ip"); private static String ftpUser =PropertiesUtil.getProperty("ftp.user"); private static String ftpPass =PropertiesUtil.getProperty("ftp.pass"); private String ip; private int port; private String user; private String pwd; private FTPClient ftpClient; public FTPUtil(String ip,int port,String user,String pwd ){ this.ip =ip; this.port =port; this.user=user; this.pwd =pwd; } //上传服务器 public static boolean uploadFile(List<File> fileList) throws IOException { FTPUtil ftpUtil = new FTPUtil(ftpIp,21,ftpUser,ftpPass); logger.info("开始连接 ftp 服务器"); boolean result = ftpUtil.uploadFile("img",fileList); logger.info("开始连接 ftp 服务器,结束上传,上传结果:{}"); return result; } private boolean uploadFile(String remotePath,List<File> fileList) throws IOException { boolean uploaded = true; FileInputStream fis = null; //连接 FTP 服务器 if(connectServer(this.ip,this.port,this.user,this.pwd)){ try { ftpClient.changeWorkingDirectory(remotePath); ftpClient.setBufferSize(1024); ftpClient.setControlEncoding("UTF-8"); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); //二进制类型,可以防止乱码 ftpClient.enterLocalPassiveMode(); //打开本地的被动模式 for(File fileItem : fileList){ fis = new FileInputStream(fileItem); ftpClient.storeFile(fileItem.getName(),fis); } } catch (IOException e) { logger.error("上传文件异常",e); uploaded = false; e.printStackTrace(); } finally { fis.close(); //释放连接 ftpClient.disconnect(); } } return uploaded; } //连接Ftp服务器 private boolean connectServer(String ip,int port,String user,String pwd){ boolean isSuccess = false; ftpClient = new FTPClient(); try { ftpClient.connect(ip); isSuccess = ftpClient.login(user,pwd); } catch (IOException e) { logger.error("连接 FTP 服务器异常",e); } return isSuccess; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public FTPClient getFtpClient() { return ftpClient; } public void setFtpClient(FTPClient ftpClient) { this.ftpClient = ftpClient; } }
这个文件的作用就是获取服务器的属性以及负责连接服务器和上传文件到服务器。
3、我们继续回到ProductManageController.java文件,在最上面进行IFileService 的注入:
@Autowired private IFileService iFileService;
关于文件上传的一些参数的设置,大家可以打开dispatcher-servlet.xml文件:
<!-- 文件上传 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="10485760"/> <!-- 10m --> <property name="maxInMemorySize" value="4096" /> <property name="defaultEncoding" value="UTF-8"></property> </bean>
上面说了允许文件上传的最大尺寸,默认编码方式以及阈值,低于此值,只保留在内存里,超过此阈值,生成硬盘上的临时文件。
为了后面进行测试,你可以打开webapp下面的index.jsp文件,在里面添加如下代码:
<%--springmvc 上传文件--%> <form name="form1" action="/manage/product/upload.do" method="post" enctype="multipart/form-data"> <input type="file" name="upload_file" /> <input type="submit" value="springmvc 上传文件" /> </form>
这样后台文件上传的实现就介绍完了,接下来就进行后台富文本图片上传的开发。
后台富文本图片上传的开发
前面说过,我们这两个功能的接口是一样的,因此那部分代码就可以不用再写了,直接就可以进行使用。但是我们这里使用了simditor,你可以点击这里进行了解:simditor,我们这里主要使用json,因此你可以拉到底部看到这段代码:
{
"success": true/false,
" msg ": "error message", # optional
"file_path": "[real file path]"
}
所以我们后面图片文件上传之后,返回的格式就是这个样子,这里告诉大家希望大家对此有个提前的认识。我们打开ProductManageController.java文件,在里面新增以下代码:
/*** * * 后台管理员--富文本图片上传文件到服务器 * */ @RequestMapping("richtext_img_upload.do") @ResponseBody public Map richtextImgUpload(HttpSession session, @RequestParam(value = "upload_file",required = false) MultipartFile file, HttpServletRequest request, HttpServletResponse response){ Map resultMap =Maps.newHashMap(); //判断一下登录情况 User user = (User)session.getAttribute(Const.CURRENT_USER); if(user == null){ resultMap.put("success",false); resultMap.put("msg","请登录管理员"); return resultMap; } //富文本中对于返回值有自己的要求,我们使用simditor,因此按照simditor的要求进行返回,前面我们也说过了。 //{ // "success": true/false, // "msg": "error message", # optional // "file_path": "[real file path]" //} //判断一下是不是管理员身份 if(iUserService.checkAdminRole(user).isSuccess()){ //如果是管理员就进行后台上传富文本文件的逻辑 String path = request.getSession().getServletContext().getRealPath("upload"); String targetFileName = iFileService.upload(file,path); //判断文件名是否为空,如果为空的话 if(StringUtils.isBlank(targetFileName)){ resultMap.put("success",false); resultMap.put("msg","上传失败"); return resultMap; } String url = PropertiesUtil.getProperty("ftp.server.http.prefix")+targetFileName; //进行url的拼接以供前端使用 resultMap.put("success",true); resultMap.put("msg","上传成功"); resultMap.put("file_path",url); response.addHeader("Access-Control-Allow-Headers","X-File-Name"); return resultMap; }else{ resultMap.put("success",false); resultMap.put("msg","无权限操作,需要管理员权限"); return resultMap; } }
这个段代码就是核心代码,所以我需要说明几点:
1、为什么我们最后的返回是一个map,因为simditor文档要求最后返回的是一个json而且是以一种键值对的格式进行返回,所以你要莫使用map,当然使用object也是可以的,你可以参考这篇文章:list、map、对象对应json的格式。
2、记住我们本项目都是使用了guava提供的map,set,list等,因为它们进行了更深层次的封装。
3、这里的逻辑就是先判断文件存在与否,不存在就直接返回失败,存在就进行url的拼接以及保存到header里面并及时显示成功之后的信息。这个逻辑还行,能理解。
同样为了后面进行测试,你可以打开webapp下面的index.jsp文件,在里面添加如下代码:
<%--富文本图片上传文件--%> <form name="form2" action="/manage/product/richtext_img_upload.do" method="post" enctype="multipart/form-data"> <input type="file" name="upload_file" /> <input type="submit" value="富文本图片上传文件" /> </form>
这样我们本篇关于后台文件上传和后台富文本图片上传开发的介绍就到此为止了,感谢你的赏阅!