J2EE开发技术点3:文件上传下载-阿里云开发者社区

开发者社区> rhwayfun> 正文

J2EE开发技术点3:文件上传下载

简介:
+关注继续查看

前言

文件上传下载在类似注册表单中经常会使用到,这里也单独抽取出来,以便日后直接使用。文件上传是以流的方式提交到服务器的,这点与普通的表单提交不同,所以需要对有文件上传域的表单特别声明,这样提交到后台的时候就可以以流的方式进行存取了。实现这个功能我们需要借助Apache的两个jar包:commons-fileupload-1.2.2.jar
commons-io-2.0.1.jar。这两个jar可以在网上直接下载。

文件上传

1、创建一个web工程,并导入上面两个jar包,如下图:

2、创建文件上传表单

  <body>
    <form action="uploadServlet" enctype="multipart/form-data" method="post">
        <h3>文件上传</h3><br>
        上传文件1:<input type="file" name="pic1"><br>
        上传文件2:<input type="file" name="pic2">
    </form>
  </body>

3、建立uploadServlet.java文件

package com.rhwayfun.servlet;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

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.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadServlet extends HttpServlet {

    @SuppressWarnings("unchecked")
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //1、创建DiskFileItemFactory工厂
        FileItemFactory factory = new DiskFileItemFactory();
        //2、创建一个文件上传解析器
        ServletFileUpload su = new ServletFileUpload(factory);
        //解决上传文件名乱码
        su.setHeaderEncoding("UTF-8"); 
        List<FileItem> list = null;
        //获取输出流对象
        PrintWriter out = response.getWriter();
        try {
            //3、解析Request对象,以便对文件上传域对象进行处理
            list= su.parseRequest(request);
            for (FileItem fileItem : list) {
                if(fileItem.isFormField()){//普通表单域
                    if(fileItem.getFieldName().equals("username")){
                        //处理表单提交字段,解决普通输入域中文乱码问题
                        String username = fileItem.getString("utf-8");
                        out.print(username + ",");
                    }
                }else{//文件上传域
                    //得到上传文件的保存目录,将上传的文件保存到WebRoot下的upload文件夹中
                    String path = this.getServletContext().getRealPath("/WEB-INF/upload");
                    //浏览器请求路径,这是一个相对路径
                    String url = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/upload/";
                    //获取上传文件的文件名
                    String fileName = fileItem.getName();
                    //得到上传文件的扩展名
                    String extName = fileName.substring(fileName.lastIndexOf(".")+1);
                    //服务器只支持jpg和gif两种格式的文件
                    if(extName.equals("jpg") || extName.equals("gif")){
                        File uFile = new File(path);
                        //如果保存的目录不存在就创建一个目录
                        if(!uFile.exists()){
                            uFile.mkdirs();
                        }
                        File file = new File(path,fileName);
                        //写入文件到保存的目录中
                        fileItem.write(file);
                    }else{
                        System.out.println("文件格式不支持");
                    }

                }
            }
            out.print("上传成功");
        } catch (Exception e) {
            out.print("对不起,上传失败");
            e.printStackTrace();
        }
    }
}

4、配置web.xml文件

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

5、验证是否上传成功

文件下载
实现文件下载需要得到服务器上指定目录下的所有资源,所以第一步是创建一个Servlet用于得到所有的下载资源列表,该Servlet在获取所有资源之后,返回到下载列表的页面,用户可以对其中下载列表进行下载。

首先创建ListFileServlet,用于获取下载资源列表:

package com.rhwayfun.servlet;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

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

public class ListFileServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //上传文件的时候保存的路径
        String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
