|
package com.ekexiu.portal.service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.List;
import org.jfw.apt.web.annotation.Path;
import org.jfw.apt.web.annotation.operate.Post;
import org.jfw.apt.web.annotation.param.Upload;
import org.jfw.util.StringUtil;
import org.jfw.util.exception.JfwBaseException;
import org.jfw.util.web.fileupload.Item;
import org.jfw.util.web.fileupload.UploadItemIterator;
@Path("/file")
public class FileUploadService {
private long millisecondInOnDay = 1000 * 60 * 60 * 24;
private long fileMaxSize = 10 * 1024 * 1024;
private long fileMaxCount = Long.MAX_VALUE;
private String fileExtList = null;
private File rootPath;
public long getFileMaxSize() {
return fileMaxSize;
}
public void setFileMaxSize(long fileMaxSize) {
this.fileMaxSize = fileMaxSize;
}
public long getFileMaxCount() {
return fileMaxCount;
}
public void setFileMaxCount(long fileMaxCount) {
this.fileMaxCount = fileMaxCount;
}
public String getFileExtList() {
return fileExtList;
}
public void setFileExtList(String fileExtList) {
if (fileExtList.trim().length() == 0)
this.fileExtList = null;
else
this.fileExtList = fileExtList;
}
public File getRootPath() {
return rootPath;
}
public void setRootPath(File rootPath) {
this.rootPath = rootPath;
}
private void remove(List<UploadFile> files) {
for (UploadFile f : files)
f.getFn().delete();
}
private boolean validFileExt(String ext) {
if (this.fileExtList == null)
return true;
if (ext.length() == 0)
return false;
return this.fileExtList.indexOf("," + ext + ",") >= 0;
}
private String normalizeFileName(String fn) {
int index = fn.indexOf('\\');
if (index >= 0) {
fn = fn.substring(fn.lastIndexOf('\\') + 1);
}
index = fn.indexOf('/');
if (index >= 0) {
fn = fn.substring(fn.lastIndexOf('/') + 1);
}
if (fn.length() == 0)
throw new RuntimeException("invalid filename in Multipart/data request");
return fn;
}
private UploadFile buildTargetFile(String ext) {
File path = new File(this.rootPath, String.valueOf(System.currentTimeMillis() / millisecondInOnDay));
if (!path.exists())
path.mkdirs();
File file;
do {
String fn = StringUtil.buildUUID();
if (ext.isEmpty()) {
file = new File(path, fn);
} else {
file = new File(path, fn + "." + ext);
}
} while (file.exists());
UploadFile uf = new UploadFile();
uf.setFn(file);
return uf;
}
@Post
@Path("/upload")
public List<UploadFile> upload(@Upload UploadItemIterator it) throws Exception {
List<UploadFile> ret = new LinkedList<UploadFile>();
try {
long fileCount = 0;
while (it.hasNext()) {
Item item = it.next();
if (!item.isFormField()) {
++fileCount;
if (fileCount > this.fileMaxCount)
throw new JfwBaseException(-1, "invalid file count");
String name = normalizeFileName(item.getName());
int index = name.lastIndexOf('.');
String ext = index >= 0 ? name.substring(index + 1) : "";
ext = ext.trim();
if (!this.validFileExt(ext))
throw new JfwBaseException(-2, "invalid file ext");
long fileLen = 0;
int len = 0;
UploadFile uf = this.buildTargetFile(ext);
uf.setName(name);
File file = uf.getFn();
uf.setUri(file.getParentFile().getName() + "/" + file.getName());
ret.add(uf);
byte[] buf = new byte[8092];
OutputStream of = new FileOutputStream(file);
try {
InputStream in = item.getInputStream();
try {
while ((len = in.read(buf)) >= 0) {
if (len > 0) {
of.write(buf, 0, len);
fileLen += len;
if (fileLen > this.fileMaxCount)
throw new JfwBaseException(-3, "invalid file size");
}
}
uf.setSize(fileLen);
} finally {
in.close();
}
} finally {
of.close();
}
}
}
return ret;
} catch (Exception e) {
this.remove(ret);
throw e;
} finally {
if (it != null)
it.clean();
}
}
public static class UploadFile {
private String name;
private String uri;
private long size;
private transient File fn;
public File getFn() {
return fn;
}
public void setFn(File fn) {
this.fn = fn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
}
}
|