文件上传案例实现
一、分析:
    1、原理:
        所谓文件上传就是先让客户端浏览器将目标文件进行二进制化,通过二进制流将文件内容发送给服务器;在服务器端接收到带有文件内容的二进制流后,对这些流进行解析(解析工作也可以交给第三方的jar包完成)

    2、文件上传的前期准备:
        1、要有一个form标签,method=post请求
        2、form 标签的encType属性值必须为multipart/form-data值
        3、在form标签中使用input type=file 添加上传的文件
        4、编写服务器代码(Servlet 程序)接收,处理上传的数据。

        注:
            encType=multipart/form-data表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼 接,然后以二进制流的形式发送给服务器

    3、http协议的理解:
        Content-type表示提交的数据类型{
            如: encType=multipart/form-data表示提交的数据,以多段(每一个表单项一个数据段)的形式进行拼 接,然后以二进制流的形式发送给服务器

            boundary= 表示每段数据的分割符号
        }    4、了解第三方文件解析jar包
        commons-fileupload.jar:用于文件解析操作
        commons-io-1.4.jar:用于流操作
        常用类与方法:

ServletFileUpload类,用于解析上传的数据。
FileItem类,表示每一个表单项。

boolean ServletFileUpload.isMultipartContent(HttpServletRequest request);
    判断当前上传的数据格式是否是多段的格式。

public List<FileItem> parseRequest(HttpServletRequest request);
    解析上传的数据

boolean FileItem.isFormField();
    判断当前这个表单项,是否是普通的表单项。还是上传的文件类型。
    true 表示普通类型的表单项
    false 表示上传的文件类型

String FileItem.getFieldName();
    获取表单项的 name 属性值

String FileItem.getString();
    获取当前表单项的值

String FileItem.getName();
    获取上传的文件名

void FileItem.write( file );
    将上传的文件写到参数file所指向抽硬盘位置 。

二、实现(以Apache提供的commons-fileupload.jar包为例子)
    1.导入解析jar包
        commons-fileupload.jar
        commons-io-1.4.jar
    2.编写相应的前端页面

{
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <form action="http://localhost:8080/basepart003/UploadServlet" method="post" enctype="multipart/form-data">
            用户名称:<input type="text" name="username"><br>
            文件:<input type="file" name="file" ><br>
            <input type="submit" value="上传">
        </form>
    </body>
    </html>
}

    3.编写相应的servlet程序

{
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.先判断上传的数据是否是多段数据(只有是多段数据才是文件上传的)
        if(ServletFileUpload.isMultipartContent(req)){
            //创建FileItemFactory工厂实现类
            FileItemFactory fileItemFactory=new DiskFileItemFactory();
            //创建用于解析上传数据的工具类ServletFileUpload类
            ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);

            try {
                //解析上传的数据得到每一个表单项FileItem
                List<FileItem> list = servletFileUpload.parseRequest(req);
                //循环判断每一个表单项是普通类型还是上传的文件
                for (FileItem fileItem : list) {
                    if(fileItem.isFormField()){
                        //普通表单项
                        System.out.println("表单项的name属性值"+fileItem.getFieldName());

                        //参数utf-8解决乱码问题
                        System.out.println("表单项的value属性值"+fileItem.getString("UTF-8"));
                    }else {
                        //上传的文件
                        System.out.println("表单项的name属性值"+fileItem.getFieldName());
                        System.out.println("上传的文件名称"+fileItem.getName());

                        fileItem.write(new File("全路径"+fileItem.getName()));
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
}

文件下载案例实现
一、分析:
    1、原理:
        客户端发送请求告诉服务器要下载的目标文件;在服务器端获取要下载的文件名称,在服务器本地或数据库中通过名称读取客户端要下载的文件内容,将其转化为二进制流回传给客户端,通过响应头告诉客户端回传的二进制流文件类型,以及告知客户端浏览器回传的数据是用于下载的
二、代码实现:

{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取要下载的文件名称
        String downloadFileName="0.jpg";
        //读取要下载的文件内容(通过ServletContext对象可以读取)
        ServletContext servletContext = getServletContext();
        //获取要下载的文件类型
        String mimeType = servletContext.getMimeType("/file/" + downloadFileName);
        System.out.println("下载的文件类型:"+mimeType);
        //通过响应头告诉客户端返回的数据类型
        resp.setContentType(mimeType);
        /*
            告诉客户端收到的数据是用于下载而非显示(通过响应头)
            Content-Disposition响应头表示收到的数据怎么处理
            attachment表示附件,表示下载使用
            filename表示指定下载的文件名
         */
        //判断使用什么浏览器
        if(req.getHeader("User-Ahent").contains("Firefox")){
            //针对base64编码集--火狐浏览器
            resp.setHeader("Content-Disposition","attachment;filename==?UTF-8?B?"+new BASE64Encoder().encode("中国.jap".getBytes("UTF-8")) +"?=");

        }else{
            //URL编码是把汉字转换为%xx%xx的格式--针对谷歌浏览器
            resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("中国.jpg","UTF-8"));
        }
        //resp.setHeader("Content-Disposition","attachment;filename="+downloadFileName);
        //resp.setHeader("Content-Disposition","attachment;filename=自己取名字.jpg");


        /**
         * /斜杠被服务器解析表示地址为http://ip:port/工程名称/  映射到代码的web目录
         */
        InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + downloadFileName);
        //获取响应的输出流
        ServletOutputStream outputStream = resp.getOutputStream();
        //把下载的文件回传给客户端
        //读取流中全部数据,复制给输出流,输出给客户端
        IOUtils.copy(resourceAsStream,outputStream);
    }
}

以上是本篇小节,不喜勿喷,感谢理解