📄 fileupload.java
字号:
/*
* FileUpload.java
*
* Created on 2004年12月26日, 上午10:24
* 这个类用于上传文件
*
*/
package com.mg.admin;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.*;
import java.io.*;
/**
*这个类用于上传文件
*/
class FileUpload {
//----------------------------------------------------类方法
/**
* 判断request中是否包含multipart请求
*
* @param req Servlet的request请求,不能为null.
*
* @return <code>true</code> 如果请求是multipart;
* <code>false</code> 如果不是multipart。
*/
public static final boolean isMultipartContent(HttpServletRequest req) {
String contentType = req.getHeader(CONTENT_TYPE);
if (contentType == null) {
return false;
}
if (contentType.startsWith(MULTIPART)) {
return true;
}
return false;
}
// ----------------------------------------------------- Manifest常量
/**
* HTTP内容头:Content-type.
*/
public static final String CONTENT_TYPE = "Content-type";
/**
* HTTP内容头:disposition.
*/
public static final String CONTENT_DISPOSITION = "Content-disposition";
/**
* HTTP内容头:form data.
*/
public static final String FORM_DATA = "form-data";
/**
* HTTP内容头:attachment.
*/
public static final String ATTACHMENT = "attachment";
/**
* HTTP内容头:multipart.
*/
public static final String MULTIPART = "multipart/";
/**
* HTTP内容头:multipart forms.
*/
public static final String MULTIPART_FORM_DATA = "multipart/form-data";
/**
* HTTP内容头:multiple uploads.
*/
public static final String MULTIPART_MIXED = "multipart/mixed";
/**
* 最大解析长度(1024 bytes).
*/
public static final int MAX_HEADER_SIZE = 1024;
// ----------------------------------------------------------- Data members
/**
* 最大允许上传大小
*/
private long sizeMax = -1;
/**
* 编码类型.
*/
private String headerEncoding;
// ----------------------------------------------------------- 构造函数
/**
* Constructs an instance of this class which uses the default factory to
* create <code>FileItem</code> instances.
*
* @see #FileUpload(FileItemFactory)
*/
public FileUpload() {
}
// ----------------------------------------------------- Property accessors
/**
* 返回最大允许上传大小
*
* @return 最大允许上传大小。
*
* @see #setSizeMax(long)
*
*/
public long getSizeMax() {
return sizeMax;
}
/**
* 设置最大允许上传大小,如果为小于0,则没有限制
* <p>
* @param sizeMax 最大的上传大小, 如果为 -1表示没有限制。
*
* @see #getSizeMax()
*
*/
public void setSizeMax(long sizeMax) {
this.sizeMax = sizeMax;
}
/**
* 返回编码类型
*
* @return 编码类型.
*/
public String getHeaderEncoding() {
return headerEncoding;
}
/**
* 设置编码类型,如果不指定,则使用缺省的编码
*
* @param encoding 编码类型。
*/
public void setHeaderEncoding(String encoding) {
headerEncoding = encoding;
}
// --------------------------------------------------------- Public methods
/**
* 解析request对象,返回Picture对象列表
*
* @param req 要解析的Request对象。
*
* @return 返回Picture对象列表
*
*/
public List /* Picture */ parseRequest(HttpServletRequest req,
long sizeMax, String targetPath) {
ArrayList items = new ArrayList();
setSizeMax(sizeMax);
//有效性检查
if (req==null) {
return items;
}
String contentType = req.getHeader(CONTENT_TYPE);
if ((contentType==null) || (!contentType.startsWith(MULTIPART))) {
return items;
}
int requestSize = req.getContentLength();
if (requestSize == -1) {
return items;
}
if (sizeMax >= 0 && requestSize > sizeMax) {
return items;
}
//开始解析
try {
int boundaryIndex = contentType.indexOf("boundary=");
if (boundaryIndex < 0) {
return items;
}
byte[] boundary = contentType.substring(
boundaryIndex + 9).getBytes();
InputStream input = req.getInputStream();
MultipartStream multi = new MultipartStream(input, boundary);
multi.setHeaderEncoding(headerEncoding);
Picture singlePicture = new Picture();
boolean nextPart = multi.skipPreamble();
while (nextPart) {
Map headers = parseHeaders(multi.readHeaders());
String fieldName = getFieldName(headers);
if (fieldName != null) {
String subContentType = getHeader(headers, CONTENT_TYPE);
if (subContentType != null && subContentType
.startsWith(MULTIPART_MIXED)) {
//处理多个文件
byte[] subBoundary = subContentType.substring(
subContentType.indexOf("boundary=") + 9).
getBytes();
multi.setBoundary(subBoundary);
boolean nextSubPart = multi.skipPreamble();
while (nextSubPart) {
headers = parseHeaders(multi.readHeaders());
String filename = getFileName(headers);
if (filename!= null) {
Picture picture = new Picture();
OutputStream os=picture.getOutputStream(filename,
sizeMax);
try {
multi.readBodyData(os);
} finally {
os.close();
}
items.add(picture);
} else {
//如果文件名无效,则忽略该部分
multi.discardBodyData();
}
nextSubPart = multi.readBoundary();
}
multi.setBoundary(boundary);
} else {
String filename = getFileName(headers);
if (filename != null) {
// 上传单一的文件
OutputStream os=singlePicture.getOutputStream(
filename,
sizeMax);
try {
multi.readBodyData(os);
} finally {
os.close();
}
items.add(singlePicture);
} else {
//出来域值
if (getFieldName(headers).equals("title")) {
OutputStream os = new ByteArrayOutputStream();
try {
multi.readBodyData(os);
} finally {
os.close();
}
singlePicture.setTitle(os.toString());
}
}
}
} else {
// Skip this part.
multi.discardBodyData();
}
nextPart = multi.readBoundary();
}
} catch (IOException e) {
//throw new FileUploadException(
}
return items;
}
// ------------------------------------------------------ Protected methods
/**
* 返回上传的文件名
*
* @param headers 包含了headers的Map对象。
*
* @return 当前的文件名。
*/
protected String getFileName(Map headers) {
String fileName = null;
String cd = getHeader(headers, CONTENT_DISPOSITION);
if (cd.startsWith(FORM_DATA) || cd.startsWith(ATTACHMENT)) {
int start = cd.indexOf("filename=\"");
int end = cd.indexOf('"', start + 10);
if (start != -1 && end != -1) {
fileName = cd.substring(start + 10, end).trim();
}
}
return fileName;
}
/**
* 返回域名
*
* @param headers 包含了headers的Map对象。
*
* @return 当前的域名。
*/
protected String getFieldName(Map headers) {
String fieldName = null;
String cd = getHeader(headers, CONTENT_DISPOSITION);
if (cd != null && cd.startsWith(FORM_DATA)) {
int start = cd.indexOf("name=\"");
int end = cd.indexOf('"', start + 6);
if (start != -1 && end != -1) {
fieldName = cd.substring(start + 6, end);
}
}
return fieldName;
}
/**
* <p> 解析<code>header-part</code>,并将解析内容以key/value形式保存在
* Map对象中。
*
* <p> 一个名字如果有多个头,则以逗号分开。
*
* @param headerPart 要解析的<code>header-part</code>字符串。
*
* @return 返回头,以key/value形式保存在<code>Map</code>对象中。
*/
protected Map parseHeaders(String headerPart){
Map headers = new HashMap();
char buffer[] = new char[MAX_HEADER_SIZE];
boolean done = false;
int j = 0;
int i;
String header, headerName, headerValue;
try {
while (!done) {
i = 0;
// 复制一行,忽略结尾的回车CRLF.
while (i < 2 || buffer[i - 2] != '\r' ||
buffer[i - 1] != '\n') {
buffer[i++] = headerPart.charAt(j++);
}
header = new String(buffer, 0, i - 2);
if (header.equals("")) {
done = true;
} else {
if (header.indexOf(':') == -1) {
// 如果无效则跳过
continue;
}
headerName = header.substring(0,
header.indexOf(':')).trim().toLowerCase();
headerValue =
header.substring(header.indexOf(':') + 1).trim();
if (getHeader(headers, headerName) != null) {
headers.put(headerName,
getHeader(headers, headerName) + ','
+ headerValue);
} else {
headers.put(headerName, headerValue);
}
}
}
} catch (IndexOutOfBoundsException e) {
// Headers were malformed. continue with all that was
// parsed.
}
return headers;
}
/**
* 返回指定的头内容
*
* @param headers <code>Map</code>对象,包含了所有的请求头。
* @param name 要返回的头的名字。
*
* @return 指定头的值,如果该名字有多个头,则返回以逗号分开的列表。
*/
protected String getHeader(Map headers, String name) {
return (String) headers.get(name.toLowerCase());
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -