📄 multipartiterator.java
字号:
/**
* Set the maximum post data size allowed for a multipart request
* @param maxSize The maximum post data size in bytes, set to <code>-1</code>
* for no limit
*/
public void setMaxSize(long maxSize) {
this.maxSize = maxSize;
}
/**
* Get the maximum post data size allowed for a multipart request
* @return The maximum post data size in bytes
*/
public long getMaxSize() {
return maxSize;
}
/**
* Handles retrieving the boundary and setting the input stream
*/
protected void parseRequest() throws ServletException {
contentLength = request.getContentLength();
//set boundary
boundary = parseBoundary(request.getContentType());
boundaryBytes = boundary.getBytes();
try {
//set the input stream
inputStream = new BufferedMultipartInputStream(request.getInputStream(),
bufferSize,
contentLength,
maxSize);
//mark the input stream to allow multiple reads
if (inputStream.markSupported()) {
inputStream.mark(contentLength+1);
}
}
catch (IOException ioe) {
throw new ServletException("Problem while reading request: " +
ioe.getMessage(), ioe);
}
if ((boundary == null) || (boundary.length() < 1)) {
//try retrieving the header through more "normal" means
boundary = parseBoundary(request.getHeader("Content-type"));
}
if ((boundary == null) || (boundary.length() < 1)) {
throw new ServletException("MultipartIterator: cannot retrieve boundary " +
"for multipart request");
}
//read first line
try {
String firstLine = readLine();
if (firstLine == null) {
throw new ServletException("MultipartIterator: no multipart request data " +
"sent");
}
if (!firstLine.startsWith(boundary)) {
throw new ServletException("MultipartIterator: invalid multipart request " +
"data, doesn't start with boundary");
}
}
catch (UnsupportedEncodingException uee) {
throw new ServletException("MultipartIterator: encoding \"ISO-8859-1\" not supported");
}
}
/**
* Parses a content-type String for the boundary. Appends a
* "--" to the beginning of the boundary, because thats the
* real boundary as opposed to the shortened one in the
* content type.
*/
public static String parseBoundary(String contentType) {
if (contentType.lastIndexOf("boundary=") != -1) {
String _boundary = "--" +
contentType.substring(contentType.lastIndexOf("boundary=")+9);
if (_boundary.endsWith("\n")) {
//strip it off
return _boundary.substring(0, _boundary.length()-1);
}
return _boundary;
}
return null;
}
/**
* Parses the "Content-Type" line of a multipart form for a content type
*
* @param contentTypeString A String reprsenting the Content-Type line,
* with a trailing "\n"
* @return The content type specified, or <code>null</code> if one can't be
* found.
*/
public static String parseContentType(String contentTypeString) {
int nameIndex = contentTypeString.indexOf("Content-Type: ");
if (nameIndex == -1)
nameIndex = contentTypeString.indexOf("\n");
if (nameIndex != -1) {
int endLineIndex = contentTypeString.indexOf("\n");
if (endLineIndex == -1) {
endLineIndex = contentTypeString.length()-1;
}
return contentTypeString.substring(nameIndex+14, endLineIndex);
}
return null;
}
/**
* Retrieves the "name" attribute from a content disposition line
*
* @param dispositionString The entire "Content-disposition" string
* @return <code>null</code> if no name could be found, otherwise,
* returns the name
* @see #parseForAttribute(String, String)
*/
public static String parseDispositionName(String dispositionString) {
return parseForAttribute("name", dispositionString);
}
/**
* Retrieves the "filename" attribute from a content disposition line
*
* @param dispositionString The entire "Content-disposition" string
* @return <code>null</code> if no filename could be found, otherwise,
* returns the filename
* @see #parseForAttribute(String, String)
*/
public static String parseDispositionFilename(String dispositionString) {
return parseForAttribute("filename", dispositionString);
}
/**
* Parses a string looking for a attribute-value pair, and returns the value.
* For example:
* <pre>
* String parseString = "Content-Disposition: filename=\"bob\" name=\"jack\"";
* MultipartIterator.parseForAttribute(parseString, "name");
* </pre>
* That will return "bob".
*
* @param attribute The name of the attribute you're trying to get
* @param parseString The string to retrieve the value from
* @return The value of the attribute, or <code>null</code> if none could be found
*/
public static String parseForAttribute(String attribute, String parseString) {
int nameIndex = parseString.indexOf(attribute + "=\"");
if (nameIndex != -1) {
int endQuoteIndex = parseString.indexOf("\"", nameIndex+attribute.length()+3);
if (endQuoteIndex != -1) {
return parseString.substring(nameIndex+attribute.length()+2, endQuoteIndex);
}
return "";
}
return null;
}
/**
* Reads the input stream until it reaches a new line
*/
protected String readLine() throws ServletException, UnsupportedEncodingException {
byte[] bufferByte;
int bytesRead;
if (totalLength >= contentLength) {
return null;
}
try {
bufferByte = inputStream.readLine();
if (bufferByte == null)
return null;
bytesRead = bufferByte.length;
}
catch (IOException ioe) {
throw new ServletException("IOException while reading multipart request: " +
ioe.getMessage());
}
if (bytesRead == -1) {
return null;
}
totalLength += bytesRead;
return new String(bufferByte, 0, bytesRead, "ISO-8859-1");
}
/**
* Creates a file on disk from the current mulitpart element
* @param fileName the name of the multipart file
*/
protected File createLocalFile() throws IOException {
File tempFile = File.createTempFile("jaction", null, new File(tempDir));
BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(tempFile),
diskBufferSize);
byte[] lineBuffer = inputStream.readLine();
if (lineBuffer == null)
{
throw new IOException("Premature end of stream while reading multipart request");
}
int bytesRead = lineBuffer.length;
boolean cutCarriage = false;
boolean cutNewline = false;
try {
while ((bytesRead != -1) && (!equals(lineBuffer, 0, boundaryBytes.length,
boundaryBytes))) {
if (cutCarriage) {
fos.write('\r');
}
if (cutNewline) {
fos.write('\n');
}
cutCarriage = false;
if (bytesRead > 0) {
if (lineBuffer[bytesRead-1] == '\r') {
bytesRead--;
cutCarriage = true;
}
}
cutNewline = true;
fos.write(lineBuffer, 0, bytesRead);
lineBuffer = inputStream.readLine();
if (lineBuffer == null)
{
throw new IOException("Premature end of stream while reading multipart request");
}
bytesRead = lineBuffer.length;
}
}
catch (IOException ioe) {
fos.close();
tempFile.delete();
throw ioe;
}
fos.flush();
fos.close();
return tempFile;
}
/**
* Checks bytes for equality. Two byte arrays are equal if
* each of their elements are the same. This method checks
* comp[offset] with source[0] to source[length-1] with
* comp[offset + length - 1]
* @param comp The byte to compare to <code>source</code>
* @param offset The offset to start at in <code>comp</code>
* @param length The length of <code>comp</code> to compare to
* @param source The reference byte array to test for equality
*/
public static boolean equals(byte[] comp, int offset, int length,
byte[] source) {
if ((length != source.length) || (comp.length - offset < length)) {
return false;
}
for (int i = 0; i < length; i++) {
if (comp[offset+i] != source[i]) {
return false;
}
}
return true;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -