使用apache的fileupload进行文件上传

时间:2022-11-27 21:38:22

1.准备工作,下载apache的IO包和fileupload包,并将它们拷贝到web-inf下的lib目录里面,注意要在WebRoot下建一个upload的目录,用来保存上传的文件

 

2. 编写类FileUploadServlet

package org.liky.fileupload;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
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;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class FileUploadServlet extends HttpServlet {

    private static final long serialVersionUID = 8088769669368270752L;

    // 如果文件的大小超过这个数值,将直接写入磁盘,而不会放在内存缓冲区
    private int threshold = 0;
    // 服务器端临时文件上传目录
    private String repository;
    // 单个上传文件大小的最大值
    private long fileSizeMax;

    @SuppressWarnings("unchecked")
    @Override
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");


        DiskFileItemFactory factory = new DiskFileItemFactory();

        // 设置内存缓冲区的大小
        factory.setSizeThreshold(threshold);

        // 设置临时文件上传目录

        factory.setRepository(new File(repository));

        // 创建文件上出的实例
        ServletFileUpload upload = new ServletFileUpload(factory);

        // 设置单个上传文件大小的最大值

        upload.setFileSizeMax(fileSizeMax);

        try {
            List<FileItem> fileItems = upload.parseRequest(request);

            for (FileItem fileItem : fileItems) {

                if (fileItem.isFormField()) {
                    // 获得普通表单项的名字
                    String name = fileItem.getFieldName();
                    // 获得普通表单项的值
                    String value = fileItem.getString();
                   
                    System.out.println(name + ": " + value);

                    // 将普通表单项放入request请求中继续向前转发,以进一步处理
                    request.setAttribute(name, value);
                } else {
                    writeFiles(fileItem, request);
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }

        RequestDispatcher formHandler = request
                .getRequestDispatcher("/formHandler.do");
        if (null != formHandler) {
            formHandler.forward(request, response);
            System.out.println("****************** FormHandler *****************");
        } else {
            throw new ServletException("Sorry, formHandler.do not found!");
        }

    }

    @Override
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    /**
     * 将文件写入磁盘,注意为了提高效率, 我们没有直接调用FileItem.get()来读取文件内容,
     * 因为如果文件非常大的话,网络将承受不了,所以使用了缓冲区来读取, 如果上传的文件很小,则大可以使用这个方法
     *
     * @param fileItem
     */

    @SuppressWarnings("deprecation")
    private void writeFiles(FileItem fileItem, HttpServletRequest request)
            throws IOException {
        // 处理不同的浏览器上传文件时,文件名和路径的问题,有的浏览器只会显示文件名
        // 但是有的浏览器却会将完整路径也加上,因此需要处理

        String fileNameString = fileItem.getName();
        int start = fileNameString.indexOf("//");
        String fileName = fileNameString.substring(start + 1);

        // 获得当前web应用的根路径
        String parent = request.getRealPath(repository);

        // 构造一个File对象,规则是当前web应用的根路径加上文件名
        File file = new File(parent, fileName);

        // 设输出流一个缓冲区
        byte[] buffer = new byte[1024];

        // 获得实际能够有效读取的字节数组的长度
        int length = 0;
        // 获得FileItem的文件输入流
        InputStream is = fileItem.getInputStream();
        // 构造一个文件输出流
        FileOutputStream fos = new FileOutputStream(file);

        // 将字节流按顺序读入缓冲区,如果已经读到了字节输入流的末尾,
        // 也就是length小于或等于0时,读取结束

        while ((length = is.read(buffer)) > 0) {
            fos.write(buffer, 0, length);
        }

        // 记得关闭输入和输出流
        fos.close();
        is.close();
    }

    /**
     * 设置servlet的初始化参数
     */

    @Override
    public void init(ServletConfig config) throws ServletException {
        String thresholdParam = config.getInitParameter("threshold");
        String repositoryParam = config.getInitParameter("repository");
        String fileSizeMaxParam = config.getInitParameter("fileSizeMax");

        if (null != thresholdParam) {
            this.threshold = Integer.parseInt(thresholdParam);
        }
        if (null != repositoryParam) {
            this.repository = repositoryParam;
        }
        if (null != repositoryParam) {
            this.fileSizeMax = Integer.parseInt(fileSizeMaxParam);
        }
    }
}

 

 

3.编写类FormHandlerServlet

 

package org.liky.fileupload;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FormHandlerServlet extends HttpServlet {

    private static final long serialVersionUID = -3433917547449179227L;

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

        response.setContentType("text/html;charset=UTF-8");       
       
        String username = request.getAttribute("username").toString();
        String password = request.getAttribute("password").toString();
        String ageParam = request.getAttribute("age").toString();
       
        User user = new User();
       
       
        user.setUsername(username);
        user.setPassword(password);
       
        if (null != ageParam) {
            user.setAge(Integer.parseInt(ageParam));
        }
       
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getAge());
       
        request.setAttribute("user", user);
       
        RequestDispatcher show = request.getRequestDispatcher("show.jsp");
       
        if (null != show) {
            show.forward(request, response);           
        }
        else {
            response.sendRedirect("/index.jsp");           
        }

    }
  
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}


4.编写类User

 

package org.liky.fileupload;

public class User {
    private String username;
    private String password;
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

 

5.文件上传的JSP页面index.jsp

 

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%request.setCharacterEncoding("UTF-8"); %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>      
    <title>上传文件</title>   
  </head>
 
  <body>
    <form action="fileUpload.do" name="FileForm" method="post" enctype="multipart/form-data">
        姓名:<input type="text" name="username"><br>       
        年龄:<input type="text" name="age"><br>
        密码:<input type="password" name="password"><br>
        文件:<input type="file" name="file"><br>
        <input type="submit" value="提交">
    </form>
  </body>
</html>

 

6.查看用户信息的JSP页面show.jsp

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<%@ page import="org.liky.fileupload.User" %>
<%request.setCharacterEncoding("UTF-8");%>

<%
    User user = (User)request.getAttribute("user");
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>   
    <title>显示用户信息</title>
  </head>
 
  <body>
    <h2>显示用户信息</h2>
    姓名:<%=user.getUsername()%><br>
    密码:<%=user.getPassword()%><br>
    年龄:<%=user.getAge()%><br>
  </body>
</html>

 

7.web.xml文件的配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>FileUploadServlet</servlet-name>
        <servlet-class>
            org.liky.fileupload.FileUploadServlet
        </servlet-class>
        <init-param>
            <!-- 上传文件内存缓冲区的大小,大于这个值将直接写入临时磁盘存储目录 -->
            <param-name>threshold</param-name>
            <param-value>1048576</param-value>
        </init-param>
        <init-param>
            <!-- 服务器端上传文件的临时磁盘存储目录 -->
            <param-name>repository</param-name>
            <param-value>/upload</param-value>
        </init-param>
        <init-param>
            <!-- 允许单个上传文件大小的最大值 -->
            <param-name>fileSizeMax</param-name>
            <param-value>10485760</param-value>
        </init-param>
    </servlet>
  <servlet>
    <servlet-name>FormHandlerServlet</servlet-name>
    <servlet-class>org.liky.fileupload.FormHandlerServlet</servlet-class>
  </servlet>


    <servlet-mapping>
        <servlet-name>FileUploadServlet</servlet-name>
        <url-pattern>/fileUpload.do</url-pattern>
    </servlet-mapping>
  <servlet-mapping>
    <servlet-name>FormHandlerServlet</servlet-name>
    <url-pattern>/formHandler.do</url-pattern>
  </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>