Servlet文件的上传与下载详解

网友投稿 1201 2022-09-27

Servlet文件的上传与-详解

Servlet文件的上传与-详解

目录文件的上传和-1. 文件上传细节2. 文件上传3. 文件-

文件的上传和-

1. 文件上传细节

要有一个 form 标签,method-post请求 (因为get有长度限制)

form标签的属性 encType 值必须为 multipart/form-data

表示提交的数据以多端(每一个表单项一个数据段)的形式进行拼接,然后以二进制流的形式发送给服务器

在 form 标签中使用 input type="file" 添加上传的文件

编写服务器代码 (Servlet接收),接受处理上传的数据

文件上传http请求信息:

请求头:Content-Type: multipart/form-data; boundary=------WebKitFormBoundaryCd3g75eOt35olUs7

解析:

Content-Type 表示提交的数据类型multipart/form-data 表示以流的形式分段提交服务器boundary 表示每段数据的分隔符,值:----WebKitFormBoundarylXiF4fEzpo9c8L4p 是浏览器每次随机生成的,它就是每段数据的分界符。在每段里面 第一行是对表单项的描述,然后有个空行,下面是提交的值。

请求体:

------WebKitFormBoundaryCd3g75eOt35olUs7Content-Disposition: form-data; name="username"

zhu------WebKitFormBoundaryCd3g75eOt35olUs7Content-Disposition: form-data; name="photo"; filename="head.jpg"Content-Type: image/jpeg

文件的信息(很长这里省略了)------WebKitFormBoundaryCd3g75eOt35olUs7--

因为客户端是以按流的方式提交是,所以我们要按流的方式获取,不能这样: req.getParameter(&qBEAYTbuot;username");

正确用法:

@Override

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

System.out.println("上传成功");

ServletInputStream inputStream = req.getInputStream(); // 先得到 字节输入流

byte[] buffer = new byte[1024]; // 缓冲区

int readCount = 0;

while ((readCount = inputStream.read(buffer)) != -1) { // 打印出来的就是上面全部的请求体

System.out.println(new String(buffer, 0, readCount));

}

}

2. 文件上传

这种文件上传(常用)有很多第三方提供好的API我们使用进行了,可以帮我们对收到的数据进行解析。

例如:commons-fileupload-1.2.1.jar (依赖于 commons-io-1.4.jar)

导入两个jar包解析

关键的类:

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

//ServletFileUpload中的方法

// 判断当前上传的数据是否是多端的格式,不是解析不了

public boolean ServletFileUpload.isMultipartContent(HttpServletRequest req)

// 解析上传的数据,FileItem表示每一个表单项

public List parseRequest(HttpServletRequest req)

//FileItem中方法

// 判断当前这个表单项是普通的表单项还是文件上传的类型,true表示普通的

public boolean isFormField()

// 获取表单项name属性值

public String getFieldName()

// 获取当前表单项的值

public String getString() // 可传入字符集,防止乱码,一开始req.setCharacterEncoding("UTF-8");也行

// 获取上传的文件名

public String getName()

// 将上传的文件写道 参数file所指向的磁盘位置

public void write(File file)

Servlet上传文件示例:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

req.setCharacterEncoding("UTF-8"); // 防止乱码

resp.setContentType("text/html; charset=utf-8")BEAYTb;

String savePath = getServletContext().getRealPath("/WEB-INF/uploadFile"); //保存的路径

// 首先判断上传的数据是否是多段的数据

if (ServletFileUpload.isMultipartContent(req)) {

FileItemFactory fileItemFactory = new DiskFileItemFactory(); // 创建FileItemFactory工厂的实现类,

// 创建用于解析上传数据的工具类

ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);

try {

List list = servletFileUpload.parseRequest(req); // 解析,得到每一个表单项

for (FileItem fileItem : list) {

if (fileItem.isFormField()) { // 普通表单项

System.out.print("表单项的name属性值:" + fileItem.getFieldName());

System.out.println(" 表单项的value:" + fileItem.getString("UTF-8"));

} else { // 文件类型

System.out.print("文件的name属性值:" + fileItem.getFieldName());

System.out.println(" 上传的文件名:" + fileItem.getName());

// 一般会保存到用户访问不能直接访问的目录下 File.separator是系统默认路径分隔符,win下是 /

// (下面这是保存到了部署的真是目录下,保存到了服务器中)

// 可以用UUID保证文件名的唯一性,防止文件覆盖。

// 防止单个目录文件过多影响读写速度,还可以使用目录生成算法分散储存

fileItem.write(new File(savePath + File.separator + fileItem.getName()));

//fileItem.delete(); //关闭资源

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

3. 文件-

客户端 ->(发送请求告诉服务器我要-什么文件) -> 服务器

服务器干的内容:

获取要-的文件名读取要-的文件内容通过响应头告诉客户端返回的数据类型是什么 (和要-的类型一致)告诉的客户端收到的数据是用于-使用(还是用响应头设置)把-的的文件内容回传给客户端-

这个也能用 commons-io-1.4.jar 的IOUtils 类:

@Override

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

req.setCharacterEncoding("UTF-8"); // 防止乱码

resp.setCharacterEncoding("UTF-8");

//1.获取要-的文件名路径名,并通过ServletContext读取读取文件

String downloadFileName = "head.jpg"; // 我们这里写死了

ServletContext servletContext = getServletContext();

String savePath = servletContext.getRealPath("/WEB-INF/upload"); //以前上传文件保存的目录

String downloadPath = savePath + File.separator + downloadFileName;

//2.告诉客户端返回的类型

String downloadType = servletContext.getMimeType(downloadPath); //获取要-文件的类型 (这个是image/jpeg)

resp.setContentType(downloadType); // (和要-的类型一样)

//3.告诉客户端收到的数据是用于-的,不是直接显示在页面的

// Content-Disposition表示收到的数据怎么处理,attachment表示附件-使用,filename表示-文件的名字

// filename名可以不和本地的名字一样,当有中文时会乱码,因为http协议设置的的时候不支持中文,需要进行url编码

/resp.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName);

resp.setHeader("Content-Disposition",

"attachment;filename=" + URLEncoder.encode(downloadFileName, "UTF-8"));

InputStream resourceAsStream = servletContext.getResourceAsStream(downloadPath);

// getResourceAsStream() 传入文件路径,读取文件!!!!!!!!!!!!!

// 4.commons-io-1.4.jar中有IOUtils我们可以直接用,不用自己read() write()了

ServletOutputStream outputStream = resp.getOutputStream(); // 获取响应的输出流

IOUtils.copy(resourceAsStream, outputStream);

// 读取输入流的信息复制给输出流,输出给客户端,传入一个输入流和输出流 (字节字符流都行)

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Shell if else语句实战案例
下一篇:Nginx http_sub_module 替换网站响应内容
相关文章

 发表评论

暂时没有评论,来抢沙发吧~