其他分享
首页 > 其他分享> > FileUpload

FileUpload

作者:互联网

14.FileUpload

14.1.文件上传中遇到的问题
14.1.1.尝试文件上传
  1. 使用form表单,设置属性input type=file,method=post,Content-Length: 11,表示的是请求体的长度。
    • 此时仅会上传文件名,没有长传文件的data。还需要设置一个属性
  2. 设置enctype=multipart/form-data
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ServletInputStream inputStream = request.getInputStream();
        //FileInputStream fileInputStream = new FileInputStream();
        //比如保存在当前应用下 upload目录下面
        String realPath = getServletContext().getRealPath("upload/1.jpg");
        File file = new File(realPath);
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        int length = 0;
        byte[] bytes = new byte[1024];
        while ((length = inputStream.read(bytes)) != -1){
            fileOutputStream.write(bytes, 0, length);
        }
        fileOutputStream.flush();
        fileOutputStream.close();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {

        }catch (Exception e){
            response.setStatus(500);
        }
    }
}
14.1.2.上传文件之后会引入很多字符数据
------WebKitFormBoundarytdzmIhaGTkvQcl7f
content-Disposition: form-data; name="image" ; filename="1.txt"content-Type: text/plain

hello
------WebKitFormBoundarytdzmIhaGTkvQcl7f--
14.1.3.在引入文件上传的同时,无法获取普通文本表单数据
14.2.使用第三方jar包实现文件上传
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;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;

