0
点赞
收藏
分享

微信扫一扫

javaweb基础第二十六课:使用commons-fileupload进行文件上传

婉殇成长笔记 2022-02-09 阅读 64


  这节课我们就来学怎么真正的上传文件

  要想上传文件,我们需要引入新的第三方Jar包,两个:

- commons-fileupload

- commons-io

commons-fileupload依赖于commons-io


jar包一如既往的给大家准备好了,直接复制粘贴到/WEB-INF/lib下即可


OK,关键问题来了,怎么用。百度,准确的说是看官方文档,这节课就来教大家怎么去搜和看官方文档。


​​http://commons.apache.org/proper/commons-fileupload/​​

这个就是commons-fileupload的官网,可以看到也是属于Apache的,Apache我们不陌生了,我们用的Tomcat就是它家的


OK,继续看官网

javaweb基础第二十六课:使用commons-fileupload进行文件上传_java

全英文,头疼。但是,我们的谷歌浏览器不是吃素的。

javaweb基础第二十六课:使用commons-fileupload进行文件上传_apache_02

OK,变成中文了,当然,翻译的质量肯定很差,很多时候需要切回英文去看,再点一下就切回英文了。


OK,我们看什么呢?显然是用户指南。


最简单的使用情况,显然可以直接复制粘贴,OK,我们开始写代码

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Configure a repository (to ensure a secure temp location is used)
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List<FileItem> items = upload.parseRequest(request);



package com.servlet;



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;



import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletInputStream;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.*;

import java.util.Iterator;

import java.util.List;

import java.util.UUID;



//负责文件上传的Servlet

public class FileUploadServlet extends HttpServlet {



//文件上传一定是POST方式,所以我们用doPost

@Override

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

try {

//创建一个FileItemFactory,也就是FIleItem工厂

DiskFileItemFactory factory = new DiskFileItemFactory();



//设置临时存储区

ServletContext servletContext = this.getServletConfig().getServletContext();

File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");

factory.setRepository(repository);



//new一个ServletFileUpload对象

ServletFileUpload upload = new ServletFileUpload(factory);



//解析request对象,获取FileItem集合

List<FileItem> items = upload.parseRequest(req);



//处理上传的项目

//文档里代码的括号是中文的,真是讨厌

//替换一下,解决

Iterator<FileItem> iter = items.iterator();

while(iter.hasNext()){

FileItem item = iter.next();



if(item.isFormField()){

processFormField(item);

} else {

processUploadedFile(item);

}

}

//OK,文件成功上传,下面开始解释



/**

* 先来解释ServletContext.getRealPath()方法

* 这个方法就是根据相对路径获取真实路径,相对于谁的路径呢?相对于F:\code\java\JavaWebTeach01\out\artifacts\JavaWebTeach01_war_exploded的路径

* 当然,如果有ContextPath的话,那就是F:\code\java\JavaWebTeach01\out\artifacts\JavaWebTeach01_war_exploded\${ContextPath}

*

* 然后,为什么会是这个路径呢?

* 这个是在ProjectStructure里设置的,Eclipse又不一样,它会编译到Tomcat的/webapps里,也就是下面这条路径

* F:\tomcat8.5\apache-tomcat-8.5.35\webapps

*

* idea的就直接在项目下的out/artifacts/项目名_war_exploded下

*

* web下的东西会全部编译到out/artifacts/项目名_war_exploded下

* src里的源代码会被编译成.class文件存放在/WEB-INF/classes下

*

* 刚刚我新建了一个upload文件夹,然后放了个1.txt,注意,在idea里,web目录下的空文件夹不会被编译到out下,因此必须放个文件

* 还有,我的文件上传是上传到了out下的upload,web下的upload里只会有一个1.txt

* 这就是全部的文件上传

*/

} catch (FileUploadException e) {

e.printStackTrace();

}

}



//处理上传文件,这里的item保存着文件流

private void processUploadedFile(FileItem item) throws IOException {

//处理文件上传

if(!item.isFormField()){

//获取文件对应的属性名,就是input标签里的name属性值

String fieldName = item.getFieldName();



//获取文件名

String fileName = item.getName();



//获取文件类型

String contentType = item.getContentType();



//判断是否在内存中

boolean isInMemory = item.isInMemory();



//获取文件大小

long sizeInBytes = item.getSize();



//OK,之后自己写

//接下来我们就是读文件内容,然后保存到自己设置的文件夹里

InputStream inputStream = item.getInputStream();

byte[] bytes = new byte[(int)sizeInBytes];

inputStream.read(bytes);

//这样要上传的文件的数据就都在bytes里了,接下来我们写到指定文件夹里就可以了

//别忘了close掉inoutStream

inputStream.close();



//获取文件后缀名

String fileSuffixName = fileName.substring(fileName.lastIndexOf("."));



//然后设置我们想要的文件名即可

//但有一点,文件名不可以重复,因此我们还需要一个随机文件名生成器

//java自带这玩意,类名叫UUID

String newFileName = UUID.randomUUID().toString() + fileSuffixName;

System.out.println("新文件名: " + newFileName);



String path = this.getServletContext().getRealPath("/upload");



//File.separator就是文件分隔符,可以根据不同平台显示不同分隔符,windows就是\,Linux就是/

newFileName = path + File.separator + newFileName;

System.out.println("新文件的完整路径: \n" + newFileName);

File file = new File(newFileName);

if (!file.exists()) {

file.createNewFile();

OutputStream outputStream = new FileOutputStream(file);

outputStream.write(bytes);



//别忘了close掉OutputStream

outputStream.close();

}



}

}



//处理form表单数据,这类数据是字符串

private void processFormField(FileItem item) {

//处理常规表单字段

if(item.isFormField()){

String name = item.getFieldName();

String value = item.getString();

System.out.println("name: " + name);

System.out.println("value: " + value);

}

}

}



举报

相关推荐

0 条评论