⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 multipartrequest.java

📁 Jodd是一个开源的公用Java基础类库
💻 JAVA
字号:
package jodd.servlet;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;

import javax.servlet.http.HttpServletRequest;

/**
 * Handles multipart requests and extract uploaded files and parameters from
 * it. Multipart forms should be defined as:
 * <p>
 *
 * <code>
 * &lt;form method="post" enctype="multipart/form-data" accept-charset="<i>charset</i>"...
 * </code>
 *
 * <p>
 * "accept-charset" should be used in case when jsp page uses specific
 * encoding. If dfault encoding is used, this attribute is not required.
 *
 * <p>
 * This class loads complete request. To prevent big uploads (and potential
 * DoS attacks) check content length <b>before</b> using this class.
 */
public class MultipartRequest {

	private Hashtable requestParameters;

	private Hashtable requestFiles;

	/**
	 * Default constructor, for using MultipartRequest in steps.
	 */
	public MultipartRequest() {
	}

	/**
	 * Constructor that loads request and extracts all uploaded files and
	 * parameters using specified encoding. If request is not multipart, all
	 * parameters will be read, anyway.
	 *
	 * @param request  http request
	 * @param encoding encoding
	 *
	 * @exception IOException
	 */
	public MultipartRequest(HttpServletRequest request, String encoding) throws IOException {
		load(request, encoding);
	}

	/**
	 * Constructor that loads request and extracts all uploaded files and
	 * parameters without encoding.
	 *
	 * @param request http request
	 *
	 * @exception IOException
	 * @see #MultipartRequest(HttpServletRequest, String)
	 */

	public MultipartRequest(HttpServletRequest request) throws IOException {
		load(request);
	}


	/**
	 * Loads http request manually without encoding.
	 *
	 * @param request http request.
	 *
	 * @exception IOException
	 * @see #load(HttpServletRequest, String)
	 */
	public void load(HttpServletRequest request) throws IOException {
		load(request, null);
	}

	/**
	 * Loads http request manually, with susing of specific encoding. If request
	 * is not multipart, all parameters will be read, anyway.
	 *
	 * @param request  http request.
	 * @param encoding encoding that will be used during extracting
	 *
	 * @exception IOException
	 */
	public void load(HttpServletRequest request, String encoding) throws IOException {

		if (ServletUtil.isRequestMultipart(request) == true) {
			byte[] requestData = getRequestData(request);
			Hashtable[] maps = extractParameters(requestData, encoding);
			requestParameters = maps[0];
			requestFiles = maps[1];
		} else {
			requestParameters = new Hashtable();
			requestFiles = new Hashtable();
			Enumeration names = request.getParameterNames();
			while (names.hasMoreElements()) {
				String paramName = (String) names.nextElement();
				String[] values = request.getParameterValues(paramName);
				requestParameters.put(paramName, values);
			}
		}
	}


	/**
	 * Returns value of a parameter.
	 *
	 * @param paramName parameter name
	 *
	 * @return parameer value, or <code>null</code> if not found
	 */
	public String getParameter(String paramName) {
		String[] values = (String[]) requestParameters.get(paramName);
		if ((values != null) && (values.length > 0)) {
			return (String) values[0];
		}
		return null;
	}
	/**
	 * Returns names of all availiable parameters.
	 *
	 * @return enumeration of all parameters names
	 */
	public Enumeration getParameterNames() {
		return requestParameters.keys();
	}

	public String[] getParameterValues(String paramName) {
		return (String[]) requestParameters.get(paramName);
	}


	/**
	 * Returns uploaded file.
	 *
	 * @param paramName parameter name of the uploaded file
	 *
	 * @return uploaded file or <code>null</code> if parameter name not found
	 */
	public UploadedFile getUploadedFile(String paramName) {
		return (UploadedFile) requestFiles.get(paramName);
	}

