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 }