文件上传案例

文件上传案例

1.浏览器端说明

  1. 请求方式为post
  2. 采用form表单提交,Input标签类型位file
  3. form表单的enctype属性值设置为multipart/form-data

jsp代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <form action="${pageContext.request.contextPath}/u" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" name="提交">

  </form>
  </body>
</html>

2.配置xml文件

    <servlet>
        <servlet-name>uploadServlet</servlet-name>
        <servlet-class>com.example.servlet.UploadServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>uploadServlet</servlet-name>
        <url-pattern>/u</url-pattern>
    </servlet-mapping>

3.servlet测试

public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("up");
    }
}

4.抓包工具抓包

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这时如果通过servlet中req.getParameter的方式拿不到对应的名称
在这里插入图片描述

5.上传依赖的jar包

在这里插入图片描述
可以在http://tomcat.apache.org/官网下载 http://commons.apache.org/proper/commons-fileupload/
下载地址:
链接:https://pan.baidu.com/s/1o5IujerfmNKkO5-uI9yIuw
提取码:p2s4

6.实际操作

  1. 判定请求中是否有文件上传boolean isMultipart = ServletFileUpload.isMultipartContent(request);
  2. 基于磁盘创建工厂DiskFileItemFactory factory = new DiskFileItemFactory();
  3. 创建新的文件上载处理程序ServletFileUpload upload = new ServletFileUpload(factory);
  4. 解析请求,返回一列表List<FileItem> items = upload.parseRequest(request);
  5. 循环遍历FileItem判定是否是普通的表单项next.isFormField()
    5.1 如果是普通表单项,通过String fieldName = next.getFieldName();拿到表单项的name属性,next.getString();拿到表单控件的值
    5.2 如果是文件表单next.getFieldName()拿到控件的name属性,next.getName()拿到上传文件的原始名,next.getInputStream()拿到文件的二进制流内容
  6. 如果是文件,则使用二进制输入流进行文件输入

完整代码:

public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if(ServletFileUpload.isMultipartContent(req)){
            //创建基于磁盘的FileItemFactory
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //基于FileItemFactory创建文件上传的操作对象
            ServletFileUpload upload = new ServletFileUpload(factory);
            //解析请求
            try {
                List<FileItem> items = upload.parseRequest(req);
                Iterator<FileItem> iterator = items.iterator();
                //循环遍历
                while (iterator.hasNext()){
                    //拿到每个FileItem
                    FileItem next = iterator.next();
                    //判定FileItem是否是普通的表单项
                    if(next.isFormField()){
                        String fieldName = next.getFieldName();
                        String string = next.getString();
                        System.out.println(fieldName);
                        System.out.println(string);

                    }else {//是文件上传项

                        String fieldName = next.getFieldName();//拿到控件name属性
                        String name = next.getName();//拿到文件的原始名
                        InputStream inputStream = next.getInputStream();//二进制文件内容流
						//创建文件保存路径
                        String realPath = getServletContext().getRealPath("/WEB-INF/source");
                        File file = new File(realPath);
                        file.mkdirs();
						//利用二进制流进行写入
                        OutputStream outputStream = new FileOutputStream(new File(realPath,name));
                        byte[] buffer = new byte[1024];
                        int len = -1;
                        while ((len = inputStream.read(buffer,0,buffer.length))!=-1){
                            outputStream.write(buffer,0,len);
                        }
                        //关闭流
                        outputStream.close();
                        inputStream.close();
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
        }
    }
}

但是当普通表单控件传入时会有中文乱码的问题:
在form表单中加入一个input-text标签,写入输出结果:

在这里插入图片描述

在这里插入图片描述
可以看到文件域的名字并没有乱码
解决乱码问题:string = new String(string.getBytes("iso-8859-1"),"utf-8");
在这里插入图片描述

在这里插入图片描述

7.commons-IO提供了对文件流的更简单的操作方式

FileUtils工具类
说明文档位置:http://commons.apache.org/proper/commons-io/apidocs/index.html
在这里插入图片描述
使用输入流复制到文件位置实现上传,
并且文件上传路径不存在可以默认创建,流使用完毕后自动关闭。
简化后的代码:

public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if(ServletFileUpload.isMultipartContent(req)){
            //创建基于磁盘的FileItemFactory
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //基于FileItemFactory创建文件上传的操作对象
            ServletFileUpload upload = new ServletFileUpload(factory);
            //解析请求
            try {
                List<FileItem> items = upload.parseRequest(req);
                Iterator<FileItem> iterator = items.iterator();
                //循环遍历
                while (iterator.hasNext()){
                    //拿到每个FileItem
                    FileItem next = iterator.next();
                    //判定FileItem是否是普通的表单项
                    if(next.isFormField()){
                        String fieldName = next.getFieldName();//拿到控件name属性
                        String string = next.getString();//拿到控件的值
                        string = new String(string.getBytes("iso-8859-1"),"utf-8");
                        
                    }else {//是文件上传项

                        String fieldName = next.getFieldName();//拿到控件name属性
                        String name = next.getName();//拿到文件的原始名
                        System.out.println(name);
                        InputStream inputStream = next.getInputStream();//二进制文件内容流
                        String realPath = getServletContext().getRealPath("/WEB-INF/source");
                        FileUtils.copyInputStreamToFile(inputStream,new File(realPath,name));
                    }
                }
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值