`
┿┅мīSS
  • 浏览: 95162 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

实现fileuoload的透明上传

    博客分类:
  • J2EE
阅读更多
我们用fileupload上传文件的时候,为了获取上传表单里的非文件表单域,通常都要不断去循环读取,每一个上传文件的方法都要重复同样的代码,很不方便,而struts2里面就把fileupload封装好了,可以很方便地用get()来获取表单里非文件域的值,那么底层是怎么实现的呢?
   简单点来说,就是文件传达到servlet之前,先把上传的文件流用filter拦截过滤,在filter里面利用自己封装的文件流,再传送过去给filter,使得servlet里能够直接使用我们封装好的文件流,这样的话,就很方便,只需一个filter,以后哪个页面需要上传文件,只需要配置一些web.xml ,过滤一下就可以.

本文用到的是fileupload 1.2.现在一起看看实现的关键代码:

首先是要利用HttpServletRequestWrapper,实现一个自己的HttpServletRequest;

import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * 
 * 拦截Servlet容器传给Servlet的请求信息
 * 封装上传文件表单的请求信息
 * @author Miss
 *
 */

public class MultipartRequest extends HttpServletRequestWrapper {

	HashMap<String,String[]> parameters = new HashMap<String,String[]>();
	HashMap<String,FileItem> files = new HashMap<String,FileItem>();

	public MultipartRequest(HttpServletRequest request)
			throws FileUploadException, IOException {

		super(request);
		DiskFileItemFactory dff = new DiskFileItemFactory();
		dff.setSizeThreshold(1024 * 1024); // 内存最多存储1MB数据,超过就用临时目录缓存
		ServletFileUpload sfu = new ServletFileUpload(dff);
		sfu.setSizeMax(1024 * 1024 * 10); // 最多上传10MB数据
		sfu.setHeaderEncoding("utf-8");

		List<FileItem> fileItems = null;
		fileItems = sfu.parseRequest(request);
		Iterator i = fileItems.iterator();

		while (i.hasNext()) {
			FileItem fi = (FileItem) i.next();

			if (fi.isFormField()) {

				String fieldName = fi.getFieldName();
				String content = null;
				content = fi.getString("utf-8");
				setParameter(fieldName, content);
			} else {
				String pathSrc = fi.getName();
				if (pathSrc.trim().equals("")) {

					continue;
				}
				String fieldName = fi.getFieldName();
				files.put(fieldName, fi);
			}
		}

	}

	private void setParameter(String fieldName, String content) {

		String[] mValue = (String[]) parameters.get(fieldName);
		if (mValue == null) {

			mValue = new String[0];
		}
		String[] newValue = new String[mValue.length + 1];
		System.arraycopy(mValue, 0, newValue, 0, mValue.length);
		newValue[mValue.length] = content;
		parameters.put(fieldName, newValue);
	}

	public String getParameter(String fieldName) {
		String[] mValue = (String[]) parameters.get(fieldName);
		if ((mValue != null) && (mValue.length > 0)) {

			return mValue[0];

		}

		return null;
	}

	public Enumeration getParameterNames() {

		Collection c = parameters.keySet();

		return Collections.enumeration(c);

	}

	public String[] getParameterValues(String fieldName) {

		String[] mValue = (String[]) parameters.get(fieldName);
		return mValue;

	}

	public Map getParameterMap() {

		return parameters;
	}

	public FileItem getFileItem(String fieldName) {

		FileItem fItem = (FileItem) files.get(fieldName);
		return fItem;
	}

	public Enumeration getFileItemNames() {

		Collection c = files.keySet();
		return Collections.enumeration(c);

	}

}



接下来是写个filter来掉包一下上传的文件流

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class UploadFilter implements Filter {

	public void destroy() {
		// TODO Auto-generated method stub

	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

		HttpServletRequest req = (HttpServletRequest) request;
		String type = req.getHeader("Content-Type");
		if (type == null || !type.startsWith("multipart/form-data")) {

			chain.doFilter(request, response);

		} else {

			MultipartRequest mreq = null;
			try {
				mreq = new MultipartRequest(req);
			} catch (Exception e) {

				throw new ServletException(e);

			}
			chain.doFilter(mreq, response);

		}

	}

	public void init(FilterConfig arg0) throws ServletException {

	}

}



然后在需要实现上传的servlet里就能轻松获取上传表单里的值,就是平时的requset.getParameter().

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;

public class UploadServlet extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		resp.setContentType("text/html;charset=gb2312");
		PrintWriter out = resp.getWriter();

		out.println("用户:" + req.getParameter("user"));


		// 设置上传文件后的保存目录
		String path = this.getServletContext().getRealPath("/upload");

		File saveDir = new File(path);
		if (!saveDir.exists()) {

			if (!saveDir.mkdir()) {

				out.println("无法创建储存目录");
				return;
			}

		}

		MultipartRequest mreq = (MultipartRequest) req;
		Enumeration fileItemNames = mreq.getFileItemNames();

		while (fileItemNames.hasMoreElements()) {

			String name = (String) fileItemNames.nextElement();
			FileItem fi = (FileItem) mreq.getFileItem(name);

			String fileName = fi.getName().substring(
					fi.getName().lastIndexOf("\\") + 1);

			try {
				fi.write(new File(saveDir, fileName));
				out.println("上传文件成功!");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	}
}


这里是上传表单里有一个name=user 的非文件表单项,可以直接在servlet里用req.getParameter("user")获取.
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics