ServletFileUpload 文件上传并ftp上传到ftp服务器
public List<AttachmentVo> uploadAttachment(HttpServletRequest request, RequestVO requestVO){ // 设置缓存区与缓存大小 DiskFileItemFactory factory = new DiskFileItemFactory(); String reposityString = clientsProperties.getProperty("fileupload.repository"); factory.setRepository(new File(reposityString)); int sizeThreshold = Integer.parseInt(clientsProperties.getProperty("fileupload.sizeThreshold")); factory.setSizeThreshold(sizeThreshold); // //上传的大小控制 ServletFileUpload fileUpload = new ServletFileUpload(factory); int sizeMax = Integer.parseInt(clientsProperties.getProperty("fileupload.sizemax")); fileUpload.setSizeMax(sizeMax);
//设置编码格式 fileUpload.setHeaderEncoding("UTF-8"); List<AttachmentVo> attachments = new ArrayList<AttachmentVo>(); try { List<FileItem> fileItemList = fileUpload.parseRequest(request); // 取出ftp帐号配置并连接上ftp String server = clientsProperties.getProperty("ftp.hostname"); String username = clientsProperties.getProperty("ftp.username"); String password = clientsProperties.getProperty("ftp.password"); FtpClientUtil ftpClient = new FtpClientUtil(); boolean res = ftpClient.connectServer(server, username, password); if (!res) { log.error("ftp server login error!!!"); return attachments; } for (FileItem fileItem : fileItemList) { try { if (!fileItem.isFormField()) { //获取文件信息 String fileName = fileItem.getName(); String fieldName = fileItem.getFieldName(); String fileExt = fileName.substring(fileName.lastIndexOf(".")+1); //文件格式过滤 String supportFileTypes = clientsProperties.getProperty("fileupload.fileType"); if(!supportFileTypes.contains(fileExt)){ log.warn("the file type is forbinden! ->"+fileExt); continue; } //生成路径并ftp上传 String uploadFileName = UUID.randomUUID() + "." + fileExt; String uploadFilePath = makeFilePath() + uploadFileName; boolean rs = ftpClient.uploadFile(uploadFilePath, fileItem.getInputStream()); //上传成功后 if (rs) { AttachmentVo attachmentVo = new AttachmentVo(); attachmentVo.setFileName(fieldName); attachmentVo.setFilePath(uploadFilePath); attachments.add(attachmentVo); } } else { //普通的表单字段直接填值 requestVO.getParameters().put(fileItem.getFieldName(), fileItem.getString()); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } ftpClient.disconnectServer(); } catch (FileUploadException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } return attachments; } /** * 生成路径 * @return */ private String makeFilePath(){ SimpleDateFormat dateFormater = new SimpleDateFormat("yyyy/MM/dd/"); String dateStr = dateFormater.format(new Date()); return dateStr; }
import java.io.IOException; import java.io.InputStream; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <pre> * ftp上传工具类 * </pre> * * @author qinyujun qinyujun@powerjun.cn * @version 1.00.00 * * <pre> * 修改记录 * 修改后版本: 修改人: 修改日期: 修改内容: * </pre> */ public class FtpClientUtil { private static Logger logger = LoggerFactory.getLogger(FtpClientUtil.class); private FTPClient ftpClient; public boolean connectServer(String Servcer, String username, String password){ boolean res = false; try { ftpClient = new FTPClient(); ftpClient.connect(Servcer); boolean login = ftpClient.login(username, password); if(!login){ logger.error("FtpClientUtils -> connectServer ftp login failed! ftpConfig[{},{},{}]", new Object[]{ Servcer, username, password}); return res; } logger.info("FtpClientUtils conneted {} server ." , username); int replyCode = ftpClient.getReplyCode(); if(!FTPReply.isPositiveCompletion(replyCode)){ ftpClient.disconnect(); logger.error("FTP server refused connection."); return res; } //设置缓冲大小 ftpClient.setBufferSize(2048); ftpClient.setControlEncoding("UTF-8"); ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE); res = true; } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); if(ftpClient != null && ftpClient.isConnected()){ try { ftpClient.disconnect(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } logger.error("###FtpClientUtils -> connectServer failed!!!!"); } return res; } /** * 断开 */ public void disconnectServer(){ if(ftpClient != null && ftpClient.isConnected()){ try { ftpClient.disconnect(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } logger.debug("disconnectServer success!"); } public boolean uploadFile(String fileName, InputStream is){ boolean res = false; if(ftpClient != null && ftpClient.isConnected()){ try { //如果名称含有文件夹刚先创建文件夹 if(fileName.indexOf("/") > -1){ String parentPath = fileName.substring(0, fileName.lastIndexOf("/")); String[] filePaths = parentPath.split("/"); String dirPath = ""; //出现多层目录时需要一层层建目录 for(String dirName : filePaths){ if(!dirName.equals("") ){ dirPath = dirPath + "/" + dirName; ftpClient.makeDirectory(dirPath); } } logger.debug("FtpClientUtils->uploadFile [{}] makedir success!->" ); } res = ftpClient.storeFile(fileName, is); is.close(); if(res){ logger.info("uploadFile[{}] success! ", fileName); }else{ logger.error("uploafile[{}] failed! ", fileName); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); logger.error("FtpClientUtils->uploadFile failed!!!"); } } return res; } }
这样的例子在网上很多见,代码虽然简单,但是在使用过程一些参数设置不合理就会出现其他莫明其妙的错,比如 fileUpload.parseRequest(request) 这句代码会出错,而且这是当上传的文件,大于10K时就会出现报错,小于10K又是正常的,经过上面的百度才知道,如果小于10K 的,这个ServletFileUpload会用ByteOutputStream使用的是内存,如果大于10K 使用的是FileOutputStream,就要用到的文件系统,找了半天才发现是在 factory.setRepository(new File(reposityString)); 这个设置缓存位置的,不能随便写个路径,是一定要存在才行,要不然它生成不了缓存文件,所以会报下面的错,设置好了就没有问题了,其中其他人说是要改tomcat配置的,可能属于另外一种情况。
Processing of multipart/form-data request failed. Stream ended unexpectedly