only with Servlet API, can not use apache or other those components , which experts have done a similar function and success, help !
I think it must have the means , or in the absence of those components when it came to how to do file upload needs .
------ Solution ---------------------------------------- ----
I am here to answer too .
http://bbs.csdn.net/topics/390154611
------ For reference only ---------------------------------- -----
UploadBytes What is this class
------ For reference only --------------------- ------------------
many examples online right
------ For reference only ------------ ---------------------------
really small basically use a third-party
--- --- For reference only ---------------------------------------
UploadBytes What is this class
is a utility class , as follows .
public class UploadBytes {
//文件名的标志位
public static final String SIGN_FILENAME = "filename=\"";
//表单域名称的标志位
public static final String FORM_NAME = "name=\"";
//以引号结束的标志位(文件名和表单域名称后的内容)
public static final String QUOTE_FLAG = "\"";
//含文件名的表单域的上传文件类型 Content-type
private final static String CONTENT_TYPE = "Content-Type:";
//自动换行符(上传文件类型名称后面的内容 实际上传文件内容之前的换行符)
private final static String AUTO_LINE = "\r\n\r\n";
private static final String SIGN_MULTIDATA = "multipart/form-data";
//默认编码
private final static String DEFAULT_ENCODING = "iso8859_1";
/**
* buff为当前已经读取的上传流字节
* boundary为HTTP头信息中的Content-Type指定的当前域的分隔符的字节数组
* 处理思想即找到一组成对的boundary,那么其中的字节即为表单域的数据.
* @param boundary 分隔符
* @param buff 输出流
* @return 各分隔符之间的字节列表
* @throws Exception
*/
public static List<byte[]> findFiled(byte[] boundary,
ByteArrayOutputStream buff)
throws Exception {
//当前的数据连成对的boundary长度都不够,直接返回。
if (buff.size() < boundary.length * 2) {
return Collections.emptyList();
} else {
byte[] data = buff.toByteArray();//当前数据
List<byte[]> fileds = new ArrayList<byte[]>();
int point = 0;//当前指针位置
int alertStart = 0;//最近一次警戒区的位置
boolean alert = false;//是否处于警戒区
int treated = 0;//已经处理的字节长度
while (true) {
if (!alert && data.length - point < boundary.length * 2) {
break;
} else if (alert && data.length - point < boundary.length) {
break;
}
if (isBytes(data, boundary, point)) {
if (!alert) { //start line
alert = true;
alertStart = point + boundary.length;
point = alertStart;
} else { //end line
byte[] filed;
filed = Arrays.copyOfRange(data, alertStart, point);
treated += (point - alertStart + boundary.length);
fileds.add(filed);
alert = false;
}
} else {
point++;
}
}
if (fileds.size() > 0) {
buff.reset();
buff.write(data, treated, data.length - treated);
return fileds;
}
return Collections.emptyList();
}
}
/**
* 根据解析上传文件的所有分隔符之间的字节数组列表
* 来获取各个文件上传的文件名所在表单域的字节数组列表
* 即含"filename="的表单域字节数组
* @param filesByte 所有分隔符之间的字节数组列表
* @param charset 上传文件的字符集
* @return 各个文件上传的文件名所在表单域的字节数组列表
*/
public static List<byte[]> getFilesByteList(
List<byte[]> filesByte, String charset)
throws UnsupportedEncodingException {
List<byte[]> fieldFilesByte = new ArrayList<byte[]>();
byte[] fileName = SIGN_FILENAME.getBytes(charset);
for (int i = 0; i < filesByte.size(); i++) {
byte[] bs = filesByte.get(i);
int point = 0;
while (true) {
if (bs.length - point < fileName.length) {
break;
}
if (isBytes(bs, fileName, point)) {
fieldFilesByte.add(bs);
break;
} else {
point++;
}
}
}
return fieldFilesByte;
}
/**
* 根据获取上传文件实际域的数据的字节 获取实际域数据
* @param fieldByte 实际域的数据的字节
* @param charset 上传文件的编码
* @return 实际域的数据
*/
public static Field getField(byte[] fieldByte, String charset)
throws UnsupportedEncodingException, IOException {
Field field = new Field();
String fileNameStr = getFieldStr(fieldByte, charset, SIGN_FILENAME,
QUOTE_FLAG);
field.setFieldName(fileNameStr);
String fileName = "";
if (fileNameStr != null && !fileNameStr.isEmpty()) {
fileName = getExtensionName(fileNameStr);
}
field.setFileName(fileName);
String fileType = getFieldStr(fieldByte, charset, CONTENT_TYPE,
AUTO_LINE);
field.setContentType(fileType);
byte[] realFileBytes = getRealFileByte(fieldByte, charset);
field.setFieldData(realFileBytes);
return field;
}
/**
* 根据域数据获取域中标志的名称
* @param fieldByte 域数据
* @param charset 编码
* @param nameFlag 名称的标志
* @param endFlag 以该标志位结束的内容
* @return 名称
*/
private static String getFieldStr(byte[] fieldByte, String charset,
String nameFlag, String endFlag)
throws UnsupportedEncodingException {
byte[] fileNameByte = nameFlag.getBytes(charset);
int point = 0;
while (true) {
if (fieldByte.length - point < fileNameByte.length) {
break;
}
if (isBytes(fieldByte, fileNameByte, point)) {
break;
} else {
point++;
}
}
int pos = point + fileNameByte.length;
//截取从名称开始到内容结束的部分的字节数组
byte[] fileStart = Arrays.copyOfRange(fieldByte, pos, fieldByte.length);
//从文件名开始 第一个引号 " 出现的位置 (即为文件名后面的第一个引号)
byte[] quoteBytes = endFlag.getBytes(charset);
int point1 = 0;
while (true) {
if (fileStart.length - point1 < quoteBytes.length) {
break;
}
if (isBytes(fileStart, quoteBytes, point1)) {
break;
} else {
point1++;
}
}
//名称开始到名称结束的字节数组
byte[] nameBytes = Arrays.copyOfRange(fieldByte, pos, pos + point1);
if (nameBytes == null || nameBytes.length == 0) {
return null;
}
String result = new String(nameBytes, charset);
//若结果前后含有空格,则去掉前后的空格
result = result.trim();
return result;
}
/**
* 根据带文件名的文件表单域字节获取实际要上传的字节内容
* @param fieldByte 带文件名的文件表单域字节
* @param charset 文件的字符集
* @return 实际要上传的字节内容
*/
public static byte[] getRealFileByte(byte[] fieldByte, String charset)
throws UnsupportedEncodingException, FileNotFoundException,
IOException {
//自动换行开始的位置
byte[] autoLineByte = AUTO_LINE.getBytes(charset);
int point = 0;
while (true) {
if (fieldByte.length - point < autoLineByte.length) {
break;
}
if (isBytes(fieldByte, autoLineByte, point)) {
break;
} else {
point++;
}
}
//上传文件的实际内容(自动换行结束的位置开始,内容的结束有一个换行符)
byte[] realFileByte = Arrays.copyOfRange(fieldByte,
point + autoLineByte.length, fieldByte.length - 2);
return realFileByte;
}
/**
* 比较源数据中是否有与给定的字节数组匹配的数据
* @param data 源数据
* @param byteGiven 要比较的数据
* @param point 当前指针所在的位置
* @return
*/
public static boolean isBytes(byte[] data, byte[] byteGiven, int point) {
for (int i = 0; i < byteGiven.length; i++) {
if (data[point + i] != byteGiven[i]) {
return false;
}
}
return true;
}
/**
* 获取上传文件的字符集
* @param request 请求
* @return 如果设置字符集的话 则返回字符集,否则 返回默认的字符集
*/
public static String getCharset(HttpServletRequest request) {
CharsetParser charsetParser = new CharsetParser();
String contentType = request.getContentType();
String charset = charsetParser.getCharset(contentType, ';');
if (charset == null || charset.isEmpty()) {
charset = DEFAULT_ENCODING;
}
return charset;
}
/**
* 获取请求的信息
* @param request 请求
* @return 请求信息byte数组
* @throws IOException
*/
public static byte[] getContentBytes(HttpServletRequest request) throws
IOException {
InputStream sis = request.getInputStream();
int dataLength = request.getContentLength();
//保存上传图片的数据
byte[] dataBytes = new byte[dataLength];
int byteRead = 0;
int totalBytes = 0;
//上传的数据保存在byte数组
while (totalBytes < dataLength) {
byteRead = sis.read(dataBytes, totalBytes, dataLength);
totalBytes += byteRead;
}
sis.close();
return dataBytes;
}
/**
* 取得数据的分隔字符串
* @param request 请求
* @return 数据的分隔字符串
*/
public static String getBoundaryStr(HttpServletRequest request) {
String contentType = request.getContentType();
int lastIndex = contentType.lastIndexOf("=");
//取得数据的分隔字符串
String boundaryStr = "--" + contentType.substring(lastIndex + 1,
contentType.length());
return boundaryStr;
}
/**
* 获取上传文件的扩展名
* @param fileName 文件名
* @return 文件名的扩展名
*/
public static String getExtensionName(String fileName) {
int format = fileName.lastIndexOf(".");
String extensionName = "";
if (format >= 0) {
extensionName = fileName.substring(format);
}
return extensionName;
}
/**
* 判断上传文件类型,如果是multipart/form-data,则返回true,否则返回fase
* @param request 请求
* @return boolean
*/
public static boolean getContentTypeFlag(HttpServletRequest request) {
String contentType = request.getContentType();
if (contentType != null && !contentType.isEmpty()) {
if (contentType.indexOf(SIGN_MULTIDATA) >= 0) {
return true;
}
}
return false;
}
}
------ For reference only ---------------------------------- -----
search servlet bulk upload more than N it ! !
------ For reference only -------------------------------------- -
can be found to also be used in this help ?
------ For reference only -------------------------------------- -
UploadBytes What is this class
is a utility class , as follows .
You 've done the same function right, I follow your post in the request that information , the string analysis, the results will come out , but the Chinese garbled, you come across it
----- - For reference only ---------------------------------------
stay mailboxes ; send items to you
------ For reference only -------------------------------- -------
I realized , though your code though useless , but the thing I read is to read the post request information only to achieve, in the Whole to you !
没有评论:
发表评论