1 package com.baidu.ueditor.um; 2 3 import java.io.BufferedInputStream; 4 import java.io.BufferedOutputStream; 5 import java.io.BufferedReader; 6 import java.io.File; 7 import java.io.FileOutputStream; 8 import java.io.InputStreamReader; 9 import java.io.OutputStream; 10 import java.text.SimpleDateFormat; 11 import java.util.Arrays; 12 import java.util.Date; 13 import java.util.HashMap; 14 import java.util.Iterator; 15 import java.util.Random; 16 17 import javax.servlet.http.HttpServletRequest; 18 19 import org.apache.commons.fileupload.FileItemIterator; 20 import org.apache.commons.fileupload.FileItemStream; 21 import org.apache.commons.fileupload.FileUploadBase.InvalidContentTypeException; 22 import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException; 23 import org.apache.commons.fileupload.FileUploadException; 24 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 25 import org.apache.commons.fileupload.servlet.ServletFileUpload; 26 import org.apache.commons.fileupload.util.Streams; 27 28 import sun.misc.BASE64Decoder; 29 30 /** 31 * UEditor文件上传辅助类 32 * 33 */ 34 public class Uploader { 35 // 输出文件地址 36 private String url = ""; 37 // 上传文件名 38 private String fileName = ""; 39 // 状态 40 private String state = ""; 41 // 文件类型 42 private String type = ""; 43 // 原始文件名 44 private String originalName = ""; 45 // 文件大小 46 private long size = 0; 47 48 private HttpServletRequest request = null; 49 private String title = ""; 50 51 // 保存路径 52 private String savePath = "upload"; 53 // 文件允许格式 54 private String[] allowFiles = { ".rar", ".doc", ".docx", ".zip", ".pdf", ".txt", ".swf", ".wmv", ".gif", ".png", ".jpg", ".jpeg", ".bmp" }; 55 // 文件大小限制,单位KB 56 private int maxSize = 10000; 57 58 private HashMap<String, String> errorInfo = new HashMap<String, String>(); 59 60 public Uploader(HttpServletRequest request) { 61 this.request = request; 62 HashMap<String, String> tmp = this.errorInfo; 63 tmp.put("SUCCESS", "SUCCESS"); // 默认成功 64 tmp.put("NOFILE", "未包含文件上传域"); 65 tmp.put("TYPE", "不允许的文件格式"); 66 tmp.put("SIZE", "文件大小超出限制"); 67 tmp.put("ENTYPE", "请求类型ENTYPE错误"); 68 tmp.put("REQUEST", "上传请求异常"); 69 tmp.put("IO", "IO异常"); 70 tmp.put("DIR", "目录创建失败"); 71 tmp.put("UNKNOWN", "未知错误"); 72 } 73 74 public void upload() throws Exception { 75 boolean isMultipart = ServletFileUpload.isMultipartContent(this.request); 76 if (!isMultipart) { 77 this.state = this.errorInfo.get("NOFILE"); 78 return; 79 } 80 DiskFileItemFactory dff = new DiskFileItemFactory(); 81 String savePath = this.getFolder(this.savePath); 82 dff.setRepository(new File(savePath)); 83 try { 84 ServletFileUpload sfu = new ServletFileUpload(dff); 85 sfu.setSizeMax(this.maxSize * 1024); 86 sfu.setHeaderEncoding("utf-8"); 87 FileItemIterator fii = sfu.getItemIterator(this.request); 88 while (fii.hasNext()) { 89 FileItemStream fis = fii.next(); 90 if (!fis.isFormField()) { 91 this.originalName = fis.getName().substring(fis.getName().lastIndexOf(System.getProperty("file.separator")) + 1); 92 if (!this.checkFileType(this.originalName)) { 93 this.state = this.errorInfo.get("TYPE"); 94 continue; 95 } 96 this.fileName = this.getName(this.originalName); 97 this.type = this.getFileExt(this.fileName); 98 this.url = savePath + "/" + this.fileName; 99 BufferedInputStream in = new BufferedInputStream(fis.openStream()); 100 File file = new File(this.getPhysicalPath(this.url)); 101 FileOutputStream out = new FileOutputStream(file); 102 BufferedOutputStream output = new BufferedOutputStream(out); 103 Streams.copy(in, output, true); 104 this.state = this.errorInfo.get("SUCCESS"); 105 this.size = file.length(); 106 // UE中只会处理单张上传,完成后即退出 107 break; 108 } else { 109 String fname = fis.getFieldName(); 110 // 只处理title,其余表单请自行处理 111 if (!fname.equals("pictitle")) { 112 continue; 113 } 114 BufferedInputStream in = new BufferedInputStream(fis.openStream()); 115 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 116 StringBuffer result = new StringBuffer(); 117 while (reader.ready()) { 118 result.append((char) reader.read()); 119 } 120 this.title = new String(result.toString().getBytes(),"utf-8"); 121 reader.close(); 122 } 123 } 124 } catch (SizeLimitExceededException e) { 125 this.state = this.errorInfo.get("SIZE"); 126 } catch (InvalidContentTypeException e) { 127 this.state = this.errorInfo.get("ENTYPE"); 128 } catch (FileUploadException e) { 129 this.state = this.errorInfo.get("REQUEST"); 130 } catch (Exception e) { 131 this.state = this.errorInfo.get("UNKNOWN"); 132 } 133 } 134 135 /** 136 * 接受并保存以base64格式上传的文件 137 * 138 * @param fieldName 139 */ 140 public void uploadBase64(String fieldName) { 141 String savePath = this.getFolder(this.savePath); 142 String base64Data = this.request.getParameter(fieldName); 143 this.fileName = this.getName("test.png"); 144 this.url = savePath + "/" + this.fileName; 145 BASE64Decoder decoder = new BASE64Decoder(); 146 try { 147 File outFile = new File(this.getPhysicalPath(this.url)); 148 OutputStream ro = new FileOutputStream(outFile); 149 byte[] b = decoder.decodeBuffer(base64Data); 150 for (int i = 0; i < b.length; ++i) { 151 if (b[i] < 0) { 152 b[i] += 256; 153 } 154 } 155 ro.write(b); 156 ro.flush(); 157 ro.close(); 158 this.state = this.errorInfo.get("SUCCESS"); 159 } catch (Exception e) { 160 this.state = this.errorInfo.get("IO"); 161 } 162 } 163 164 /** 165 * 文件类型判断 166 * 167 * @param fileName 168 * @return 169 */ 170 private boolean checkFileType(String fileName) { 171 Iterator<String> type = Arrays.asList(this.allowFiles).iterator(); 172 while (type.hasNext()) { 173 String ext = type.next(); 174 if (fileName.toLowerCase().endsWith(ext)) { 175 return true; 176 } 177 } 178 return false; 179 } 180 181 /** 182 * 获取文件扩展名 183 * 184 * @return string 185 */ 186 private String getFileExt(String fileName) { 187 return fileName.substring(fileName.lastIndexOf(".")); 188 } 189 /** 190 * 依据原始文件名生成新文件名 191 * 192 * @return 193 */ 194 private String getName(String fileName) { 195 Random random = new Random(); 196 return this.fileName = "" + random.nextInt(10000) + System.currentTimeMillis() + this.getFileExt(fileName); 197 } 198 /** 199 * 根据字符串创建本地目录 并按照日期建立子目录返回 200 * 201 * @param path 202 * @return 203 */ 204 private String getFolder(String path) { 205 SimpleDateFormat formater = new SimpleDateFormat("yyyyMMdd"); 206 path += "/" + formater.format(new Date()); 207 File dir = new File(this.getPhysicalPath(path)); 208 if (!dir.exists()) { 209 try { 210 dir.mkdirs(); 211 } catch (Exception e) { 212 this.state = this.errorInfo.get("DIR"); 213 return ""; 214 } 215 } 216 return path; 217 } 218 public static void main(String[] args) { 219 SimpleDateFormat formater = new SimpleDateFormat("yyyyMMddhhmmss"); 220 String strDate = formater.format(new Date()); 221 System.out.println(strDate); 222 } 223 /** 224 * 根据传入的虚拟路径获取物理路径 225 * 226 * @param path 227 * @return 228 */ 229 private String getPhysicalPath(String path) { 230 String servletPath = this.request.getServletPath(); 231 String realPath = this.request.getSession().getServletContext() 232 .getRealPath(servletPath); 233 return new File(realPath).getParent() + "/" + path; 234 } 235 236 public void setSavePath(String savePath) { 237 this.savePath = savePath; 238 } 239 240 public void setAllowFiles(String[] allowFiles) { 241 this.allowFiles = allowFiles; 242 } 243 244 public void setMaxSize(int size) { 245 this.maxSize = size; 246 } 247 248 public long getSize() { 249 return this.size; 250 } 251 252 public String getUrl() { 253 return this.url; 254 } 255 256 public String getFileName() { 257 return this.fileName; 258 } 259 260 public String getState() { 261 return this.state; 262 } 263 264 public String getTitle() { 265 return this.title; 266 } 267 268 public String getType() { 269 return this.type; 270 } 271 272 public String getOriginalName() { 273 return this.originalName; 274 } 275 }