Web项目中文件上传Filter处理

最近遇到一个文件上传的项目,而且在这个项目中遇到的文件上传的次数还是挺多的,所以就写了个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>
        密&nbsp;&nbsp;码:<input type="password" value="" name="psw"><br>
        头&nbsp;&nbsp;像:<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中,这样就可以了,具体操作在下就不书写了。。

以上内容如有错误,欢迎指出。。。

时间: 2024-10-11 02:24:21

Web项目中文件上传Filter处理的相关文章

Eclipse搭建springboot项目(三)文件上传

知识点:SpringBoot2.x文件上传:HTML页面文件上传和后端处理 1.springboot文件上传 MultipartFile file,源自SpringMVC 1)静态页面直接访问:localhost:8080/index.html 注意点:如果想要直接访问html页面,则需要把html放在springboot默认加载的文件夹下面 2)MultipartFile 对象的transferTo方法,用于文件保存(效率和操作比原先用FileOutStream方便和高效) 访问路径 http

extjs列表中文件上传与下载(带有重命名操作)

下面是extjs列表中文件上传与下载: 如图: 一.上传 上传按钮: { xtype: 'button', width: 60, margin: '0 20', text: ' 上 传 ', handler: 'onUploadClick' }] 上传按钮事件(打开上传窗口和传参): onUploadClick: function () { var me = this, view = me.getView(), vm = view.getViewModel(), store = me.getSt

C# 之 FTP服务器中文件上传与下载(三)

通过上一篇博客<C# 之 FTP服务器中文件上传与下载(二)>,我们已经实现将文件上传到我们创建的FTP服务器.今天我们就一起来看看怎么样实现从FTP服务器中下载我们所需要的文件.         我们想实现的效果是在页面上有一个超链接,超链接显示为我们想要下载的文件名.点击该文件名进入下载页面.首先我们在前台插入一个超链接,但是这个超链接为后台拼接的超链接. using System; using System.Collections.Generic; using System.Linq;

C# 之 FTP服务器中文件上传与下载(四)

        通过上一篇博客<C# 之 FTP服务器中文件上传与下载(三)>,我们已经实现将文件从我们创建的FTP服务器中下载到本地.今天就最后给大家讲解一下怎么对FTP中的文件进行重命名和删除操作. 首先在前台添加两个重命名和删除的按钮 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Defaul

Android与Asp.Net Web服务器的文件上传下载BUG汇总【更新】

遇到的问题: 1.java.io.IOException: open failed: EINVAL (Invalid argument)异常,在模拟器中的sd卡创建文件夹和文件时报错 出错原因可能是:(1)文件名称中含有不符合规范的字符,比如“:”,“?”或者空格等.(2)需要先创建文件夹目录再创建文件,不能直接创建文件. 2. android.os.NetworkOnMainThreadException异常,从服务器请求数据后,写入文件时报错 出错原因:在主线程内执行了访问http的操作,最

Spring MVC环境中文件上传大小和文件类型限制以及超大文件上传bug问题

    在上一篇文章中,主要介绍了Spirng MVC环境下的正常情况下文件上传功能实现.在实际开发的时候,还会涉及到上传文件大小和类型的限制,接下来就会对Spirng MVC环境下文件上传大小和类型的限制进行介绍,还会讲解到文件上传大小tomcat服务器bug问题及解决方案. 一.文件上传大小限制 这里还是接着上篇文章先介绍Spring MVC下的文件上传大小限制,文件上传大小的限制在springmvc-config.xml中配置文件解析器CommonsMultipartResolver时即可

SpringMVC中文件上传的客户端验证

SpringMVC中文件上传的客户端验证 客户端验证主要思想:在jsp页面中利用javascript进行对文件的判断,完成验证后允许上传 验证步骤:1.文件名称 2.获取文件的后缀名称 3.判断哪些文件类型允许上传 4.判断文件大小 5.满足条件后跳转后台实现上传 前台界面(验证上传文件是否格式满足要求): <body> <h2>文件上传</h2> <form action="upload01" method="post" 

web.py处理文件上传

1 #coding=utf8 2 import web 3 4 urls = ('/','Home', 5 '/upload', 'Upload') 6 7 app = web.application(urls, globals()) 8 9 class Upload: 10 def GET(self): 11 web.header("Content-Type","text/html; charset=utf-8") 12 return ""&q

ExtJS 中文件上传控件

1 Ext.onReady(function(){ 2 var fileUpload = new Ext.FormPanel({ 3 id:'fileUpload', 4 frame:true, 5 fileUpload:true, 6 items:[{ 7 xtype:'textfield', 8 labelStyle : 'text-align:right;', 9 allowBlank:false, 10 fieldLabel:'选择文件', 11 inputType:'file', 12