@WebServlet("/upload")
public class Upload extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //注意中文乱码问题,提交上来的表单设置这个没有用
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        //判断是否含有上传的文件
        if(!ServletFileUpload.isMultipartContent(request)){
            response.getWriter().println("没有包含上传的文件");
            return;
        }
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //设置一个仓库、缓冲区,目的是为了传输大型文件时,会利用缓冲区边中转边传输
        ServletContext servletContext = getServletContext();
        File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
        factory.setRepository(repository);

        //拿到真正去处理请求的处理器
        ServletFileUpload handler = new ServletFileUpload(factory);
        //解决上传文件中文名乱码问题
        handler.setHeaderEncoding("utf-8");
        //设置文件大小为1024Bytes*1024*10=10MB
        handler.setFileSizeMax(1024*1024*10);

        try {
            //这一步是最为关键的,它会对请求进行解析,会将每个input封装成为一个FileItem
            List<FileItem> items = handler.parseRequest(request);
            //遍历出每一个input,这里每一个FileItem就是每一个input
            Iterator<FileItem> iterator = items.iterator();
            while (iterator.hasNext()){
                //item有两种可能性,一种是普通的form表单,一种是上传的文件
                FileItem item = iterator.next();

                //执行这一分支说明他是普通的form表单
                if(item.isFormField()){
                    processFormField(item);
                }else {
                    //这一分支说明他是文件
                    processUploadedFile(item);
                }
            }

        } catch (FileUploadException e) {
            e.printStackTrace();
        }
    }

    private void processUploadedFile(FileItem item) {
        //表单的name属性
        String fieldName = item.getFieldName();
        //上传的文件名
        String fileName = item.getName();
        //MIME类型
        String contentType = item.getContentType();
        //是否在内存里面
        boolean isInMemory = item.isInMemory();
        //大小,单位是字节
        long sizeInBytes = item.getSize();
        System.out.println("file:" + fieldName + ":" + fileName + ":" + contentType + ":" + isInMemory + ":" + sizeInBytes);

        //保存在本地硬盘上,real是获取到的硬盘的绝对路径
        String realPath = getServletContext().getRealPath("upload/" + fileName);
        File file = new File(realPath);
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        try {
            //执行该行代码时,它会将文件的数据写入到file
            //这一步也是对磁盘IO的封装
            item.write(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void processFormField(FileItem item) {
        //表单的name属性名
        String name = item.getFieldName();
        //表单的value值
        String value = null;
        try {
            //解决普通表单数据中有中文乱码问题
            value = item.getString("utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(name + ":" + value);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
14.3.JavaBean
import com.cskaoyan.request.User;
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;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class FileUploadUtils {
    public static Map<String, String> parseRequest(HttpServletRequest request) {
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //设置一个仓库、缓冲区,目的是为了传输大型文件时,会利用缓冲区边中转边传输
        ServletContext servletContext = request.getServletContext();
        File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
        factory.setRepository(repository);
        // 拿到真正去处理请求的处理器
        ServletFileUpload handler = new ServletFileUpload(factory);
        //可以解决上传文件中文名乱码问题
        handler.setHeaderEncoding("utf-8");
        // bytes
        //handler.setFileSizeMax(1024);
        Map<String, String> params = new HashMap<>();
        try {
            //这一步是最为关键的,它会对请求进行解析,会将每个input封装成为一个FileItem
            List<FileItem> items = handler.parseRequest(request);
            //遍历出每一个input,
            Iterator<FileItem> iterator = items.iterator();
            while (iterator.hasNext()){
                //item有两种可能性,一种是普通的form表单,一种是上传的文件
                FileItem item = iterator.next();
                if(item.isFormField()){
                    processFormField(item, params);
                }else {
                    processUploadedFile(item, params,request);
                }
            }

        } catch (FileUploadException e) {
            e.printStackTrace();
        }
        return params;
    }

    private static void processUploadedFile(FileItem item, Map<String, String> params, HttpServletRequest request) {
        String fieldName = item.getFieldName();
        String fileName = item.getName();
        String contentType = item.getContentType();
        boolean isInMemory = item.isInMemory();
        long sizeInBytes = item.getSize();
        System.out.println("file:" + fieldName + ":" + fileName + ":" + contentType + ":" + isInMemory + ":" + sizeInBytes);
        //保存在本地硬盘上  硬盘的绝对路径
        String relativePath = "upload/" + fileName;
        String realPath = request.getServletContext().getRealPath(relativePath);
        File file = new File(realPath);
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        try {
            //执行该行代码时,它会将文件的数据写入到file
            //这一步也是对磁盘IO的封装,相当于一个新的线程去写入
            item.write(file);
            //应该把文件的相对路径保存下来,为什么不保存绝对路径呢
            //因为我们这边有一个需求, 需要将该图片再次显示给客户端  img src  /应用名  /资源路径
            //  /app   /upload/1.jpg
            params.put(fieldName, relativePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void processFormField(FileItem item, Map<String, String> params) {
        String name = item.getFieldName();
        String value = null;
        try {
            value = item.getString("utf-8");
            //BeanUtils 没有map参数
            params.put(name, value);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        System.out.println(name + ":" + value);
    }
}
14.4.重名文件
14.5.应用案例
import request.utils.FileUploadUtils;//导入刚刚封装的JavaBean工具
import org.apache.commons.beanutils.BeanUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

@WebServlet("/uploadrefresh")
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //FileUpload
        response.setContentType("text/html;charset=utf-8");
        Map<String, String> map = FileUploadUtils.parseRequest(request);
        User user = new User();
        try {
            BeanUtils.populate(user, map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //将user数据和另外一个servlet进行共享
        //没有在当前页面里面进行页面显示的代码原因是因为一个组件内处理的逻辑越多
        //那么它的整个功能耦合性就越强;如果部分代码发生变化,其他代码很容易也会收到影响 MVC
        //context、request域都可以,但是,context域有一个bug
        //request.setAttribute("user", user);
        //注意:转发前后请求方法不变
        //如果你适用refresh、重定向,浏览器默认适用get
        //context域有一个bug,在FileUplopUtils中,item.write(file)涉及到磁盘IO的写入,IO比正常运行的内存代码慢一些,
        //在out文件中,文件是存在的,而在浏览器中,资源还没准备好就显示了,所以无法显示出来,因此用refresh等待一些时间就可以正常显示了
        //request.getRequestDispatcher("/view").forward(request, response);
        getServletContext().setAttribute("user", user);
        response.getWriter().println("上传成功,即将回显数据");
        response.setHeader("refresh", "5;url=" + request.getContextPath() + "/view");
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}


import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/view")
public class ViewServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        User user = (User) getServletContext().getAttribute("user");
        response.getWriter().println("<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>Title</title>\n" +
                "</head>\n" +
                "<body>");
        response.getWriter().println("<div>" + user.getUsername() + "</div>");
        response.getWriter().println("<div>" + user.getPassword() + "</div>");
        response.getWriter().println("<div><img src='" + request.getContextPath() + "/" + user.getImage() + "' /></div>");

        response.getWriter().println("</body>\n" +
                "</html>");

    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/app/uploadrefresh" enctype="multipart/form-data"  method="post">
        <input type="file" name="image"><br>
        <input type="text" name="username"><br>
        <input type="password" name="password"><br>
        <input type="submit">
    </form>
</body>
</html>

标签:FileUpload,String,request,item,import,servlet,javax
来源: https://blog.csdn.net/lsoxvxe/article/details/116563406