package li.mvc.adapter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.Vector; import javax.servlet.ServletInputStream; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import li.mvc.Context; public class Uploader { private Map<String, String[]> parameters = new HashMap<String, String[]>(); public List<FileMeta> upload(ServletRequest request, String uploadPath) throws IOException { List<FileMeta> fileMetas = new ArrayList<FileMeta>(); String boundaryStart = "--" + getBoundary(request.getContentType()); ServletInputStream inputStream = request.getInputStream(); FileOutputStream fileOutputStream = null;// 文件输出流 byte[] buf = new byte[1024]; String name = null, fileName = null;// 文件名 boolean isText = false; for (int len = 1; len > 0; len = inputStream.readLine(buf, 0, buf.length)) {// 循环读取ServletInputStream String temp = new String(buf, 0, len); if (boundaryStart.equalsIgnoreCase(temp.trim()) && null != fileOutputStream) {// 一个域的开始,结束写文件 fileOutputStream.flush(); fileOutputStream.close(); fileOutputStream = null;// 是否为空会作为一个标志 } else if (temp.startsWith("Content-Disposition") && temp.contains("filename=")) {// 文件头 name = getName(temp); fileName = getFileName(temp);// 文件名 isText = false; if (null != fileName && !fileName.isEmpty()) {// 是文件域的时候文件名非空 File file = file(uploadPath, name, fileName);// 文件名 fileOutputStream = new FileOutputStream(file);// 开始写一个新的文件 FileMeta fileMeta = new FileMeta(name, fileName, file); fileMetas.add(fileMeta); } } else if (temp.startsWith("Content-Type")) {// Content-Type行 inputStream.readLine(buf, 0, len); // 跳过Content-Type后的空行 } else if (null != fileOutputStream) {// 如果在写一个文件的过程中 fileOutputStream.write(buf, 0, len);// 写文件类容 } else if (temp.startsWith("Content-Disposition") && !temp.contains("filename=")) {// 文本表单域 name = getName(temp);// 获取文本域名 isText = true; } else if (!temp.startsWith(boundaryStart) && null != name && isText && !temp.isEmpty()) {// 不是分隔符,非空,是文本域类容 putParameter(name, temp); } } if (null != fileOutputStream) {// 结束 fileOutputStream.flush(); fileOutputStream.close(); } inputStream.close(); Context.init(new LiHttpServletRequestWrapper(Context.getRequest(), parameters), Context.getResponse(), Context.getAction()); return fileMetas; } /** * 设置文本域参数 */ private void putParameter(String name, String value) { if (null != value && !value.trim().isEmpty()) { String[] params = this.parameters.get(name); if (null == params) { this.parameters.put(name, new String[] { value.trim() }); } else { String[] temp = new String[params.length + 1]; for (int i = 0; i < params.length; i++) { temp[i] = params[i]; } temp[params.length] = value.trim(); this.parameters.put(name, temp); } } } /** * 创建文件 */ private static File file(String uploadPath, String name, String fileName) { int i = fileName.indexOf("\\"); if (i > 0) {// ie11里面filename不仅为文件名而为完整文件路径 fileName = fileName.substring(i + 1); } fileName = uploadPath + "//" + UUID.randomUUID() + "_" + name + "_" + fileName; File file = new File(fileName); file.getParentFile().mkdirs(); return file; } /** * 获取表单域名称 */ private static String getName(String temp) { int a = temp.indexOf("name="); int b = temp.indexOf(";", a); b = b < 0 ? temp.length() - 2 : b; if (a < 0) { return null; } else { return temp.substring(a + 6, b - 1); } } /** * 获取文件名 */ private static String getFileName(String temp) { int a = temp.indexOf("filename="); if (a < 0) { return null; } else { return temp.substring(a + 10, temp.lastIndexOf("\"")); } } /** * 获取分隔符 */ private static String getBoundary(String contentType) { if (null == contentType) { return null; } int pos = contentType.indexOf(";"); if (pos <= 10) { return null; } if (!contentType.substring(0, pos).equalsIgnoreCase("multipart/form-data")) { return null; } pos = contentType.indexOf("=", pos); if (pos < 0) { return null; } return contentType.substring(pos + 1); } /** * request的封装 * * @author : 明伟  */ public class LiHttpServletRequestWrapper extends HttpServletRequestWrapper { private Map<String, String[]> parameters; public LiHttpServletRequestWrapper(ServletRequest request, Map<String, String[]> parameters) { super((HttpServletRequest) request); this.parameters = parameters; } public String getParameter(String name) { String[] parameterValues = this.getParameterValues(name); return null == parameterValues || parameterValues.length < 1 ? null : parameterValues[0]; } public Map<String, String[]> getParameterMap() { return this.parameters; } public Enumeration<String> getParameterNames() { return new Vector(this.parameters.entrySet()).elements(); } public String[] getParameterValues(String name) { return this.parameters.get(name); } } }