📄 upload.java
字号:
package cn.ialvin.web.upload;
import java.io.IOException;
import java.util.Hashtable;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import cn.ialvin.web.upload.exception.FileSizeTooLargeException;
import cn.ialvin.web.upload.exception.FileTypeNotAllowedException;
import cn.ialvin.web.upload.exception.UploadException;
public class Upload {
public final static int G = 1024 * 1024 * 1024;
public final static int M = 1024 * 1024;
public final static int K = 1024;
public static boolean checkInStrI(String s, String ext) {
return Upload.checkInStr(s.toUpperCase(), ext.toUpperCase());
}
public static boolean checkInStr(String s, String ext) {
return (("|" + s + "|").indexOf("|" + ext + "|")>=0);
}
private Hashtable<String, FileList> Files = new Hashtable<String, FileList>();
private Hashtable<String, StringList> params = new Hashtable<String, StringList>();
private ByteArrayBuffer data = null;
private String boundary = "";
private byte[] bound = null;
private String CHAR_SET = "UTF-8";
private byte[] CRLF = null;
boolean isDone = false;
ServletInputStream in = null;
public Upload(HttpServletRequest request) throws IOException, UploadException {
String cSet = request.getCharacterEncoding();
if (cSet != null) this.CHAR_SET = cSet;
this.CRLF = "\r\n".getBytes(this.CHAR_SET);
this.in = request.getInputStream();
this.totalByte = request.getContentLength();
String contentType = request.getContentType();
if (contentType==null || contentType.indexOf("multipart/form-data; boundary=")<0) {
this.progress = -1;
throw new UploadException("没有以 multipart/form-data 方式提交数据。");
}
this.boundary = "--" + contentType.split("boundary\\=")[1];
this.bound = this.boundary.getBytes(this.CHAR_SET);
if (this.totalByte>this.maxSize) {
this.progress = -1;
throw new UploadException("不能提交太多数据。");
}
if (this.totalByte < 3) {
this.progress = -1;
throw new UploadException("非法提交。");
}
}
public void destory() {
if (this.in == null) return;
try {
in.close();
} catch (IOException e) { }
this.in = null;
}
public void finalize() throws Throwable {
this.destory();
super.finalize();
}
private boolean _first_ = true;
private byte[] buf = null;
private int appendTo(byte[] bits) throws IOException {
int l;
int pos = this.data.indexOf(bits, 0);
while (this.current < this.totalByte
&& pos < 0) {
l = this.in.read(this.buf);
this.current += l;
this.progress = (int)(100f * this.current / this.totalByte);
pos = this.data.length();
this.data.append(this.buf, l);
pos = this.data.indexOf(bits, pos-bits.length);
}
if (pos < 0) this.isDone = true;
return pos;
}
private boolean shiftTo(byte[] bits, boolean self) throws IOException {
int l, x = 2 * bits.length;
int pos = this.data.indexOf(bits, 0);
while (this.current < this.totalByte
&& pos < 0) {
l = this.in.read(this.buf);
this.current += l;
this.progress = (int)(100f * this.current / this.totalByte);
this.data.append(this.buf, l);
pos = this.data.indexOf(bits, 0);
while (pos < 0 && this.data.length() > x) {
this.data.shift(bits.length);
}
}
if (pos < 0) {
this.isDone = true;
return false;
}
this.data.shift(pos);
if (self) this.data.shift(bits.length);
return true;
}
private byte[] _CONTENT_TYPE = null;
private byte[] _CONTENT_DISP = null;
private byte[] _FILE_NAME = null;
private byte[] _QNL = null;
private byte[] _QNLNL = null;
private byte[] _NLNL = null;
private void init() throws IOException {
this.data = new ByteArrayBuffer(this.bloackSize);
this.buf = new byte[this.bloackSize];
this._CONTENT_DISP = "Content-Disposition: form-data; name=\"".getBytes(this.CHAR_SET);
this._CONTENT_TYPE = "\"\r\nContent-Type: ".getBytes(this.CHAR_SET);
this._QNL = "\"\r\n".getBytes(this.CHAR_SET);
this._QNLNL = "\"\r\n\r\n".getBytes(this.CHAR_SET);
this._FILE_NAME = "\"; filename=\"".getBytes(this.CHAR_SET);
this._NLNL = "\r\n\r\n".getBytes(this.CHAR_SET);
this.shiftTo(this.bound, true);
}
public boolean initField() throws IOException, FileTypeNotAllowedException, FileSizeTooLargeException {
if (this._first_) { this.init(); this._first_ = false; }
if (this.isDone) return false;
this.shiftTo(this._CONTENT_DISP, true);
if (this.isDone) return false;
int pos = this.appendTo(this._QNL); // "\"\r\n"
int end = this.data.indexOf(this._FILE_NAME, 0); // "\"; filename=\""
String fieldName = "";
if (end >= 0 && end < pos) {
// 如果是文件
this.appendTo(this._NLNL);
fieldName = new String(this.data.subArray(0, end), this.CHAR_SET);
this.data.shift(end + this._FILE_NAME.length);
end = this.data.indexOf(this._CONTENT_TYPE, 0);
String fileName = new String(this.data.subArray(0, end), this.CHAR_SET);
this.data.shift(end + this._CONTENT_TYPE.length);
end = this.data.indexOf(this._NLNL, 0);
String contentType = new String(this.data.subArray(0, end), this.CHAR_SET);
this.data.shift(end + this._NLNL.length);
if (this.filter != null) {
if (!this.filter.doFilter(fieldName, fileName, this.getExt(fileName), contentType)) {
this.shiftTo(this.bound, true);
return true;
}
}
pos = this.appendTo(this.bound);
if (this.filter != null) {
if (!this.filter.filterSize(fieldName, fileName,
this.getExt(fileName), contentType,
pos-this.CRLF.length)) {
this.data.shift(pos + this.bound.length);
return true;
}
}
byte[] dat = this.data.subArray(0, pos-this.CRLF.length);
this.data.shift(pos + this.bound.length);
File file = null;
file = new File(dat);
file.setContentType(contentType);
file.setFormName(fieldName);
file.setPathName(fileName);
if (this.Files.containsKey(fieldName)) {
this.Files.get(fieldName).append(file);
} else {
FileList fl = new FileList(fieldName);
fl.append(file);
this.Files.put(fieldName, fl);
}
} else {
// 如果是表单
pos = this.appendTo(this._QNLNL);
fieldName = new String(this.data.subArray(0, pos), this.CHAR_SET);
this.data.shift(pos + this._QNLNL.length);
pos = this.appendTo(this.bound);
String value = new String(
this.data.subArray(0, pos-this.CRLF.length), this.CHAR_SET
);
this.data.shift(pos + this.CRLF.length);
if (this.params.containsKey(fieldName)) {
this.params.get(fieldName).append(value);
} else {
StringList sl = new StringList(fieldName);
sl.append(value);
this.params.put(fieldName, sl);
}
}
return true;
}
private UploadFilter filter = null;
public void setFilter(UploadFilter filter) {
if (filter != null) this.filter = filter;
}
public String getSingleParameter(String key) throws IOException, FileTypeNotAllowedException, FileSizeTooLargeException {
while (!this.params.containsKey(key) && this.initField())
;
if (this.params.containsKey(key))
return this.params.get(key).get(0);
return "";
}
public StringList getParameters(String key) throws IOException, FileTypeNotAllowedException, FileSizeTooLargeException {
while (this.initField()) ;
if (this.params.containsKey(key))
return this.params.get(key);
return new StringList(key);
}
public File getSingleFile(String key) throws IOException, FileTypeNotAllowedException, FileSizeTooLargeException {
while (!this.Files.containsKey(key) && this.initField())
;
if (this.Files.containsKey(key))
return this.Files.get(key).get(0);
return null;
}
public FileList getFiles(String key) throws IOException, FileTypeNotAllowedException, FileSizeTooLargeException {
while (this.initField()) ;
if (this.Files.containsKey(key))
return this.Files.get(key);
return new FileList(key);
}
private int progress = 0;
public int getProgress() { return this.progress; }
private int bloackSize = 1024*20;
private int totalByte = 0;
private int current = 0;
public void setBlockSize(int size) {
if (size > 1024*10 && size < 5 * 1024 * 1024)
this.bloackSize = size;
}
private int maxSize = 20*1024*1024; // 20 M;
private int allowSize = 5 * 1024 * 1024;
public void setAllowMax(int max) {
if (max < 1) return;
this.maxSize = max;
if (this.allowSize > this.maxSize)
this.allowSize = this.maxSize;
}
private String getExt(String path) {
int pos = path.lastIndexOf('.');
String ext = "";
if (pos >= 0) {
ext = path.substring(pos+1).toUpperCase();
}
return ext;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -