最近遇到一个文件上传的项目,而且在这个项目中遇到的文件上传的次数还是挺多的,所以就写了个Filter过滤器。这一个想法还是从一本书上看到的,所以原则上说并不是在下原创。不过因为补充了一点东西,所以,嘿嘿,不说了。
首先需要写个Filter:
package yin.filter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
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.annotation.MultipartConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.fileupload.DiskFileUpload;
import org.apache.commons.fileupload.FileItem;
public class Uploadfilter implements Filter
{
private String encoding;
@Override
public void destroy()
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
UploadRequestWrapper uploadRequestWrapper = new UploadRequestWrapper((HttpServletRequest)request);
chain.doFilter(uploadRequestWrapper, response);
}
@Override
public void init(FilterConfig config) throws ServletException
{
encoding = config.getServletContext().getInitParameter("encoding");
if (encoding == null)
{
encoding = "utf-8";
}
}
class UploadRequestWrapper extends HttpServletRequestWrapper
{
// 文件头类型
private static final String MULTIPART_HEADER = "Content-type";
// 是否是上传文件
private boolean multipart;
//保存提交的数据
private Map<String, Object> params = new HashMap<String,Object>();
@SuppressWarnings("deprecation")
public UploadRequestWrapper(HttpServletRequest request)
{
super(request);
// 判断是否是上传文件
multipart = request.getHeader(MULTIPART_HEADER) != null && request
.getHeader(MULTIPART_HEADER).startsWith("multipart/form-data");
// 如果是上传文件
if (multipart)
{
try
{
DiskFileUpload upload = new DiskFileUpload();
// 使用apache进行上传
// 设置编码
upload.setHeaderEncoding(encoding);
// 解析上传的数据
List<FileItem> fileItems = upload.parseRequest(request);
// 遍历
for (Iterator<FileItem> it = fileItems.iterator(); it.hasNext();)
{
// 获取当前的FileItem
FileItem item = (FileItem) it.next();
// 如果是文本域
if (item.isFormField())
{
params.put(item.getFieldName(), item.getString(encoding));
}
else
{
// 替换特殊字符
String filename = item.getName().replace("\\", "/");
filename = filename.substring(filename.lastIndexOf("/")+1);
// 保存到系统临时文件夹中
java.io.File file = new File(System.getProperty("java.io.tmpdir"), filename);
// 新建文件输出流
OutputStream ops = new FileOutputStream(file);
// 输出到文件流中
ops.write(item.get());
// 关闭文件流
ops.close();
// 将值放到Map中
params.put(item.getFieldName(), file);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
@Override
public Object getAttribute(String name)
{
// 如果是上传文件,则从Map中取值,支持直接获取文件对象
if (multipart && params.containsKey(name))
{
return params.get(name);
}
return super.getAttribute(name);
}
@Override
public String getParameter(String name)
{
// 如果是上传文件,则从Map中取值,
if (multipart && params.containsKey(name))
{
return params.get(name).toString();
}
return super.getParameter(name);
}
}
}
好了,Filter写完了,那么就修改配置文件web.xml吧,如下:
<filter>
<filter-name>Uploadfilter</filter-name>
<filter-class>yin.filter.Uploadfilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Uploadfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
以上只是文件上传的Filter,那么该怎样使用了。放心,在下会说滴:
我们现在先写一个简单的上传的jsp文件,
<body>
<!-- 包含上传文件的表单 -->
<form action="upload" method="post" enctype="multipart/form-data">
用户名:<input type="text" value="" name="uname"><br>
密 码:<input type="password" value="" name="psw"><br>
头 像:<input type="file" name="file"><br>
<input type="submit" value="注册">
</form>
</body>
由于样式什么的没有调整,难看点也是无所谓的吧!
然后在servlet中使用:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
request.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
// 读取表单内容
String name = request.getParameter("uname");
String psw = request.getParameter("psw");
File headPic = (File) request.getAttribute("file");
FileWriterWrapper write = new FileWriterWrapper(request, headPic);
}
大家有没有发现,这样选取表单中的内容是比较方便的,那么然后
FileWriterWrapper write = new FileWriterWrapper(request, headPic);
这一行代码就是将读取到的文件写入到硬盘中了,
package yin.usual;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
public class FileWriterWrapper
{
public FileWriterWrapper()
{
// TODO Auto-generated constructor stub
}
// 文件写入的方法
public FileWriterWrapper(HttpServletRequest request,File file)
{
try
{
// 读取上下文配置,获取路径
ServletContext context = request.getServletContext();
String filename = context.getInitParameter("filename");
// 获取文件保存路径
filename = context.getRealPath(filename);
// 如果路径不存在,则创建
if(!new File(filename).isDirectory())
{
System.out.println("文件不存在,正在创建。。。");
new File(filename).mkdirs();
}
// 获取文件名
String picname = file.getName().replace("/", "\\");
picname = picname.substring(picname.lastIndexOf("\\")+1, picname.length());
// 获取文件保存位置
String path = filename +"\\"+picname;
System.out.println("文件保存在:" + path);
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(path);
byte[] bs = new byte[1024*1024*4];
int len = 0;
while((len = fis.read(bs)) != -1)
{
fos.write(bs, 0, len);
}
// 关闭文件
fis.close();
fos.close();
System.out.println("文件写入成功");
}
catch (IOException e)
{
System.out.println("文件写入失败");
e.printStackTrace();
}
}
}
接下来,大家看看配置:
<context-param>
<param-name>filename</param-name>
<param-value>/imgs</param-value>
</context-param>
看到这,不知道大家有没有一个疑问,如果表单中的上传文件有多个,那么怎么办?如果这样就需要修改
FileWriterWrapper
类了,可以将获取上下文配置中的路径放在Servlet中,这样就可以了,具体操作在下就不书写了。。
以上内容如有错误,欢迎指出。。。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。