实现fileuoload的透明上传

我们用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")获取.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值