	/**
	 * Returns parameter names of all uploaded files.
	 *
	 * @return enumeration of all uploaded files parameter names
	 */
	public Enumeration getUploadedFileNames() {
		return requestFiles.keys();
	}


	// ---------------------------------------------------------------- load and extract

	/**
	 * Loads request data into a byte array.
	 *
	 * @param request http request
	 *
	 * @return byte array containing request data
	 * @exception IOException
	 */
	public static byte[] getRequestData(HttpServletRequest request) throws IOException {
		int totalBytes = request.getContentLength();
		byte[] binArray = new byte[totalBytes];
		int readBytes = 0;
		try {
			for (int totalRead = 0; totalRead < totalBytes; totalRead += readBytes) {
				readBytes = request.getInputStream().read(binArray, totalRead, totalBytes - totalRead);
			}
		} catch (Exception e) {
			throw new IOException("Upload error.");
		}
		return binArray;
	}

	/**
	 * Extracts uploaded files and parameters from the request data, not using
	 * any encoding.
	 *
	 * @param binArray binarry array of loaded request data
	 *
	 * @return array with two Hashtables that contains parameters and uploaded files
	 * @see #getRequestData
	 * @see #extractParameters(byte[], String)
	 */
	public static Hashtable[] extractParameters(byte[] binArray) {
		return extractParameters(binArray, null);
	}

	/**
	 * Extracts uploaded files and parameters from the request data. The result
	 * is returned as array of two Hashtables. The first one contains parameter
	 * data, and the second one contains uploaded file data.
	 *
	 * @param binArray binarry array of loaded request data
	 * @param encoding encoding for parameters, if <code>null</code> encoding will not be used
	 *
	 * @return array with two Hashtables that contains parameters and uploaded files
	 * @see #getRequestData
	 */
	public static Hashtable[] extractParameters(byte[] binArray, String encoding) {
		if (binArray == null) {
			return null;
		}
		Hashtable parameters = new Hashtable();
		Hashtable files = new Hashtable();
		int totalBytes = binArray.length;
		int currentIndex = 0;
		StringBuffer boundary = new StringBuffer();
		while (currentIndex < totalBytes) {
			if (binArray[currentIndex] == 13) {
				break;
			}
			boundary.append((char)binArray[currentIndex]);
			currentIndex++;
		}
		if (currentIndex == 1) {
			return null;
		}
		currentIndex++;

		while (currentIndex < totalBytes) {
			
			/* data header */
			int start = currentIndex;
			String dataHeader = null;
			while (currentIndex < totalBytes) {
				if ((binArray[currentIndex] == 13) && (binArray[currentIndex + 2] == 13)) {
					int end = currentIndex;
					if (encoding != null) {
						try {
							dataHeader = new String(binArray, start, currentIndex - start, encoding);
						} catch (UnsupportedEncodingException ueex) {
							dataHeader = null;
						}
					}
					if (dataHeader == null) {
						dataHeader = new String(binArray, start, currentIndex - start);
					}
					currentIndex += 2;
					break;
				}
				currentIndex++;
			}
			if (dataHeader == null) {
				break;
			}
			currentIndex += 2;
			boolean isFile = dataHeader.indexOf("filename") > 0;

			/* fields */
			String fieldName = getDataFieldValue(dataHeader, "name");
			String fileName = "";
			String filePathName = "";
			if (isFile) {
				filePathName = getDataFieldValue(dataHeader, "filename");
				fileName = getFileName(filePathName);
			}

			/* data section */
			boolean found = false;
			int searchPos = currentIndex;
			int keyPos = 0;
			int boundaryLen = boundary.length();
			int startData = currentIndex;
			int endData = 0;
			while (true) {
				if (searchPos >= totalBytes) break;
				if (binArray[searchPos] == (byte) boundary.charAt(keyPos)) {
					if (keyPos == boundaryLen - 1) {
						endData = ((searchPos - boundaryLen) + 1) - 3;
						break;
					}
					searchPos++;
					keyPos++;
				} else {
					searchPos++;
					keyPos = 0;
				}
			}
			currentIndex = endData + boundaryLen + 3;

			/* store file */
			if (isFile && (fileName.length() > 0)) {
				int totalFileSize = (endData - startData) + 1;
				UploadedFile newFile = new UploadedFile();
				newFile.setFieldName(fieldName);
				newFile.setFilePathName(filePathName);
				String contentType = getContentType(dataHeader);
				newFile.setContentType(contentType);
				newFile.setContentDisp(getContentDisp(dataHeader));
				if (contentType.indexOf("application/x-macbinary") > 0) {
					startData += 128;
				}
				newFile.setSize((endData - startData) + 1);
				newFile.setDataStart(startData);
				//newFile.setDataEnd(endData);
				newFile.setRequestData(binArray);
				
				files.put(fieldName, newFile);
			} else {
				String value = null;
				if (encoding != null) {
					try {
						value = new String(binArray, startData, (endData - startData) + 1, encoding);
					} catch (UnsupportedEncodingException ucex) {
						value = null;
					}
				}
				if (value == null) {
					value = new String(binArray, startData, (endData - startData) + 1);
				}
				if (isFile == false) {
					ArrayList valuesList = (ArrayList) parameters.get(fieldName);
					if (valuesList == null) {
						valuesList = new ArrayList();
					}
					valuesList.add(value);
					parameters.put(fieldName, valuesList);
				} else {
					UploadedFile newFile = new UploadedFile(false);
					newFile.setFieldName(fieldName);
					newFile.setFilePathName(value);
					files.put(fieldName, newFile);
				}
			}
			if ((char)binArray[currentIndex + 1] == '-') {
				break;
			}
			currentIndex += 2;
		}

		// convert ArrayLists for parameters into arrays
		Enumeration names = parameters.keys();
		while (names.hasMoreElements()) {
			String paramName = (String) names.nextElement();
			ArrayList valuesList = (ArrayList) parameters.get(paramName);
			if (valuesList != null) {
				String[] result = new String[valuesList.size()];
				for (int i = 0; i < result.length; i++) {
					result[i] = (String) valuesList.get(i);
				}
				parameters.put(paramName, result);
			}
		}
		return new Hashtable[] {parameters, files};
	}



	// ---------------------------------------------------------------- misc utils

	/**
	 * Gets value of data field
	 *
	 * @param dataHeader header
	 * @param fieldName  field's name
	 *
	 * @return value or empty string if not founded
	 */
	public static String getDataFieldValue(String dataHeader, String fieldName) {
		String value = "";
		String token = String.valueOf((new StringBuffer(String.valueOf(fieldName))).append("=").append('"'));
		int pos = dataHeader.indexOf(token);
		if (pos > 0) {
			int i = pos + token.length();
			int start = i;
			token = "\"";
			int end = dataHeader.indexOf(token, i);
			if ((start > 0) && (end > 0)) {
				value = dataHeader.substring(start, end);
			}
		}
		return value;
	}

	/**
	 * Strips content type information from request's data header.
	 *
	 * @param dataHeader data header string
	 *
	 * @return content type or an empty string if no content type defined
	 */
	private static String getContentType(String dataHeader) {
		String token = "Content-Type:";
		int start = dataHeader.indexOf(token);
		if (start == -1) {
			return "";
		}
		start += token.length();
		return dataHeader.substring(start);
	}

    private static String getFileName(String filePathName) {
		int pos = filePathName.lastIndexOf('/');
		if (pos != -1) {
			return filePathName.substring(pos + 1);
		}
		pos = filePathName.lastIndexOf('\\');
		if (pos != -1) {
			return filePathName.substring(pos + 1);
		}
		return filePathName;
	}

	private static String getContentDisp(String dataHeader) {
		int start = dataHeader.indexOf(":") + 1;
		int end = dataHeader.indexOf(";");
		return dataHeader.substring(start, end);
	}


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -