servlet文件上传、多文件上传

一、课程目标

【理解】servlet文件上传原理
【理解】servlet基于jar包文件上传
【掌握】servelt3.0注解形式的文件上传
【理解】多文件上传
【了解】文件下载原理
【理解】LayUi文件上传组件的使用

二、基于Jar文件上传

2.1 原理

将客户端的文件以流的形式进行解析发送至服务器端并进行保存的过程称之为文件上传,很多前端框架都定义了这种上传的功能,大致分为几类,form表单形式,ajax形式

创建DiskFileItemFactory工厂对象,创建文件解析对象ServletFileUpload传入工厂对象,调用解析方法解析请求中的流数据,将流数据以FileItem集合的形式进行返回(包含普通字段数据以及文件字段数据的集合),遍历集合判断是否为文件字段,如果是文件字段获取输入流,通过输出流存储至指定文件中(getName上传文件名),如果获取普通字段数据通过(getFieldName,getString)相应方法获取数据信息

2.2 书写

如果是基于form表单形式,那么在提交数据时需要修改表单的数据提交方式,将表达的数据以流的形式发送至服务器端,并且修改请求方式为post,否则不能进行上传

1、书写form表单 修改提交方式method=“post”,数据发送方式enctype="multipart/form-data“这样提交的文件会在请求体中以流的形式发送至客户端

  <!-- 提交方式post   提交数据形式multipart/form-data -->
<form action="/upload" method="post" enctype="multipart/form-data">

2、创建相应的文件域用于选择提交的文件

<form action="upload" method="post" enctype="multipart/form-data">
    账号:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    头像:<input type="file" name="img" ><br>
    <input type="submit" value="注册">
</form>

3、在导入相应jar包后创建对应处理文件上传的servlet类

package com.yunhe.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
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 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;

@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 创建文件解析工厂对象
		FileItemFactory fileItemFactory = new DiskFileItemFactory();
		// 使用文件解析工厂对象创建对应的解析对象
		ServletFileUpload servletUpload = new ServletFileUpload(fileItemFactory);
		// 创建map集合保存普通数据字段
		HashMap<String, String> map = new HashMap<>();
		try {
			// 解析请求中的流数据封装保存至对应的字段数据对象中
			List<FileItem> fileItems = servletUpload.parseRequest(request);
			// 遍历字段数据集合 判断数据类型进行操作
			for (FileItem fileItem : fileItems) {
				// 如果当前遍历的是form表单的普通字段
				if (fileItem.isFormField()) {
					map.put(fileItem.getFieldName(), fileItem.getString());
				} else {
					// 获取上传原文件名
					String name = fileItem.getName();
					// 创建保存文件的路径
					String contextPath = getServletContext().getRealPath("/");
					System.out.println(contextPath);
					// 创建保存文件的file类
					File file = new File(contextPath, name);
					// 在指定路径创建文件对象
					//file.createNewFile();
					
					// 读取上传文件的输入流
					InputStream is = fileItem.getInputStream();
					// 创建写入文件的输出流
					FileOutputStream fos = new FileOutputStream(file);
					// 读取输入流数据写入文件
					byte[] b = new byte[1024];
					int len = 0;
					while ((len = is.read(b)) != -1) {
						fos.write(b, 0, len);
					}
					is.close();
					fos.flush();
					fos.close();
					System.out.println("文件被保存到:" + file);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

2.3 多文件上传

由于后台进行处理时,就是将请求的所有数据进行解析,所以无论前台发送多个文件,后台解析方式不变,所以无需修改后台代码,只需要在前台上传页面对应文件域中添加复选属性multiple即可

<form action="upload" method="post" enctype="multipart/form-data">
    账号:<input type="text" name="username"><br>
    密码:<input type="password" name="password"><br>
    头像:<input type="file" name="img" ><br>
    <input type="submit" value="注册" multiple>
</form>

三、基于注解文件上传

3.1 原理

将客户端的文件以流的形式进行解析发送至服务器端并进行保存的过程称之为文件上传,很多前端框架都定义了这种上传的功能,大致分为几类,form表单形式,ajax形式

在servlet3.0之后可以将数据封装为part对象可以直接获取上传的文件数据,需要将servlet使用@MultipartConfig进行标识

2.2 书写

前台代码无需修改

package com.yunhe.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.*;
import java.util.Collection;
import java.util.UUID;

@WebServlet("/upload")
//告诉服务器 这个servlet可以用来直接接收文件
@MultipartConfig
public class UploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        //可以直接通过name获取请求中的值
        String username = request.getParameter("username");
        // Part part = request.getPart("imgFile");
        //获取提交文件的名字(单个文件)
        // String submittedFileName = part.getSubmittedFileName();
        //获取前台请求的所有文件(包含普通字段在内)
        Collection<Part> parts = request.getParts();
        for (Part p : parts) {
            //普通字段封装为part对象数据为null
          if(p.getSubmittedFileName()!=null){
              InputStream inputStream = p.getInputStream();
              BufferedInputStream bis=new BufferedInputStream(inputStream);
              File file=new File("F://upload", UUID.randomUUID()+p.getSubmittedFileName());
              FileOutputStream fos=new FileOutputStream(file);

              byte [] b=new byte[2048];
              int len=0;
              while((len=bis.read(b))!=-1){
                  fos.write(b,0,len);
              }
              bis.close();
              fos.flush();
              fos.close();
          }
        }
    }
}

四、文件下载

4.1 原理

就是服务器端根据客户端请求查找指定文件,通过io流的形式将文件发送至客户端,但是由于数据的类型,需要修改响应头变为文件形式,否则会直接输出到客户端展示

4.2 书写

1、创建响应客户端的文件对象

2、设置响应头,设置文件名称

3、获取响应输出流读取文件输出至客户端

package com.yunhe.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class DownLoadServlet
 */
@WebServlet("/download")
public class DownLoadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

 
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		File file = new File("C://Users/Administrator/Desktop/test.doc");
		//设置相应头设置响应文件名
		response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
		FileInputStream fis=new FileInputStream(file);
		ServletOutputStream os = response.getOutputStream();
		byte b[]=new byte[1024];
		int len=0;
		while((len=fis.read(b))!=-1){
			os.write(b, 0, len);
		}
		fis.close();
		os.flush();
		os.close();
	}
}

五、LayUI文件上传组件

通过layui加载相应模块为指定标签添加上传功能(无需使用input标签就可以完成文件上传)

5.1 使用

1、在页面引入layUI相关样式css与js

2、加载指定模块

3、书写相应配置属性绑定页面元素

4、后台进行文件的保存(注意返回数据形式)接口返回的相应信息必须是一个标准的 JSON 格式

5.2 配置属性

参数选项说明类型默认值
elem指向容器选择器,如:elem: ‘#id’。也可以是DOM对象string/object-
url服务端上传接口,返回的数据规范请详见下文string-
data请求上传接口的额外参数。如:data: {id: ‘xxx’}object-
headers接口的请求头。如:headers: {token: ‘sasasas’}。注:该参数为 layui 2.2.6 开始新增
accept指定允许上传时校验的文件类型,可选值有:images(图片)、file(所有文件)、video(视频)、audio(音频)stringimages
acceptMime规定打开文件选择框时,筛选出的文件类型,值为用逗号隔开的 MIME 类型列表。如: acceptMime: ‘image/*’(只显示图片文件) acceptMime: ‘image/jpg, image/png’(只显示 jpg 和 png 文件) 注:该参数为 layui 2.2.6 开始新增stringimages
exts允许上传的文件后缀。一般结合 accept 参数类设定。假设 accept 为 file 类型时,那么你设置 exts: ‘zip|rar|7z’ 即代表只允许上传压缩格式的文件。如果 accept 未设定,那么限制的就是图片的文件格式stringjpg|png|gif|bmp|jpeg
auto是否选完文件后自动上传。如果设定 false,那么需要设置 bindAction 参数来指向一个其它按钮提交上传booleantrue
bindAction指向一个按钮触发上传,一般配合 auto: false 来使用。值为选择器或DOM对象,如:bindAction: ‘#btn’string/object-
field设定文件域的字段名stringfile
size设置文件最大可允许上传的大小,单位 KB。不支持ie8/9number0(即不限制)
multiple是否允许多文件上传。设置 true即可开启。不支持ie8/9booleanfalse
number设置同时可上传的文件数量,一般配合 multiple 参数出现。 注意:该参数为 layui 2.2.3 开始新增number0(即不限制)
drag是否接受拖拽的文件上传,设置 false 可禁用。不支持ie8/9booleantrue
回调
choose选择文件后的回调函数。返回一个object参数,详见下文function-
before文件提交上传前的回调。返回一个object参数(同上),详见下文function-
done执行上传请求后的回调。返回三个参数,分别为:res(服务端响应信息)、index(当前文件的索引)、upload(重新上传的方法,一般在文件上传失败后使用)。详见下文function-
error执行上传请求出现异常的回调(一般为网络异常、URL 404等)。返回两个参数,分别为:index(当前文件的索引)、upload(重新上传的方法)。详见下文function-

upload.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="static/layui/css/layui.css">
    <script src="static/layui/layui.js"></script>
    <script src="static/js/jquery-3.4.1.min.js"></script>
    <script>
        $(function () {
            layui.use('upload', function () {
                var upload = layui.upload;
                //执行实例
                var uploadInst = upload.render({
                    elem: '#test1' //绑定元素
                    , url: 'imgUpload' //上传接口
                    , done: function (res) {
                        //上传完毕回调
                      //  console.log(res.data.src)
                      //  alert("上传成功")
                        $("#i1").attr("src",res.data.src)
                    }
                    , error: function () {
                        //请求异常回调
                        alert("上传失败")
                    }
                });
            });
        })
    </script>
</head>

<body>
<img id="i1">
    <button type="button" class="layui-btn" id="test1">
        <i class="layui-icon">&#xe67c;</i>上传图片
    </button>
</body>
</html>

ImgServlet.java

package com.yunhe.servlet;

import net.sf.json.JSONObject;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.*;
import java.util.Collection;
import java.util.UUID;

@WebServlet("/imgUpload")
@MultipartConfig
public class ImgServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        Collection<Part> parts = request.getParts();
        for (Part p : parts) {
            //普通字段封装为part对象数据为null
            if (p.getSubmittedFileName() != null) {
                InputStream inputStream = p.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(inputStream);
                String fileName=UUID.randomUUID() + p.getSubmittedFileName();
                File file = new File("F://upload", fileName);
                FileOutputStream fos = new FileOutputStream(file);
                byte[] b = new byte[2048];
                int len = 0;
                while ((len = bis.read(b)) != -1) {
                    fos.write(b, 0, len);
                }
                bis.close();
                fos.flush();
                fos.close();
                //创建json对象
                JSONObject jsonObject=new JSONObject();
                JSONObject dataJson=new JSONObject();

                jsonObject.put("code",0);
                jsonObject.put("msg","");
                dataJson.put("src","/img/"+fileName);
                jsonObject.put("data",dataJson);
                System.out.println(jsonObject);
                response.getWriter().print(jsonObject);
            }
        }
    }
}

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Servlet中实现多文件上传需要以下步骤: 1. 在HTML表单中设置enctype属性为"multipart/form-data",并且设置method为"POST"。 2. 在Servlet中获取HttpServletRequest对象,并通过该对象获取上传文件信息。 3. 遍历HttpServletRequest对象中的文件信息,并将每个文件保存到服务器本地磁盘。 以下是一个示例Servlet代码: ```java 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 { private static final long serialVersionUID = 1L; public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); // 判断上传表单是否为multipart/form-data类型 boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (!isMultipart) { out.println("<html>"); out.println("<head>"); out.println("<title>Servlet upload</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Invalid request type</h1>"); out.println("</body>"); out.println("</html>"); return; } // 创建一个FileItemFactory对象 FileItemFactory factory = new DiskFileItemFactory(); // 创建ServletFileUpload对象 ServletFileUpload upload = new ServletFileUpload(factory); try { // 解析上传表单 List<FileItem> items = upload.parseRequest(request); for (FileItem item : items) { // 判断是否为文件域 if (!item.isFormField()) { // 获取上传文件名称 String fileName = item.getName(); // 创建一个文件对象 File file = new File("c:/uploads/" + fileName); // 保存上传文件到本地磁盘 item.write(file); } } // 显示上传成功页面 out.println("<html>"); out.println("<head>"); out.println("<title>Servlet upload</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Upload successful</h1>"); out.println("</body>"); out.println("</html>"); } catch (Exception e) { e.printStackTrace(); } } } ``` 在上面的示例中,使用了Apache Commons FileUpload API来解析上传表单数据。这个API提供了一种方便、可靠、高效的方式来处理文件上传

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值