//      System.out.println(uploadPath);
        //创建一个Map用于保存该目录下的所有文件
        Map<String,String> files = new HashMap<String,String>();
        //遍历该目录,并保存到该map中
        listFileAndSave(new File(uploadPath),files);
        //返回给浏览器端
        request.setAttribute("files", files);
        request.getRequestDispatcher("listFile.jsp").forward(request, response);
    }

    private void listFileAndSave(File file, Map<String, String> files) {
        //首先判断是否是一个目录
        if(!file.isFile()){//表示这是一个目录
            //得到该目录下的所有文件
            File[] fs = file.listFiles();
            //遍历列出的所有文件,直到全部都是文件而不是目录为止
            for (File file2 : fs) {
                listFileAndSave(file2, files);
            }
        }else{//表示这是一个文件
            //需要得到这个文件真实的文件名,比如一个文件为
            //D:\apache-tomcat-7.0.42\webapps\\uploadAndDownload\WEB-INF\\upload\c.jpg
            //那么其真实的文件名应该是c.jpg才对,所以需要对该文件进行字符串的截取
//          System.out.println(file.getPath());
            String fileName = file.getPath().substring(file.getPath().lastIndexOf("\\")+1);
            files.put(file.getPath(), fileName);
        }
    }
}

然后配置web.xml文件:

<servlet>
    <servlet-name>ListFileServlet</servlet-name>
    <servlet-class>com.rhwayfun.servlet.ListFileServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ListFileServlet</servlet-name>
    <url-pattern>/listFileServlet</url-pattern>
  </servlet-mapping>

接着编写listFile.jsp页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>下载列表</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
  </head>

  <body>
  <form action="">
    <c:forEach items="${files }" var="file">
        <c:url value="downLoadServlet" var="downurl">
             <c:param name="filepath" value="${file.key}"></c:param>
        </c:url>
       ${file.value}<a href="${downurl}">下载</a>
       <br>
    </c:forEach>
    </form>
  </body>
</html>

为了防止出错,我们先测试以上代码是否有错:

ok,经过测试,我们的代码是正确的。接下来就要实现下载功能了,首先需要编写DownLoadServlet类,对下载的资源进行处理,请看代码:

package com.rhwayfun.servlet;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

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

public class DownLoadServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //获取要下载文件的服务器路径
        String filepath = request.getParameter("filepath");
        //获取文件名
        String filename = filepath.substring(filepath.lastIndexOf("\\")+1);
        //设置响应头,控制浏览器下载该文件
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-disposition", "attachment;filename="+ new String(filename.getBytes("utf-8"), "ISO-8859-1"));
        //创建输入流
        FileInputStream fis = new FileInputStream(filepath);
        //读取文件至缓冲区中
        byte[] data = new byte[fis.available()];
        fis.read(data);
        //关闭流
        fis.close();
        //创建输出流
        OutputStream os = response.getOutputStream();
        //写入到文件中
        os.write(data);
        os.close();
    }
}

再配置web.xml文件:

<servlet>
    <servlet-name>DownLoadServlet</servlet-name>
    <servlet-class>com.rhwayfun.servlet.DownLoadServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>DownLoadServlet</servlet-name>
    <url-pattern>/downLoadServlet</url-pattern>
  </servlet-mapping>

最后,我们来测试我们的下载功能是否正常:

小结
至此,我们就把文件上传域下载两个功能做完了,实现思路不复杂,主要有一些细节的处理,比如文件名中文乱码问题等。文件上传下载是特别实用的功能,需要介绍的内容也就这么多了。在以后的开发中,直接复用这些代码就很方便了。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
微信公众平台开发(80) 上传下载多媒体文件
微信公众账号在回复图片、语音、视频的时候,将使用media_id来调用相关文件,很多朋友咨询这个如何开发实现。本文将介绍在微信公众平台开发过程中,如何上传下载多媒体文件。   一、上传多媒体文件 公众号可调用本接口来上传图片、语音、视频等文件到微信服务器,上传后服务器会返回对应的media_id,公众号此后可根据该media_id来获取多媒体。
1106 0
Android开发4——文件操作模式
一、基本概念 // 上下文对象 private Context context; public FileService(Context context) { super(); this.context = context; } // 保存文件方法 public void save(String filename, String fileContent) thr
765 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4425 0
Android开发5——文件读写
一、基本概念 在Android应用中保存文件,保存的位置有两处 ①手机自带的存储空间,较小(如200M),适合保存一些小文件,Android中保存位置在data/data/应用包名/files目录 ②外存储设备如SD卡,较大,适合保存大文件如视频,Android中保存位置在mnt/sdcard目录,androd1.5,android1.6保存在sdcard目录 保存的位置通过and
1222 0
+关注
111
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载