import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.wk.util.StringUtil;@SuppressWarnings("serial")
public class FileUploadServlet extends HttpServlet {
public static final byte CR = 0x0D;
public static final byte LF = 0x0A;
public static final byte DASH = 0x2D;
protected static final int REMAIN_SIZE = 64;
protected static final int DEFAULT_BUFSIZE = 4096;
protected static final int READ_BUFSIZE = DEFAULT_BUFSIZE - REMAIN_SIZE;
protected static final byte[] HEADER_SEPARATOR = {CR, LF, CR, LF};
protected static final byte[] FIELD_SEPARATOR = {CR, LF};
protected static final byte[] STREAM_TERMINATOR = {DASH, DASH};
protected static final byte[] BOUNDARY_PREFIX = {CR, LF, DASH, DASH}; private static String upload_base_path; protected boolean equals(byte[] b1, int start1, byte[] b2, int start2, int length) {
if (b1.length - start1 < length) {
return false;
} if (b2.length - start2 < length) {
return false;
} for (int i = 0; i < length; i++) {
if (b1[start1 + i] != b2[start2 + i]) {
return false;
}
} return true;
} protected int search(byte[] b, int start, String str) {
return search(b, start, str.getBytes());
} protected int search(byte[] b, int start, byte[] s) {
int length = s.length;
byte first = s[0];
for (int i = start, total = b.length - length; i <= total; i++) {
if (b[i] == first && equals(b, i, s, 0, length)) {
return i;
}
} return -1;
} protected byte[] merge(byte[]... bs) {
if (bs == null) {
return null;
} int total = 0;
for (byte[] b : bs) {
total += b.length;
} byte[] newb = new byte[total];
int offset = 0;
for (byte[] b : bs) {
System.arraycopy(b, 0, newb, offset, b.length);
offset += b.length;
} return newb;
} protected int readFully(InputStream in, byte[] buff, int offset, int length) {
int total = 0;
while (true) {
try {
int readlen = in.read(buff, offset, length);
if (readlen == -1) {
return 0;
} total += readlen;
if (readlen == length) {
return total;
} offset += readlen;
length -= readlen;
} catch (IOException ioe) {
return -1;
}
}
} protected void afterUploadSuccess(int index, String name, String fileName) {
} protected void afterUploadFail(String errcode, String errmsg) {
afterUploadFail(0, errcode, errmsg);
} protected void afterUploadFail(int index, String errcode, String errmsg) {
if (index == 0) {
System.out.println(errcode + ":" + errmsg);
} else {
System.out.println("Upload file " + index + " error:");
System.out.println(errcode + ":" + errmsg);
}
} protected String getUploadPath(HttpServletRequest request) {
String saveFilePath = request.getParameter("uploadPath");
if (saveFilePath == null) {
saveFilePath="upload";
} String uploadPath;
if (StringUtil.isEmpty(upload_base_path)) {
uploadPath = getServletContext().getRealPath(saveFilePath);
} else {
uploadPath = upload_base_path + saveFilePath;
} return uploadPath;
} protected String getUploadFileName(HttpServletRequest request, int index, String name, String fileName) throws UnsupportedEncodingException {
String[] fnames = request.getParameterValues("fileName");
String fname = fileName;
if (fnames != null && fnames.length >= index) {
fname = fnames[index-1];
} if (fname == null) {
fname = "";
}
fname = new String(fname.getBytes("iso-8859-1"),"UTF-8"); char sep = (fname.indexOf('/') >= 0) ? '/' : '\\';
int pos = fname.lastIndexOf(sep);
String newFileName;
if (pos < 0) {
newFileName = fname;
} else {
newFileName = fname.substring(pos + 1);
} return getUploadPath(request) + File.separatorChar + newFileName;
} private String getNameFromDisposition(byte[] disposition) {
return getField(disposition, "name=");
} private String getFileNameFromDisposition(byte[] disposition) {
return getField(disposition, "filename=");
} private String getField(byte[] disposition, String field) {
int field_start = search(disposition, 0, field);
if (field_start == -1) {
return null;
} String value;
field_start += field.length();
int field_end = search(disposition, field_start, ";");
if (field_end == -1) {
value = new String(disposition, field_start, disposition.length - field_start).trim();
} else {
value = new String(disposition, field_start, field_end - field_start).trim();
} value = value.replaceAll("\"", "");
return value;
} static class FileInfo {
int index; // 第几个文件,从1开始
boolean isFile; // 是否是文件
String fileName; // 文件名
String name; // input的名称
int size; // 文件的大小
int remain; // 这次读的但是没有处理完成的数据
boolean success; // 是否保存成功
String errcode; // 错误编号
String errmsg; // 错误信息 FileInfo fail(String errcode, String errmsg) {
this.success = false;
this.errcode = errcode;
this.errmsg = errmsg;
return this;
}
} private FileInfo saveOneFile(HttpServletRequest request, InputStream in,
int index, int length, byte[] data, int remain, byte[] boundary_tag) throws UnsupportedEncodingException {
FileInfo fi = new FileInfo();
fi.index = index;
fi.success = true; int readlen = (length > (DEFAULT_BUFSIZE-remain))? (DEFAULT_BUFSIZE-remain) : length;
if (readFully(in, data, remain, readlen) == -1) {
return fi.fail("ERR_READ_NETWORK_DATA", "Read data from network error");
}
length -= readlen;
readlen += remain; // System.out.println("buffer:" + new String(data, 0, readlen)); // 处理boundary start
if (!equals(data, 0, boundary_tag, 0, boundary_tag.length)) {
return fi.fail("ERR_DATA_BOUNDARY", "Data not start with the boundary");
} if (equals(data, boundary_tag.length, STREAM_TERMINATOR, 0, STREAM_TERMINATOR.length)) {
return fi;
} // 处理文件名
int content_disposition_start = search(data, 0, "Content-Disposition");
if (content_disposition_start == -1) {
return fi.fail("ERR_DATA_DISPOSITION", "Cannot get the content disposition");
} int field_end = search(data, content_disposition_start, FIELD_SEPARATOR);
if (field_end == -1) {
return fi.fail("ERR_DATA_DISPOSITION", "Cannot get the content disposition");
} byte[] disposition = new byte[field_end - content_disposition_start];
System.arraycopy(data, content_disposition_start, disposition, 0, field_end - content_disposition_start); String fname = getFileNameFromDisposition(disposition);
if (fname != null && !fname.equals("")) {
fi.isFile = true;
} else {
fi.isFile = false;
fname = "";
} String name = getNameFromDisposition(disposition);
fname = getUploadFileName(request, index, name, fname);
System.out.println(fname+"++++++++++++++++++++++++++++++++=");
fi.fileName = fname;
fi.name = name; //System.out.println("fname="+fname); // 到达开始处
int content_start = search(data, 0, HEADER_SEPARATOR);
if (content_start == -1) {
return fi.fail("ERR_DATA_CONTENT_START", "Cannot get the content start");
}
content_start += HEADER_SEPARATOR.length; // 打开文件
FileOutputStream fo = null;
if (fi.isFile) {
try {
fo = new FileOutputStream(fname);
} catch (IOException ioe) {
ioe.printStackTrace();
return fi.fail("ERR_FILE_CREATE", "cannot create file: " + fname);
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.wk.util.StringUtil;@SuppressWarnings("serial")
public class FileUploadServlet extends HttpServlet {
public static final byte CR = 0x0D;
public static final byte LF = 0x0A;
public static final byte DASH = 0x2D;
protected static final int REMAIN_SIZE = 64;
protected static final int DEFAULT_BUFSIZE = 4096;
protected static final int READ_BUFSIZE = DEFAULT_BUFSIZE - REMAIN_SIZE;
protected static final byte[] HEADER_SEPARATOR = {CR, LF, CR, LF};
protected static final byte[] FIELD_SEPARATOR = {CR, LF};
protected static final byte[] STREAM_TERMINATOR = {DASH, DASH};
protected static final byte[] BOUNDARY_PREFIX = {CR, LF, DASH, DASH}; private static String upload_base_path; protected boolean equals(byte[] b1, int start1, byte[] b2, int start2, int length) {
if (b1.length - start1 < length) {
return false;
} if (b2.length - start2 < length) {
return false;
} for (int i = 0; i < length; i++) {
if (b1[start1 + i] != b2[start2 + i]) {
return false;
}
} return true;
} protected int search(byte[] b, int start, String str) {
return search(b, start, str.getBytes());
} protected int search(byte[] b, int start, byte[] s) {
int length = s.length;
byte first = s[0];
for (int i = start, total = b.length - length; i <= total; i++) {
if (b[i] == first && equals(b, i, s, 0, length)) {
return i;
}
} return -1;
} protected byte[] merge(byte[]... bs) {
if (bs == null) {
return null;
} int total = 0;
for (byte[] b : bs) {
total += b.length;
} byte[] newb = new byte[total];
int offset = 0;
for (byte[] b : bs) {
System.arraycopy(b, 0, newb, offset, b.length);
offset += b.length;
} return newb;
} protected int readFully(InputStream in, byte[] buff, int offset, int length) {
int total = 0;
while (true) {
try {
int readlen = in.read(buff, offset, length);
if (readlen == -1) {
return 0;
} total += readlen;
if (readlen == length) {
return total;
} offset += readlen;
length -= readlen;
} catch (IOException ioe) {
return -1;
}
}
} protected void afterUploadSuccess(int index, String name, String fileName) {
} protected void afterUploadFail(String errcode, String errmsg) {
afterUploadFail(0, errcode, errmsg);
} protected void afterUploadFail(int index, String errcode, String errmsg) {
if (index == 0) {
System.out.println(errcode + ":" + errmsg);
} else {
System.out.println("Upload file " + index + " error:");
System.out.println(errcode + ":" + errmsg);
}
} protected String getUploadPath(HttpServletRequest request) {
String saveFilePath = request.getParameter("uploadPath");
if (saveFilePath == null) {
saveFilePath="upload";
} String uploadPath;
if (StringUtil.isEmpty(upload_base_path)) {
uploadPath = getServletContext().getRealPath(saveFilePath);
} else {
uploadPath = upload_base_path + saveFilePath;
} return uploadPath;
} protected String getUploadFileName(HttpServletRequest request, int index, String name, String fileName) throws UnsupportedEncodingException {
String[] fnames = request.getParameterValues("fileName");
String fname = fileName;
if (fnames != null && fnames.length >= index) {
fname = fnames[index-1];
} if (fname == null) {
fname = "";
}
fname = new String(fname.getBytes("iso-8859-1"),"UTF-8"); char sep = (fname.indexOf('/') >= 0) ? '/' : '\\';
int pos = fname.lastIndexOf(sep);
String newFileName;
if (pos < 0) {
newFileName = fname;
} else {
newFileName = fname.substring(pos + 1);
} return getUploadPath(request) + File.separatorChar + newFileName;
} private String getNameFromDisposition(byte[] disposition) {
return getField(disposition, "name=");
} private String getFileNameFromDisposition(byte[] disposition) {
return getField(disposition, "filename=");
} private String getField(byte[] disposition, String field) {
int field_start = search(disposition, 0, field);
if (field_start == -1) {
return null;
} String value;
field_start += field.length();
int field_end = search(disposition, field_start, ";");
if (field_end == -1) {
value = new String(disposition, field_start, disposition.length - field_start).trim();
} else {
value = new String(disposition, field_start, field_end - field_start).trim();
} value = value.replaceAll("\"", "");
return value;
} static class FileInfo {
int index; // 第几个文件,从1开始
boolean isFile; // 是否是文件
String fileName; // 文件名
String name; // input的名称
int size; // 文件的大小
int remain; // 这次读的但是没有处理完成的数据
boolean success; // 是否保存成功
String errcode; // 错误编号
String errmsg; // 错误信息 FileInfo fail(String errcode, String errmsg) {
this.success = false;
this.errcode = errcode;
this.errmsg = errmsg;
return this;
}
} private FileInfo saveOneFile(HttpServletRequest request, InputStream in,
int index, int length, byte[] data, int remain, byte[] boundary_tag) throws UnsupportedEncodingException {
FileInfo fi = new FileInfo();
fi.index = index;
fi.success = true; int readlen = (length > (DEFAULT_BUFSIZE-remain))? (DEFAULT_BUFSIZE-remain) : length;
if (readFully(in, data, remain, readlen) == -1) {
return fi.fail("ERR_READ_NETWORK_DATA", "Read data from network error");
}
length -= readlen;
readlen += remain; // System.out.println("buffer:" + new String(data, 0, readlen)); // 处理boundary start
if (!equals(data, 0, boundary_tag, 0, boundary_tag.length)) {
return fi.fail("ERR_DATA_BOUNDARY", "Data not start with the boundary");
} if (equals(data, boundary_tag.length, STREAM_TERMINATOR, 0, STREAM_TERMINATOR.length)) {
return fi;
} // 处理文件名
int content_disposition_start = search(data, 0, "Content-Disposition");
if (content_disposition_start == -1) {
return fi.fail("ERR_DATA_DISPOSITION", "Cannot get the content disposition");
} int field_end = search(data, content_disposition_start, FIELD_SEPARATOR);
if (field_end == -1) {
return fi.fail("ERR_DATA_DISPOSITION", "Cannot get the content disposition");
} byte[] disposition = new byte[field_end - content_disposition_start];
System.arraycopy(data, content_disposition_start, disposition, 0, field_end - content_disposition_start); String fname = getFileNameFromDisposition(disposition);
if (fname != null && !fname.equals("")) {
fi.isFile = true;
} else {
fi.isFile = false;
fname = "";
} String name = getNameFromDisposition(disposition);
fname = getUploadFileName(request, index, name, fname);
System.out.println(fname+"++++++++++++++++++++++++++++++++=");
fi.fileName = fname;
fi.name = name; //System.out.println("fname="+fname); // 到达开始处
int content_start = search(data, 0, HEADER_SEPARATOR);
if (content_start == -1) {
return fi.fail("ERR_DATA_CONTENT_START", "Cannot get the content start");
}
content_start += HEADER_SEPARATOR.length; // 打开文件
FileOutputStream fo = null;
if (fi.isFile) {
try {
fo = new FileOutputStream(fname);
} catch (IOException ioe) {
ioe.printStackTrace();
return fi.fail("ERR_FILE_CREATE", "cannot create file: " + fname);
}
}
解决方案 »
- 客户端开发
- 怎么移位获取一个4字节的byte数组的前30bit?
- 引包报错 是少jar包吗?
- Hibernate,org.hibernate.QueryException
- 事务 + 批处理
- 请问各位,java application中如何才能获取到需要用户名密码验证的网页源代码阿?
- 关于javaMail的问题,大家给看看 是哪里出错了。
- Linux(红帽AS4)下tomcat5+oracle10g,对于blob显示为乱码,同样的程序window下正常
- 只知道节点的名称,如何把节点删除?
- 刚开始学ejb,就困惑了----接口的对象?
- 问个小问题~很简单的~~~
- hibernate3.6.7中使用annotation的问题
try {
int data_start = content_start;
while (true) {
int boundary_end = search(data, data_start, boundary_tag);
if (boundary_end == -1) {
if (length == 0) {
//System.out.println("buffer:" + new String(data, data_start, readlen));
return fi.fail("ERR_DATA_BOUNDARY", "Cannot get the boundary end");
} int writelen = readlen - data_start - REMAIN_SIZE;
if (fi.isFile) {
try {
fo.write(data, data_start, writelen);
//System.out.println("Write " + writelen + " bytes");
} catch (IOException ioe) {
return fi.fail("ERR_WRITE_FILE", "Write data to file error");
}
}
size += writelen;
System.arraycopy(data, readlen - REMAIN_SIZE, data, 0, REMAIN_SIZE); readlen = (length > READ_BUFSIZE)? READ_BUFSIZE : length;
if (readFully(in, data, REMAIN_SIZE, readlen) == -1) {
return fi.fail("ERR_READ_NETWORK_DATA", "Read data from network error");
} //System.out.println("Read " + readlen + " bytes");
length -= readlen;
readlen += REMAIN_SIZE;
data_start = 0;
} else {
int writelen = boundary_end - data_start;
if (fi.isFile) {
try {
fo.write(data, data_start, writelen);
//System.out.println("Write " + writelen + " bytes over");
} catch (IOException ioe) {
return fi.fail("ERR_WRITE_FILE", "Write data to file error");
}
}
size += writelen;
fi.remain = readlen - boundary_end;
System.arraycopy(data, boundary_end, data, 0, fi.remain);
break;
}
}
} finally {
if (fo != null) {
try {
fo.close();
} catch (IOException ioe) {
return fi.fail("ERR_CLOSE_FILE", "Close file error");
}
}
} fi.size = size;
return fi;
} private boolean saveFile(HttpServletRequest request) throws UnsupportedEncodingException {
String contentType = request.getContentType();
//System.out.println("ContentType=" + contentType); if (contentType == null || !contentType.startsWith("multipart/form-data")) {
afterUploadFail("ERR_CONTENT_TYPE", "ContentType not multipart/form-data\n");
return false;
} byte[] boundary = contentType.substring(contentType.indexOf("boundary=") + 9).getBytes();
byte[] boundary_tag = merge(BOUNDARY_PREFIX, boundary); int length = request.getContentLength();
System.out.println("Total stream size: " + length);
InputStream in = null;
try {
in = request.getInputStream();
} catch (IOException ioe) {
afterUploadFail("ERR_READ_NETWORK_DATA", "Get input stream error");
return false;
} byte[] data = new byte[DEFAULT_BUFSIZE];
data[0] = CR;
data[1] = LF;
int remain = 2; int index = 1;
while (true) {
FileInfo fi = saveOneFile(request, in, index, length, data, remain, boundary_tag);
if (!fi.success) {
afterUploadFail(index, fi.errcode, fi.errmsg);
return false;
} else if (fi.isFile) {
afterUploadSuccess(index, fi.name, fi.fileName);
index++;
System.out.println("Success upload file " + fi.fileName);
//System.out.println("file size " + fi.size);
} else {
break;
} length -= fi.size;
remain = fi.remain; if (length <= 0) {
break;
} //System.out.println("length remain " + length);
//System.out.println("data remain " + remain);
} return true;
} public void init() throws ServletException {
try {
upload_base_path = "/home/vloaner/";
System.out.println("FileUploadServlet init params upload path:" + upload_base_path);
} catch(Exception e) {
e.printStackTrace();
} } public void doPost(HttpServletRequest request, HttpServletResponse response) {
boolean success = false;
try {
success = saveFile(request);
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
try {
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("text/html;charset=UTF-8"); String html =
"<script language='JavaScript'>\n" +
" if (parent._on_upload_over) {\n" +
" parent._on_upload_over(" + success + ");\n" +
" }\n" +
"</script>\n"; try {
PrintWriter out = response.getWriter();
out.print(html);
response.flushBuffer();
} catch (IOException ioe) {
ioe.printStackTrace();
}
} public void doGet(HttpServletRequest request, HttpServletResponse response) {
throw new RuntimeException("File upload only support post");
}
}