📄 uploadreader.java
字号:
/*****************************************************************************
* (C) Copyright 2004 。
* 保留对所有使用、复制、修改和发布整个软件和相关文档的权利。
* 本计算机程序受著作权法和国际公约的保护,未经授权擅自复制或
* 传播本程序的全部或部分,可能受到严厉的民事和刑事制裁,并
* 在法律允许的范围内受到最大可能的起诉。
*/
/*****************************************************************************
* @作者:Golden Peng
* @版本: 1.0
* @时间: 2002-10-08
*/
/*****************************************************************************
* 修改记录清单
* 修改人 :
* 修改记录:
* 修改时间:
* 修改描述:
*
*/
package com.corp.bisc.ebiz.util;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.corp.bisc.ebiz.exception.*;
/**
* UploadReader用于处理上传文件的http请求。
*
* 在上传文件的http请求中,表单内容(包括上传的文件)是用multipart/form-data
* 的格式封装的。UploadReader提供方法从multipart/form-data格式中取出客户提
* 交过来的参数。
*
* 下面是一个用于上传文件和参数的表单的例子:
* <br>
*<html><head><title>Upload Test Form</title></head><br>
*<body><br>
*<form name = "frmTest" method = "post" action = "/servlet/upload.test"<br>
*enctype = "multipart/form-data"><br>
*<input type = "text" name = "txt1"><br><br>
*<input type = "file" name = "file1"><br><br>
*<input type = "text" name = "txt2"><br><br>
*<input type = "file" name = "file2"><br><br>
*<input type = "submit"><br>
*</form><br>
*</body><br>
*</html>
*
* 上传过来的数据划分为多个部分,每个部分包含两段,参数头段和正文段,代表提
* 交来的表单内的一个参数。
* 参数头段说明了参数的名称。如果参数是一个上传的文件,则头段内还包含其文件名
* 以及文件类型。
* 正文段包含的参数值。如果参数是一个上传的文件,则正文段包含了整个文件。
* 因此,利用UploadReader提取参数的过程为:
* 1.调用getHeader()读取参数头段,获得参数名,判断该参数是否为上传的文件
* 2.如果该参数不是上传的文件,调用getParamValue()从正文段中获取参数值
* 3.如果该参数是上传的文件,调用getBodyChar()从正文段中读取文件字节,直到
* getBodyChar()返回UploadReader.EOF。
* 4.回到第1步,处理下一个参数。
*
* 下面是一个完整的处理文件上传的例子。该例子将http请求带过来的所有参数、文件
* 名用表格显示出来,并将上传过来的文件保存在c:\temp目录下。http请求中可以包含
* 任意数目的参数及文件。
* <code><br>
* try {<br>
* int c;<br>
* MultipartHeader multipartHeader;<br>
* UploadReader uploadReader = new UploadReader(request);<br>
* FileOutputStream foStream;
* <p> response.setContentType("text/html");<br>
* PrintWriter out = response.getWriter();<br>
* out.println("<html><head><title>Result of Upload Test</title></head>");<br>
* out.println("<body>");<br>
* out.println("<table border=1 width=100%>");<br>
* out.println("<tr><th>Type</th><th>Name</th><th>Value</th></tr>");</p>
* <p> while ((multipartHeader = uploadReader.getHeader()) != null) {<br>
* out.println("<tr>");</p>
* <p> if (multipartHeader.isFile()) {<br>
* out.println("<td>File</td>");<br>
* out.println("<td>" + multipartHeader.getParamName() + "</td>");<br>
* out.println("<td>" + multipartHeader.getFileName() + "</td>");</p>
* <p> if (multipartHeader.getFileName().compareTo("") != 0) {<br>
* //create a local file for saving uploaded file<br>
* foStream = <br>
* new FileOutputStream(<br>
* "c:\\temp"<br>
* + multipartHeader.getFileName().substring(<br>
* multipartHeader.getFileName().lastIndexOf("\\"))); <br>
* //save uploaded file<br>
* while ((c = uploadReader.getBodyChar()) != UploadReader.EOF) {<br>
* foStream.write(c);<br>
* }<br>
* foStream.close();<br>
* } else {<br>
* uploadReader.skipFile();<br>
* }<br>
* } else {<br>
* out.println("<td>Param</td>");<br>
* out.println("<td>" + multipartHeader.getParamName() + "</td>");<br>
* out.println("<td>" + uploadReader.getParamValue() + "</td>");<br>
* }<br>
* out.println("</tr>");<br>
* }<br>
* out.println("</table>");<br>
* out.println("</body>");<br>
* out.println("</html>");<br>
* out.close();<br>
* } catch (Throwable theException) {<br>
* System.out.println(theException);<br>
* }</p>
* </code>
*
* @author: Jim, Yang Jiang Ming
*/
public class UploadReader {
class UploadReaderInputStream extends InputStream {
UploadReader m_reader;
public UploadReaderInputStream(UploadReader reader) {
m_reader = reader;
}
public int read() throws IOException {
int c;
try {
c = m_reader.getBodyChar();
if (c < 0) {
c += 256;
}
if (c == UploadReader.EOF) {
c = -1;
}
return c;
}
catch(UploadReaderException e) {
throw new IOException(e.toString());
}
}
}
//{ constants for buffer status
protected final static int BUFFER_STATUS_HEADER = 10;
protected final static int BUFFER_STATUS_BODY = 20;
protected final static int BUFFER_STATUS_FILE = 30;
protected final static int BUFFER_STATUS_VALUE = 40;
protected final static int BUFFER_STATUS_END = 50;
protected final static int BUFFER_STATUS_ERROR = 60;
//}
protected final static int BUFFER_SIZE = 1024000;
protected final static int BOUNDARY_SIZE = 1024;
protected final static int SAFE_SIZE = BUFFER_SIZE - BOUNDARY_SIZE;
public final static int EOF = 255;
/** input stream */
protected ServletInputStream m_is;
/** indicates whether the m_is has came to end */
protected boolean m_bEndOfIs;
/** indicate whether the post parameters are sent in multi-part format */
protected boolean m_bIsMultipart;
/** boundary for multipart data */
protected String m_strBoundary;
/** boundary for multipart data in byte array*/
protected byte[] m_baBoundary;
/** buffer for multipart data */
protected byte[] m_baBuffer;
/** pointer to next byte to read in buffer */
protected int m_iPtr;
/** pointer to last available bye in buffer */
protected int m_iEndPtr;
/** buffer status */
protected int m_iBufferStatus;
/** temporary byte array */
protected byte[] m_baTemp = new byte[1024];
/**
* 构造函数
* @param request http请求
*/
public UploadReader(HttpServletRequest request)
throws UploadReaderException, IOException {
super();
m_bEndOfIs = false;
m_baBuffer = new byte[BUFFER_SIZE];
m_iPtr = -1;
m_iEndPtr = BUFFER_SIZE;
m_is = request.getInputStream();
//{is the request data in multipart format?
if (request.getMethod().equals("POST")
&& request.getContentType().startsWith("multipart/form-data")) {
m_bIsMultipart = true;
} else {
m_bIsMultipart = false;
}
//}
if (m_bIsMultipart) {
//{get boundary string
int index = request.getContentType().indexOf("boundary=");
if (index < 0) {
throw new UploadReaderException("Cannot get boundary.");
}
m_strBoundary = "--" + request.getContentType().substring(index + 9);
m_baBoundary = m_strBoundary.getBytes();
//}
readInBuffer();
}
}
/**
* 从上传的文件中读取一个字节。
* @return int 如果为UploadReader.EOF,表示文件已经读完。
*/
public int getBodyChar() throws UploadReaderException, IOException {
int i;
if (m_iPtr >= SAFE_SIZE)
readInBuffer();
if (m_iPtr >= m_iEndPtr)
throw new UploadReaderException("End of input stream.");
//must in body
if (!(m_iBufferStatus == BUFFER_STATUS_VALUE
|| m_iBufferStatus == BUFFER_STATUS_FILE))
throw new UploadReaderException("Not in body");
if (m_baBuffer[m_iPtr] == 0x0d
&& m_baBuffer[m_iPtr + 1] == 0x0a) { //check if encounter the end of body
for (i = 0; i < m_baBoundary.length; i++) {
if (m_baBuffer[m_iPtr + 2 + i] != m_baBoundary[i])
break;
}
if (i == m_baBoundary.length) {
m_iPtr += 2;
//change status
if (m_baBuffer[m_iPtr + m_baBoundary.length] == '-'
&& m_baBuffer[m_iPtr + m_baBoundary.length + 1] == '-') { //end of buffer
m_iBufferStatus = BUFFER_STATUS_END;
m_iPtr += m_baBoundary.length + 2;
} else {
m_iBufferStatus = BUFFER_STATUS_HEADER;
}
return EOF;
}
}
return m_baBuffer[m_iPtr++];
}
public InputStream getBodyInputStream() throws UploadReaderException {
if (!(m_iBufferStatus == BUFFER_STATUS_VALUE
|| m_iBufferStatus == BUFFER_STATUS_FILE))
throw new UploadReaderException("Not in body");
return new UploadReaderInputStream(this);
}
/**
* 读取头段。
* @return MultipartHeader 头段说明
*/
public MultipartHeader getHeader() throws UploadReaderException, IOException {
int i, j;
if (m_iBufferStatus == BUFFER_STATUS_END) {
return null;
}
if (m_iBufferStatus != BUFFER_STATUS_HEADER) {
throw new UploadReaderException("Not in header.");
}
MultipartHeader multipartHeader = new MultipartHeader();
String strTemp = readHeaderLine();
if (strTemp.compareTo(m_strBoundary) != 0) {
throw new UploadReaderException("Error in header: expect boundary.");
}
strTemp = readHeaderLine();
//{get param name
i = strTemp.indexOf("name=");
j = strTemp.indexOf("\"", i + 6);
multipartHeader.setParamName(strTemp.substring(i + 6, j));
//}
//{get file name and content type when this is a header for a file
i = strTemp.indexOf("filename=");
if (i > 0) { //file name exist
//{get file name
j = strTemp.indexOf("\"", i + 10);
multipartHeader.setFileName(strTemp.substring(i + 10, j));
multipartHeader.setIsFile(true);
//}
//{get content type
strTemp = readHeaderLine();
if (!strTemp.startsWith("Content-Type: ")) {
throw new UploadReaderException("No content type.");
}
multipartHeader.setContentType(strTemp.substring(14));
//}
} else {
multipartHeader.setIsFile(false);
}
//}
//{skip remaining header lines
while (m_iBufferStatus == BUFFER_STATUS_HEADER) {
strTemp = readHeaderLine();
}
//}
if (multipartHeader.isFile()) {
m_iBufferStatus = BUFFER_STATUS_FILE;
} else {
m_iBufferStatus = BUFFER_STATUS_VALUE;
}
return multipartHeader;
}
/**
* 从正文段中读取参数值。
* @return java.lang.String 参数值
*/
public String getParamValue() throws UploadReaderException, IOException {
StringBuffer sb = new StringBuffer("");
byte[] baTemp = new byte[BOUNDARY_SIZE];
int i, j = 0;
if (m_iBufferStatus != BUFFER_STATUS_VALUE) //not in value body
throw new UploadReaderException("Not in value");
i = getBodyChar();
while (i != EOF) {
baTemp[j++] = (byte) i;
i = getBodyChar();
if (j == BOUNDARY_SIZE) {
sb.append(new String(baTemp, 0, j));
j = 0;
}
}
if (j == 0) {
return sb.toString();
}
return sb.append(new String(baTemp, 0, j)).toString();
}
protected boolean isEndOfBuffer() {
return m_iPtr >= m_iEndPtr;
}
/**
* 判断请求是否用multipart/form-data的格式传递参数的。
* @return boolean
*/
public boolean isMultipart() {
return m_bIsMultipart;
}
protected synchronized String readHeaderLine()
throws UploadReaderException, IOException {
int i = 0;
//must in header
if (m_iBufferStatus != BUFFER_STATUS_HEADER)
throw new UploadReaderException("Not in header");
readInBuffer();
if (isEndOfBuffer()) //end of buffer
throw new UploadReaderException("Error in header");
while (true) {
if (m_baBuffer[m_iPtr] == 0x0d
&& m_baBuffer[m_iPtr + 1] == 0x0a) { //end of line
m_baTemp[i] = 0;
m_iPtr += 2;
break;
}
m_baTemp[i++] = m_baBuffer[m_iPtr++];
if (isEndOfBuffer()) //end of buffer
throw new UploadReaderException("Error in header.");
}
if (m_baBuffer[m_iPtr] == 0x0d
&& m_baBuffer[m_iPtr + 1] == 0x0a) { //end of header
m_iPtr += 2;
m_iBufferStatus = BUFFER_STATUS_BODY;
}
return new String(m_baTemp, 0, i);
}
protected boolean readInBuffer() throws IOException {
int i, j;
//must in multi-part mode
if (!isMultipart())
return false;
if (m_bEndOfIs)
return false;
if (m_iPtr < 0) { //read first time
m_iPtr = 0;
m_iEndPtr = readInBuffer(m_is, m_baBuffer, 0);
if (m_iEndPtr < BUFFER_SIZE) {
m_bEndOfIs = true;
}
//ready to read header information
m_iBufferStatus = BUFFER_STATUS_HEADER;
} else { //not first time
if (m_iPtr < SAFE_SIZE)
//pointer not exceed boundary yet
return false;
//move the end of buffer to the beginning
for (i = 0, j = SAFE_SIZE; i < BOUNDARY_SIZE; i++, j++)
m_baBuffer[i] = m_baBuffer[j];
//{set pointers after move
m_iPtr -= (SAFE_SIZE);
if (m_iEndPtr < BUFFER_SIZE) {
m_iEndPtr -= (SAFE_SIZE);
return true;
}
//}
if (m_bEndOfIs) //no data to read
return false;
m_iEndPtr = readInBuffer(m_is, m_baBuffer, BOUNDARY_SIZE);
if (m_iEndPtr < BUFFER_SIZE) {
m_bEndOfIs = true;
}
}
return true;
}
static protected int readInBuffer(InputStream is, byte[] ba, int iFrom) throws IOException {
int iLeft = ba.length - iFrom;
while (iLeft != 0) {
int iLen = is.read(ba, iFrom, iLeft);
if (iLen == -1) {
return iFrom;
} else {
iFrom = iFrom + iLen;
iLeft = iLeft - iLen;
}
}
return iFrom;
}
/**
* 跳过正文段中的文件。
*/
public void skipFile() throws UploadReaderException, IOException {
while(m_iBufferStatus == BUFFER_STATUS_FILE) {
getBodyChar();
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -