protected boolean readNextPart(MultipartInputStreamHandler in,
String boundary) throws IOException {
// Read the first line, should look like this:
// content-disposition: form-data; name="field1"; filename="file1.txt"
String line = in.readLine();
if (line == null) {
// No parts left, we're done
return true;
}
else if (line.length() == 0) {
// IE4 on Mac sends an empty line at the end; treat that as the end.
// Thanks to Daniel Lemire and Henri Tourigny for this fix.
return true;
} // Parse the content-disposition line
String[] dispInfo = extractDispositionInfo(line);
String disposition = dispInfo[0];
String name = dispInfo[1];
String filename = dispInfo[2]; // Now onto the next line. This will either be empty
// or contain a Content-Type and then an empty line.
line = in.readLine();
if (line == null) {
// No parts left, we're done
return true;
} // Get the content type, or null if none specified
String contentType = extractContentType(line);
if (contentType != null) {
// Eat the empty line
line = in.readLine();
if (line == null || line.length() > 0) { // line should be empty
throw new
IOException("Malformed line after content type: " + line);
}
}
else {
// Assume a default content type
contentType = "application/octet-stream";
} // Now, finally, we read the content (end after reading the boundary)
if (filename == null) {
// This is a parameter, add it to the vector of values
String value = readParameter(in, boundary);
if (value.equals("")) {
value = null; // treat empty strings like nulls
}
Vector existingValues = (Vector)parameters.get(name);
if (existingValues == null) {
existingValues = new Vector();
parameters.put(name, existingValues);
}
existingValues.addElement(value);
}
else {
// This is a file File savedFile = readAndSaveFile(in, boundary, filename,
contentType);
if (filename.equals(NO_FILE)) {
files.put(name, new UploadedFile(null, null, null));
}
else {
files.put(name,
new UploadedFile(filename, savedFile, contentType));
}
}
return false; // there's more to read
} protected String readParameter(MultipartInputStreamHandler in,
String boundary) throws IOException {
StringBuffer sbuf = new StringBuffer();
String line; while ((line = in.readLine()) != null) {
if (line.startsWith(boundary)) break;
sbuf.append(line + "\r\n"); // add the \r\n in case there are many lines
} if (sbuf.length() == 0) {
return null; // nothing read
} sbuf.setLength(sbuf.length() - 2); // cut off the last line's \r\n
return sbuf.toString(); // no URL decoding needed
} protected File readAndSaveFile(MultipartInputStreamHandler in,
String boundary,
String filename,
String contentType) throws IOException {
OutputStream out = null;
int year = Calendar.getInstance().get(Calendar.YEAR);
int month = Calendar.getInstance().get(Calendar.MONTH) + 1;
int date = Calendar.getInstance().get(Calendar.DATE); //i modify it from time to date,kaka
int id = getID();
String prefix = new Integer(year).toString() + new Integer(month).toString() +
new Integer(date).toString() + "_" + new Integer(ID).toString(); File newFile = null; // A filename of NO_FILE means no file was sent, so just read to the
// next boundary and ignore the empty contents
if (filename.equals(NO_FILE)) {
out = new ByteArrayOutputStream(); // write to nowhere
}
// A MacBinary file goes through a decoder
else if (contentType.equals("application/x-macbinary")){
newFile = new File(dir + File.separator + prefix + filename);
out = new MacBinaryDecoderOutputStream(
new BufferedOutputStream(
new FileOutputStream(newFile), 8 * 1024));
}
// A real file's contents are written to disk
else {
newFile = new File(dir + File.separator + prefix + filename);
out = new BufferedOutputStream(new FileOutputStream(newFile), 8 * 1024);
} byte[] bbuf = new byte[100 * 1024]; // 100K
int result;
String line; // ServletInputStream.readLine() has the annoying habit of
// adding a \r\n to the end of the last line.
// Since we want a byte-for-byte transfer, we have to cut those chars.
boolean rnflag = false;
while ((result = in.readLine(bbuf, 0, bbuf.length)) != -1) {
// Check for boundary
if (result > 2 && bbuf[0] == '-' && bbuf[1] == '-') { // quick pre-check
line = new String(bbuf, 0, result, "gb2312");
if (line.startsWith(boundary)) break;
}
// Are we supposed to write \r\n for the last iteration?
if (rnflag) {
out.write('\r'); out.write('\n');
rnflag = false;
}
// Write the buffer, postpone any ending \r\n
if (result >= 2 &&
bbuf[result - 2] == '\r' &&
bbuf[result - 1] == '\n') {
out.write(bbuf, 0, result - 2); // skip the last 2 chars
rnflag = true; // make a note to write them on the next iteration
}
else {
out.write(bbuf, 0, result);
}
}
out.flush();
out.close(); //set the uploaded file name for client use
setUploadedFilename(prefix + filename); return newFile; } // Extracts and returns the boundary token from a line.
//
private String extractBoundary(String line) {
// Use lastIndexOf() because IE 4.01 on Win98 has been known to send the
// "boundary=" string multiple times. Thanks to David Wall for this fix.
int index = line.lastIndexOf("boundary=");
if (index == -1) {
return null;
}
String boundary = line.substring(index + 9); // 9 for "boundary=" // The real boundary is always preceeded by an extra "--"
boundary = "--" + boundary; return boundary;
}to be continue
String boundary) throws IOException {
// Read the first line, should look like this:
// content-disposition: form-data; name="field1"; filename="file1.txt"
String line = in.readLine();
if (line == null) {
// No parts left, we're done
return true;
}
else if (line.length() == 0) {
// IE4 on Mac sends an empty line at the end; treat that as the end.
// Thanks to Daniel Lemire and Henri Tourigny for this fix.
return true;
} // Parse the content-disposition line
String[] dispInfo = extractDispositionInfo(line);
String disposition = dispInfo[0];
String name = dispInfo[1];
String filename = dispInfo[2]; // Now onto the next line. This will either be empty
// or contain a Content-Type and then an empty line.
line = in.readLine();
if (line == null) {
// No parts left, we're done
return true;
} // Get the content type, or null if none specified
String contentType = extractContentType(line);
if (contentType != null) {
// Eat the empty line
line = in.readLine();
if (line == null || line.length() > 0) { // line should be empty
throw new
IOException("Malformed line after content type: " + line);
}
}
else {
// Assume a default content type
contentType = "application/octet-stream";
} // Now, finally, we read the content (end after reading the boundary)
if (filename == null) {
// This is a parameter, add it to the vector of values
String value = readParameter(in, boundary);
if (value.equals("")) {
value = null; // treat empty strings like nulls
}
Vector existingValues = (Vector)parameters.get(name);
if (existingValues == null) {
existingValues = new Vector();
parameters.put(name, existingValues);
}
existingValues.addElement(value);
}
else {
// This is a file File savedFile = readAndSaveFile(in, boundary, filename,
contentType);
if (filename.equals(NO_FILE)) {
files.put(name, new UploadedFile(null, null, null));
}
else {
files.put(name,
new UploadedFile(filename, savedFile, contentType));
}
}
return false; // there's more to read
} protected String readParameter(MultipartInputStreamHandler in,
String boundary) throws IOException {
StringBuffer sbuf = new StringBuffer();
String line; while ((line = in.readLine()) != null) {
if (line.startsWith(boundary)) break;
sbuf.append(line + "\r\n"); // add the \r\n in case there are many lines
} if (sbuf.length() == 0) {
return null; // nothing read
} sbuf.setLength(sbuf.length() - 2); // cut off the last line's \r\n
return sbuf.toString(); // no URL decoding needed
} protected File readAndSaveFile(MultipartInputStreamHandler in,
String boundary,
String filename,
String contentType) throws IOException {
OutputStream out = null;
int year = Calendar.getInstance().get(Calendar.YEAR);
int month = Calendar.getInstance().get(Calendar.MONTH) + 1;
int date = Calendar.getInstance().get(Calendar.DATE); //i modify it from time to date,kaka
int id = getID();
String prefix = new Integer(year).toString() + new Integer(month).toString() +
new Integer(date).toString() + "_" + new Integer(ID).toString(); File newFile = null; // A filename of NO_FILE means no file was sent, so just read to the
// next boundary and ignore the empty contents
if (filename.equals(NO_FILE)) {
out = new ByteArrayOutputStream(); // write to nowhere
}
// A MacBinary file goes through a decoder
else if (contentType.equals("application/x-macbinary")){
newFile = new File(dir + File.separator + prefix + filename);
out = new MacBinaryDecoderOutputStream(
new BufferedOutputStream(
new FileOutputStream(newFile), 8 * 1024));
}
// A real file's contents are written to disk
else {
newFile = new File(dir + File.separator + prefix + filename);
out = new BufferedOutputStream(new FileOutputStream(newFile), 8 * 1024);
} byte[] bbuf = new byte[100 * 1024]; // 100K
int result;
String line; // ServletInputStream.readLine() has the annoying habit of
// adding a \r\n to the end of the last line.
// Since we want a byte-for-byte transfer, we have to cut those chars.
boolean rnflag = false;
while ((result = in.readLine(bbuf, 0, bbuf.length)) != -1) {
// Check for boundary
if (result > 2 && bbuf[0] == '-' && bbuf[1] == '-') { // quick pre-check
line = new String(bbuf, 0, result, "gb2312");
if (line.startsWith(boundary)) break;
}
// Are we supposed to write \r\n for the last iteration?
if (rnflag) {
out.write('\r'); out.write('\n');
rnflag = false;
}
// Write the buffer, postpone any ending \r\n
if (result >= 2 &&
bbuf[result - 2] == '\r' &&
bbuf[result - 1] == '\n') {
out.write(bbuf, 0, result - 2); // skip the last 2 chars
rnflag = true; // make a note to write them on the next iteration
}
else {
out.write(bbuf, 0, result);
}
}
out.flush();
out.close(); //set the uploaded file name for client use
setUploadedFilename(prefix + filename); return newFile; } // Extracts and returns the boundary token from a line.
//
private String extractBoundary(String line) {
// Use lastIndexOf() because IE 4.01 on Win98 has been known to send the
// "boundary=" string multiple times. Thanks to David Wall for this fix.
int index = line.lastIndexOf("boundary=");
if (index == -1) {
return null;
}
String boundary = line.substring(index + 9); // 9 for "boundary=" // The real boundary is always preceeded by an extra "--"
boundary = "--" + boundary; return boundary;
}to be continue
解决方案 »
- webService抛出 org.apache.axis2.AxisFault异常
- swfupload 获取上传文件路径问题
- 线程创建出错
- 高手帮忙,Thank you!!!
- 字符串“2000-1-1” 转为日期类型怎样转啊?
- 请推荐个开源的java网站进行参考
- 怎么样在jsp页面中实现音乐在线视听功能(高分,来看看了)
- 高分求救高手指点,准备国庆完后一切从头来!
- 如何把网上的一个文件下载下来,或者直接把网上的文件读入到一个变量中.
- smartupload 在Jbuilder 中如何配置才能在JSP文件中使用?
- 为什么jbuilder9里面没有javax.servlet包?
- 请问 编 jsp 除了直接用记事本 有没有什么工具!!!
// with elements: disposition, name, filename. Throws an IOException
// if the line is malformatted.
//
private String[] extractDispositionInfo(String line) throws IOException {
// Return the line's data as an array: disposition, name, filename
String[] retval = new String[3]; // Convert the line to a lowercase string without the ending \r\n
// Keep the original line for error messages and for variable names.
String origline = line;
line = origline.toLowerCase(); // Get the content disposition, should be "form-data"
int start = line.indexOf("content-disposition: ");
int end = line.indexOf(";");
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String disposition = line.substring(start + 21, end);
if (!disposition.equals("form-data")) {
throw new IOException("Invalid content disposition: " + disposition);
} // Get the field name
start = line.indexOf("name=\"", end); // start at last semicolon
end = line.indexOf("\"", start + 7); // skip name=\"
if (start == -1 || end == -1) {
throw new IOException("Content disposition corrupt: " + origline);
}
String name = origline.substring(start + 6, end); // Get the filename, if given
String filename = null;
start = line.indexOf("filename=\"", end + 2); // start after name
end = line.indexOf("\"", start + 10); // skip filename=\"
if (start != -1 && end != -1) { // note the !=
filename = origline.substring(start + 10, end);
// The filename may contain a full path. Cut to just the filename.
int slash =
Math.max(filename.lastIndexOf('/'), filename.lastIndexOf('\\'));
if (slash > -1) {
filename = filename.substring(slash + 1); // past last slash
}
if (filename.equals("")) filename = NO_FILE; // sanity check
} // Return a String array: disposition, name, filename
retval[0] = disposition;
retval[1] = name;
retval[2] = filename;
return retval;
} // Extracts and returns the content type from a line, or null if the
// line was empty. Throws an IOException if the line is malformatted.
//
private String extractContentType(String line) throws IOException {
String contentType = null; // Convert the line to a lowercase string
String origline = line;
line = origline.toLowerCase(); // Get the content type, if any
if (line.startsWith("content-type")) {
int start = line.indexOf(" ");
if (start == -1) {
throw new IOException("Content type corrupt: " + origline);
}
contentType = line.substring(start + 1);
}
else if (line.length() != 0) { // no content type, so should be empty
throw new IOException("Malformed line after disposition: " + origline);
} return contentType;
} private synchronized int getID()
{
ID++;
return ID;
}
}
// A class to hold information about an uploaded file.
//
class UploadedFile { private String filename;
private File file;
private String type; UploadedFile(String filename, File file, String type) {
this.filename = filename;
this.file = file;
this.type = type;
} public String getContentType() {
return type;
} public String getFilename() {
return filename;
} public File getFile() {
return file;
}
}
class MultipartInputStreamHandler { ServletInputStream in;
int totalExpected;
int totalRead = 0;
byte[] buf = new byte[8 * 1024]; public MultipartInputStreamHandler(ServletInputStream in,
int totalExpected) {
this.in = in;
this.totalExpected = totalExpected;
} // Reads the next line of input. Returns null to indicate the end
// of stream.
//
public String readLine() throws IOException {
StringBuffer sbuf = new StringBuffer();
int result;
String line; do {
result = this.readLine(buf, 0, buf.length); // this.readLine() does +=
if (result != -1) {
// sbuf.append(new String(buf, 0, result, "ISO-8859-1"));
sbuf.append(new String(buf, 0, result, "gb2312"));
}
} while (result == buf.length); // loop only if the buffer was filled if (sbuf.length() == 0) {
return null; // nothing read, must be at the end of stream
} sbuf.setLength(sbuf.length() - 2); // cut off the trailing \r\n
return sbuf.toString();
} public int readLine(byte b[], int off, int len) throws IOException {
if (totalRead >= totalExpected) {
return -1;
}
else {
if (len > (totalExpected - totalRead)) {
len = totalExpected - totalRead; // keep from reading off end
}
int result = in.readLine(b, off, len);
if (result > 0) {
totalRead += result;
}
return result;
}
}
}
class MacBinaryDecoderOutputStream extends FilterOutputStream { int bytesFiltered = 0;
int dataForkLength = 0; public MacBinaryDecoderOutputStream(OutputStream out) {
super(out);
} public void write(int b) throws IOException {
// Bytes 83 through 86 are a long representing the data fork length
// Check <= 86 first to short circuit early in the common case
if (bytesFiltered <= 86 && bytesFiltered >= 83) {
int leftShift = (86 - bytesFiltered) * 8;
dataForkLength = dataForkLength | (b & 0xff) << leftShift;
}
// Bytes 128 up to (128 + dataForkLength - 1) are the data fork
else if (bytesFiltered < (128 + dataForkLength) && bytesFiltered >= 128) {
out.write(b);
}
bytesFiltered++;
} public void write(byte b[]) throws IOException {
write(b, 0, b.length);
} public void write(byte b[], int off, int len) throws IOException {
// If the write is for content past the end of the data fork, ignore
if (bytesFiltered >= (128 + dataForkLength)) {
bytesFiltered += len;
}
// If the write is entirely within the data fork, write it directly
else if (bytesFiltered >= 128 &&
(bytesFiltered + len) <= (128 + dataForkLength)) {
out.write(b, off, len);
bytesFiltered += len;
}
// Otherwise, do the write a byte at a time to get the logic above
else {
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
}
}